"use client";

import { useEffect, useMemo, useRef, useState } from "react";
import { useParams, useSearchParams } from "next/navigation";

type Inspection = { external_id: string; vehicle_type: "light" | "motorcycle" | "heavy"; plate: string; chassis: string; vehicle_description: string | null; model_year: number | null; responsible_name: string; responsible_phone: string; responsible_email: string | null; status: string; risk_score: number; rules_version: string | null; inspection_cycle?: number; created_at: string };
type Photo = { id: string; category_code: string; latitude: number | string | null; longitude: number | string | null; ai_status: string; ai_quality_score: number | null; analysis_provider?: string | null; analysis_status?: string | null; analysis_confidence?: number | string | null; analysis_summary?: string | null; analysis_findings?: string[] | string | null; analysis_requires_human?: number | boolean | null; ocr_plate?: string | null; plate_match?: string | null; ocr_chassis?: string | null; chassis_match?: string | null; human_comment?: string | null; comment_analyst_name?: string | null; comment_updated_at?: string | null; manual_assessment?: string | null; manual_damage_location?: string | null; manual_comments?: string | null; manual_analyst_name?: string | null };
type Review = { analyst_name: string | null; review_status: "requested" | "completed"; decision: "approved" | "approved_with_notes" | "retriage" | "rejected" | null; comments: string | null; reason: string | null; rules_version: string | null; requested_at: string; completed_at: string | null };
type RuleEvaluation = { rule_code: string; rule_name: string; points: number | string; action: string; created_at?: string };

const labels = { light: "Veículo leve", motorcycle: "Moto", heavy: "Pesado" };
const manualAssessmentLabels: Record<string, string> = {
  no_damage: "Sem avaria ou divergência",
  damage_light: "Avaria leve (+10 pts)",
  damage_moderate: "Avaria moderada (+25 pts)",
  damage_severe: "Avaria grave (+45 pts)",
  damage_structural: "Avaria estrutural/crítica (+70 pts)",
  plate_divergent: "Placa divergente",
  chassis_divergent: "Chassi divergente/adulterado",
};
const stageLabels: Record<string, string> = { received: "Recebida", link_sent: "Link enviado", in_progress: "Em vistoria", retriage: "Com apontamento · retriagem", ai_analysis: "Em análise IA", human_review: "Com apontamento · análise humana", approved: "Sem apontamentos · aprovada", approved_with_notes: "Com apontamentos · aprovada", rejected: "Recusada · reprovada", expired: "Frustrada · link expirado", cancelled: "Frustrada · cancelada" };
const statusTone = (status: string) => status === "approved" ? "success" : ["approved_with_notes", "retriage", "human_review", "pending_data"].includes(status) ? "attention" : ["rejected", "expired", "cancelled"].includes(status) ? "critical" : "neutral";
const scripts = { light: ["Dianteira", "Lateral do motorista", "Traseira", "Lateral do passageiro", "Placa", "Chassi", "Motor", "Painel ligado"], motorcycle: ["Lateral direita", "Lateral esquerda", "Traseira", "Placa", "Chassi", "Painel ligado"], heavy: ["Cabine e dianteira", "Laterais e traseira", "Placa", "Chassi e motor", "Pneus e eixos", "Implemento e painel"] };

export default function InspectionDetailPage() {
  const params = useParams<{ externalId: string }>();
  const searchParams = useSearchParams();
  const tenantId = searchParams.get("tenantId") || "";
  const tenantQuery = tenantId ? `?tenantId=${encodeURIComponent(tenantId)}` : "";
  const [inspection, setInspection] = useState<Inspection | null>(null);
  const [photos, setPhotos] = useState<Photo[]>([]);
  const [review, setReview] = useState<Review | null>(null);
  const [evaluations, setEvaluations] = useState<RuleEvaluation[]>([]);
  const [manualReviewOpen, setManualReviewOpen] = useState(false);
  const [currentAnalyst, setCurrentAnalyst] = useState("Analista da Capital (sessão demonstrativa)");
  const [error, setError] = useState("");
  const [inspectionLink, setInspectionLink] = useState("");
  const [linkMessage, setLinkMessage] = useState("");
  const [trashMessage, setTrashMessage] = useState("");
  const [trashing, setTrashing] = useState(false);
  const [ruleMessage, setRuleMessage] = useState("");
  const [calculatingRules, setCalculatingRules] = useState(false);
  const [selectedPhoto, setSelectedPhoto] = useState<Photo | null>(null);
  const [zoom, setZoom] = useState(1);
  const [pan, setPan] = useState({ x: 0, y: 0 });
  const dragOrigin = useRef<{ x: number; y: number } | null>(null);

  async function loadInspection() {
    fetch(`/api/inspections/${encodeURIComponent(params.externalId)}${tenantQuery}`).then(async (response) => ({ response, body: await response.json() })).then(({ response, body }) => {
      if (!response.ok) throw new Error(body.error || "Não foi possível carregar a vistoria.");
      setInspection(body.inspection); setPhotos(body.photos); setReview(body.review); setEvaluations(body.evaluations ?? []); if (body.currentAnalyst) setCurrentAnalyst(body.currentAnalyst);
    }).catch((reason) => setError(reason instanceof Error ? reason.message : "Não foi possível carregar a vistoria."));
  }
  useEffect(() => { void loadInspection(); }, [params.externalId, tenantQuery]);
  useEffect(() => {
    fetch(`/api/inspections/${encodeURIComponent(params.externalId)}/link${tenantQuery}`).then(async (response) => ({ response, body: await response.json() })).then(({ response, body }) => {
      if (response.ok && body.path) setInspectionLink(`${window.location.origin}${body.path}`);
    }).catch(() => undefined);
  }, [params.externalId, tenantQuery]);

  const photoMap = useMemo(() => new Map(photos.map((photo) => [photo.category_code.toLowerCase(), photo])), [photos]);
  if (error) return <main className="detail-page"><a href="/">← Voltar ao dashboard</a><div className="detail-error"><b>Não foi possível abrir esta vistoria</b><p>{error}</p></div></main>;
  if (!inspection) return <main className="detail-page"><p className="eyebrow">CARREGANDO VISTORIA</p><h1>Buscando dados da operação...</h1></main>;
  const route = scripts[inspection.vehicle_type];
  const captured = photos.length;
  const externalId = inspection.external_id;
  async function generateLink(reinspection = false) {
    setLinkMessage(reinspection ? "Abrindo uma nova tentativa de vistoria..." : "Gerando link seguro...");
    try { const response = await fetch(`/api/inspections/${encodeURIComponent(externalId)}/link`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ reinspection, tenantId }) }); const result = await response.json(); if (!response.ok) throw new Error([result.error, result.hint].filter(Boolean).join(" ")); const url = `${window.location.origin}${result.path}`; setInspectionLink(url); await navigator.clipboard?.writeText(url); setLinkMessage(reinspection ? "Novo link de retriagem criado e copiado. O link anterior foi revogado; envie este ao responsável." : result.reused ? "Link ativo localizado e copiado novamente." : "Link criado e copiado. Escolha abaixo como enviar ao responsável."); } catch (reason) { setLinkMessage(reason instanceof Error ? reason.message : "Não foi possível gerar o link."); }
  }
  async function copyInspectionLink() { if (!inspectionLink) return; try { await navigator.clipboard?.writeText(inspectionLink); setLinkMessage("Link copiado para a área de transferência."); } catch { setLinkMessage("Não foi possível copiar automaticamente. Selecione o endereço e copie manualmente."); } }
  function deliveryMessage() { return `Olá${inspection?.responsible_name ? `, ${inspection.responsible_name}` : ""}! Sua Autovistoria Veicular está pronta. Abra o link para iniciar: ${inspectionLink}`; }
  function phoneDigits() { const digits = String(inspection?.responsible_phone || "").replace(/\D/g, ""); return digits.length === 10 || digits.length === 11 ? `55${digits}` : digits; }
  async function calculateRules() {
    setCalculatingRules(true); setRuleMessage("");
    try {
      const response = await fetch(`/api/inspections/${encodeURIComponent(externalId)}/evaluate-rules${tenantQuery}`, { method: "POST" });
      const result = await response.json();
      if (!response.ok) throw new Error([result.error, result.hint].filter(Boolean).join(" "));
      setInspection((current) => current ? { ...current, risk_score: Number(result.score), status: result.decision, rules_version: result.rulesVersion } : current);
      setEvaluations(result.triggered ?? []);
      setRuleMessage(`Regras aplicadas: ${decisionLabel(result.decision)}.`);
    } catch (reason) { setRuleMessage(reason instanceof Error ? reason.message : "Não foi possível aplicar as regras."); } finally { setCalculatingRules(false); }
  }
  async function moveToTrash() {
    if (!window.confirm(`Mover a vistoria ${externalId} para a lixeira? Os links ativos serão revogados, mas fotos e histórico serão preservados.`)) return;
    setTrashing(true); setTrashMessage("");
    try {
      const response = await fetch(`/api/inspections/${encodeURIComponent(externalId)}/trash`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ action: "trash", tenantId }) });
      const result = await response.json();
      if (!response.ok) throw new Error([result.error, result.hint].filter(Boolean).join(" "));
      setTrashMessage(result.message); window.setTimeout(() => { window.location.href = "/lixeira"; }, 650);
    } catch (error) { setTrashMessage(error instanceof Error ? error.message : "Não foi possível mover a vistoria para a lixeira."); } finally { setTrashing(false); }
  }
  const openPhoto = (photo: Photo) => { setSelectedPhoto(photo); setZoom(1); setPan({ x: 0, y: 0 }); };
  return <main className="detail-page">
    <header className="detail-header"><a className="mini-brand" href="/"><span>✓</span> GRUPO <b>CAPITAL</b></a><a href="/">← Dashboard</a></header>
    <section className="detail-wrap">
      <div className="detail-crumb">Vistorias <span>/</span> {inspection.external_id}</div>
      <div className="detail-title"><div><p className="eyebrow">VISTORIA {inspection.vehicle_type.toUpperCase()}</p><h1>{inspection.vehicle_description || "Veículo não informado"}</h1><p>{inspection.plate} · Proposta {inspection.external_id}</p></div><span className={`detail-status ${statusTone(inspection.status)}`}><i />{stageLabels[inspection.status] ?? inspection.status}</span></div>
      <section className="journey"><div className="journey-step done"><b>1</b><span>Solicitação<br /><small>Recebida</small></span></div><i /><div className={`journey-step ${inspection.status !== "received" ? "done" : ""}`}><b>2</b><span>Validação<br /><small>Aguardando consulta</small></span></div><i /><div className="journey-step"><b>3</b><span>Vistoria<br /><small>{captured}/{route.length} fotos</small></span></div><i /><div className="journey-step"><b>4</b><span>Decisão<br /><small>Regras e IA</small></span></div></section>
      <div className="detail-grid"><div className="detail-main">
        <section className="detail-card"><div className="card-heading"><div><p className="eyebrow">DADOS RECEBIDOS</p><h2>Identificação do veículo</h2></div><span>{labels[inspection.vehicle_type]}</span></div><div className="data-grid"><Data label="Placa" value={inspection.plate} /><Data label="Chassi" value={inspection.chassis} /><Data label="Ano / modelo" value={inspection.model_year ? String(inspection.model_year) : "Não informado"} /><Data label="Responsável" value={inspection.responsible_name} /><Data label="Celular" value={inspection.responsible_phone} /><Data label="Regras" value={inspection.rules_version || "Padrão Capital (provisório)"} /></div></section>
        <TechnicalSummary captured={captured} required={route.length} review={review} />
        <section className="detail-card"><div className="card-heading"><div><p className="eyebrow">CAPTURA E IA</p><h2>Roteiro de fotos</h2></div><span className="photo-counter">{captured} de {route.length}</span></div>{manualReviewOpen && <div className="manual-hint">Análise manual ativa: classifique cada foto. A avaliação humana substitui a leitura da IA naquela imagem e recalcula os pontos.</div>}<div className="photo-review-list">{route.map((item, index) => <PhotoReviewItem key={item} label={item} index={index} photo={photoMap.get(item.toLowerCase())} externalId={inspection.external_id} tenantId={tenantId} analystName={currentAnalyst} manualActive={manualReviewOpen} onOpen={openPhoto} onUpdated={loadInspection} />)}</div></section>
        <TechnicalAnalysis externalId={inspection.external_id} tenantId={tenantId} captured={captured} required={route.length} review={review} analystName={currentAnalyst} manualOpen={manualReviewOpen} onOpenManual={() => setManualReviewOpen(true)} onSaved={loadInspection} />
      </div><aside className="detail-side"><section className="link-card"><p className="eyebrow">LINK DA VISTORIA</p><h2>Enviar para o responsável</h2><p>Cria um link único, válido por 24 horas, para abrir a vistoria no navegador do celular.</p><button onClick={() => generateLink()}>Gerar link seguro</button>{inspectionLink && <div className="generated-link-box"><label>Link seguro da vistoria<input readOnly value={inspectionLink} aria-label="Link seguro da vistoria" onFocus={(event) => event.currentTarget.select()} /></label><div><button type="button" className="link-copy-button" onClick={copyInspectionLink}>Copiar link</button><a href={inspectionLink} target="_blank" rel="noreferrer">Abrir ↗</a></div><p>Enviar pelo canal escolhido</p><div className="link-delivery-actions"><a href={`https://wa.me/${phoneDigits()}?text=${encodeURIComponent(deliveryMessage())}`} target="_blank" rel="noreferrer">WhatsApp</a><a href={`sms:${phoneDigits()}?body=${encodeURIComponent(deliveryMessage())}`}>SMS</a><a href={`mailto:${inspection.responsible_email || ""}?subject=${encodeURIComponent("Autovistoria Veicular")}&body=${encodeURIComponent(deliveryMessage())}`}>E-mail</a></div>{!inspection.responsible_email && <small>O e-mail do responsável não foi informado; o botão abre uma nova mensagem para você preencher o destinatário.</small>}</div>}<button className="link-reinspection" onClick={() => generateLink(true)}>↻ Refazer vistoria e enviar novo link</button><small>Revoga o link anterior e preserva as fotos da tentativa anterior no histórico.</small>{linkMessage && <small>{linkMessage}</small>}</section><section className="link-card report-card"><p className="eyebrow">LAUDO PDF</p><h2>Laudo técnico</h2>{["approved", "approved_with_notes", "rejected"].includes(inspection.status) ? <><p>O laudo contém decisão, regras, fotos, leituras de placa/chassi e análises registradas.</p><a className="report-download" href={`/api/inspections/${encodeURIComponent(inspection.external_id)}/report${tenantQuery}`} target="_blank" rel="noreferrer">Baixar laudo em PDF ↓</a></> : <><p>Disponível somente após decisão conclusiva da IA ou do analista.</p><small>A decisão atual ainda não permite a emissão do laudo.</small></>}</section><section className="decision-card"><p className="eyebrow">MOTOR DE REGRAS</p><h2>{evaluations.length ? decisionLabel(inspection.status as Review["decision"]) : "Aguardando avaliação"}</h2><p>Aplica as regras ativas do cliente aos achados registrados pela IA.</p><div className="risk-row"><span>Índice de risco atual</span><b>{Number(inspection.risk_score)} pts</b></div>{evaluations.length > 0 && <ul className="rule-trigger-list">{evaluations.map((item) => <li key={`${item.rule_code}-${item.created_at || "now"}`}><span>{item.rule_name}</span><b>{Number(item.points) ? `+${Number(item.points)} pts` : item.action === "human_review" ? "Análise humana" : item.action === "retriage" ? "Retriagem" : "Regra aplicada"}</b></li>)}</ul>}<button onClick={calculateRules} disabled={calculatingRules}>{calculatingRules ? "Aplicando regras..." : "Aplicar regras e recalcular"}</button>{ruleMessage && <small>{ruleMessage}</small>}</section><section className="trash-card"><p className="eyebrow">ARQUIVAMENTO</p><h2>Excluir vistoria</h2><p>Move para a lixeira, preserva fotos e histórico e revoga links ativos.</p><button onClick={moveToTrash} disabled={trashing}>{trashing ? "Movendo..." : "Mover para a lixeira"}</button><a href="/lixeira">Abrir lixeira →</a>{trashMessage && <small>{trashMessage}</small>}</section><section className="timeline-card"><p className="eyebrow">LINHA DO TEMPO</p><h2>Atividades</h2><div><i className="timeline-dot active" /><b>Solicitação criada</b><small>{new Date(inspection.created_at).toLocaleString("pt-BR")}</small></div><div><i className="timeline-dot" /><b>Validação cadastral</b><small>Aguardando integração</small></div><div><i className="timeline-dot" /><b>Link ao responsável</b><small>Será enviado após validação</small></div></section></aside></div>
    </section>
    {selectedPhoto && <div className="photo-modal" role="dialog" aria-modal="true" aria-label="Foto ampliada"><button className="photo-backdrop" aria-label="Fechar" onClick={() => setSelectedPhoto(null)} /><section className="photo-modal-card"><header><div><b>{selectedPhoto.category_code}</b><small>Amplie e arraste a foto para analisar os detalhes.</small></div><button onClick={() => setSelectedPhoto(null)}>×</button></header><div className="zoom-stage"><img onPointerDown={(event) => { event.currentTarget.setPointerCapture(event.pointerId); dragOrigin.current = { x: event.clientX - pan.x, y: event.clientY - pan.y }; }} onPointerMove={(event) => { if (dragOrigin.current) setPan({ x: event.clientX - dragOrigin.current.x, y: event.clientY - dragOrigin.current.y }); }} onPointerUp={() => { dragOrigin.current = null; }} onPointerCancel={() => { dragOrigin.current = null; }} style={{ transform: `translate(${pan.x}px, ${pan.y}px) scale(${zoom})` }} src={`/api/inspections/${encodeURIComponent(inspection.external_id)}/photos/${selectedPhoto.id}${tenantQuery}`} alt={`Foto ampliada: ${selectedPhoto.category_code}`} /></div><label className="zoom-control"><span>Zoom</span><input type="range" min="1" max="3" step="0.1" value={zoom} onChange={(event) => setZoom(Number(event.target.value))} /><b>{zoom.toFixed(1)}×</b></label></section></div>}
  </main>;
}

function TechnicalSummary({ captured, required, review }: { captured: number; required: number; review: Review | null }) {
  const complete = captured >= required;
  return <section className="analysis-card analysis-card-priority analysis-summary-card"><div className="analysis-heading"><div><p className="eyebrow">ANÁLISE TÉCNICA</p><h2>Pré-análise por IA</h2><p>Os resultados detalhados, confiança e alertas aparecem em cada foto do roteiro.</p></div><span className={review?.review_status === "completed" ? "analysis-complete" : review ? "analysis-human" : "analysis-pending"}>{review?.review_status === "completed" ? "Decisão registrada" : review ? "Análise humana solicitada" : complete ? "Fotos prontas para análise" : "Roteiro incompleto"}</span></div><div className="analysis-tracks"><article><div className="track-icon ai">✦</div><div><p className="eyebrow">IA</p><h3>{complete ? "Fotos aceitas e registradas" : "Captura em andamento"}</h3><p>{complete ? "Abra cada foto para ver o resultado, os achados e as conferências de identificação." : `${captured} de ${required} fotos aceitas nesta vistoria.`}</p></div></article><article><div className="track-icon human">⌘</div><div><p className="eyebrow">HUMANA</p><h3>{review?.review_status === "completed" ? "Decisão concluída" : review ? "Aguardando decisão" : "Quando necessária"}</h3><p>{review?.review_status === "completed" ? `Registrada por ${review.analyst_name || "analista"}.` : "Depois das fotos, o analista pode assumir o caso e registrar a decisão final."}</p></div></article></div></section>;
}

function PhotoReviewItem({ label, index, photo, externalId, tenantId, analystName, manualActive, onOpen, onUpdated }: { label: string; index: number; photo?: Photo; externalId: string; tenantId: string; analystName: string; manualActive: boolean; onOpen: (photo: Photo) => void; onUpdated: () => void }) {
  const [expanded, setExpanded] = useState(false); const [assessment, setAssessment] = useState(photo?.manual_assessment || "no_damage"); const [damageLocation, setDamageLocation] = useState(photo?.manual_damage_location || ""); const [comment, setComment] = useState(photo?.manual_comments || photo?.human_comment || ""); const [message, setMessage] = useState(""); const [saving, setSaving] = useState(false);
  useEffect(() => {
    setAssessment(photo?.manual_assessment || "no_damage");
    setDamageLocation(photo?.manual_damage_location || "");
    setComment(photo?.manual_comments || photo?.human_comment || "");
  }, [photo?.id, photo?.manual_assessment, photo?.manual_damage_location, photo?.manual_comments, photo?.human_comment]);
  const hasLocation = photo?.latitude !== null && photo?.latitude !== undefined && photo?.longitude !== null && photo?.longitude !== undefined;
  const findings = parseFindings(photo?.analysis_findings);
  const category = String(photo?.category_code || label).toLocaleLowerCase("pt-BR");
  const isPlatePhoto = category === "placa";
  const isChassisPhoto = category.includes("chassi");
  const hasHumanAssessment = Boolean(photo?.manual_assessment || photo?.manual_comments || photo?.human_comment);
  const assessmentLabel = manualAssessmentLabels[String(photo?.manual_assessment || "")] || "Avaliação registrada";
  async function saveAssessment() { if (!photo) return; setSaving(true); setMessage(""); try { const response = await fetch(`/api/inspections/${encodeURIComponent(externalId)}/photos/${photo.id}/assessment`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ assessment, damageLocation, comments: comment, tenantId }) }); const body = await response.json(); if (!response.ok) throw new Error([body.error, body.hint].filter(Boolean).join(" ")); setMessage(body.message || "Classificação salva."); void onUpdated(); } catch (error) { setMessage(error instanceof Error ? error.message : "Não foi possível salvar a classificação."); } finally { setSaving(false); } }
  return <article className="photo-review-row">
    {photo ? <button className="thumbnail-button" onClick={() => onOpen(photo)}><img className="route-thumbnail" src={`/api/inspections/${encodeURIComponent(externalId)}/photos/${photo.id}${tenantId ? `?tenantId=${encodeURIComponent(tenantId)}` : ""}`} alt={`Ampliar foto: ${label}`} /></button> : <div className="photo-number">{String(index + 1).padStart(2, "0")}</div>}
    <div className="photo-main"><h3>{label}</h3><p>{photo ? "Foto recebida" : "Aguardando captura"}</p>{photo && (hasLocation ? <a className="photo-location" href={`https://www.google.com/maps?q=${photo.latitude},${photo.longitude}`} target="_blank" rel="noreferrer">⌖ Ver localização no mapa</a> : <span className="photo-location missing">⌖ Localização não registrada</span>)}</div>
    <div className="photo-actions">{photo ? <><button type="button" className="analysis-expand" onClick={() => setExpanded(!expanded)}>{expanded ? "Ocultar análise IA" : "Ver análise IA"}</button><span className={photo.ai_status === "retriage" ? "photo-status failed" : photo.analysis_status === "requires_human" || photo.ai_status === "flagged" ? "photo-status attention" : photo.ai_status === "accepted" ? "photo-status success" : "photo-status"}>{photo.ai_status === "retriage" ? "Recusada" : photo.analysis_status === "requires_human" || photo.ai_status === "flagged" ? "Com apontamento" : photo.ai_status === "accepted" ? "Sem apontamentos" : photo.analysis_status ? "Analisada" : "Recebida"}</span></> : <span className="photo-status">Pendente</span>}</div>
    {photo && <>{manualActive && <div className="photo-assessment-box"><label><span>Classificação de {analystName}</span><select value={assessment} onChange={(event) => setAssessment(event.target.value)}><option value="no_damage">Sem avaria ou divergência (0 pts)</option><option value="damage_light">Avaria leve (+10 pts)</option><option value="damage_moderate">Avaria moderada (+25 pts)</option><option value="damage_severe">Avaria grave (+45 pts · análise humana)</option><option value="damage_structural">Avaria estrutural/crítica (+70 pts · reprovação)</option>{isPlatePhoto && <option value="plate_divergent">Placa divergente (solicita retriagem)</option>}{isChassisPhoto && <option value="chassis_divergent">Chassi divergente/adulterado (+100 pts · reprovação)</option>}</select></label><label><span>Local da avaria</span><input value={damageLocation} onChange={(event) => setDamageLocation(event.target.value)} placeholder="Ex.: porta dianteira direita" disabled={assessment === "no_damage" || assessment.endsWith("divergent")} /></label><label className="assessment-comment"><span>Comentário técnico</span><textarea value={comment} onChange={(event) => setComment(event.target.value)} placeholder="Descreva o achado ou a justificativa da classificação." /></label><div className="assessment-actions"><small>Os pontos seguem as regras padrão ativas deste cliente.</small><button type="button" onClick={saveAssessment} disabled={saving}>{saving ? "Salvando e recalculando..." : "Salvar classificação"}</button>{message && <small>{message}</small>}</div></div>}{!manualActive && hasHumanAssessment && <div className="photo-human-detail"><div><span>AVALIAÇÃO HUMANA</span><b>{assessmentLabel}</b></div>{photo.manual_analyst_name && <small>Registrada por {photo.manual_analyst_name}</small>}{photo.manual_damage_location && <p><b>Local:</b> {photo.manual_damage_location}</p>}{(photo.manual_comments || photo.human_comment) && <p><b>Comentário:</b> {photo.manual_comments || photo.human_comment}</p>}</div>}{expanded && <div className="photo-ai-detail"><div><span className="demo-badge">{photo.analysis_provider && photo.analysis_provider !== "demo" ? "IA REAL" : "DEMONSTRAÇÃO"}</span><b>Pré-análise por IA</b><span>Confiança: {photo.analysis_confidence ? `${photo.analysis_confidence}%` : "aguardando"}</span></div><p>{photo.analysis_summary || "A foto foi recebida e aguarda a integração com o modelo de IA."}</p>{(isPlatePhoto || isChassisPhoto) && <div className="identity-checks">{isPlatePhoto && photo.plate_match && <span>Placa: <b className={photo.plate_match === "matched" ? "ok" : "alert"}>{photo.plate_match === "matched" ? "confere" : photo.plate_match === "mismatched" ? "divergente" : "não lida"}</b>{photo.ocr_plate ? ` (${photo.ocr_plate})` : ""}</span>}{isChassisPhoto && photo.chassis_match && <span>Chassi: <b className={photo.chassis_match === "matched" ? "ok" : "alert"}>{photo.chassis_match === "matched" ? "confere" : photo.chassis_match === "mismatched" ? "divergente" : "não lido"}</b>{photo.ocr_chassis ? ` (${photo.ocr_chassis})` : ""}</span>}</div>}{findings.length > 0 && <ul>{findings.map((finding) => <li key={finding}>{finding}</li>)}</ul>}{photo.analysis_requires_human ? <small className="attention-text">Encaminhar para conferência humana antes da decisão.</small> : <small>{photo.analysis_provider && photo.analysis_provider !== "demo" ? "Resultado da IA registrado; decisão financeira segue as regras e exceções configuradas." : "Resultado ilustrativo para apresentação; não constitui decisão automática."}</small>}</div>}</>}
  </article>;
}

function TechnicalAnalysis({ externalId, tenantId, captured, required, review, analystName, manualOpen, onOpenManual, onSaved }: { externalId: string; tenantId: string; captured: number; required: number; review: Review | null; analystName: string; manualOpen: boolean; onOpenManual: () => void; onSaved: () => void }) {
  const [message, setMessage] = useState(""); const [saving, setSaving] = useState(false); const [decision, setDecision] = useState("approved"); const [reason, setReason] = useState(""); const [comments, setComments] = useState(""); const [confirmedFindings, setConfirmedFindings] = useState(""); const [discardedFindings, setDiscardedFindings] = useState("");
  async function requestHumanReview() { setSaving(true); try { const response = await fetch(`/api/inspections/${encodeURIComponent(externalId)}/review`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ action: "request", tenantId }) }); const result = await response.json(); if (!response.ok) throw new Error([result.error, result.hint].filter(Boolean).join(" ")); onOpenManual(); setMessage("Análise manual iniciada. Registre os comentários nas fotos e a decisão abaixo."); } catch (error) { setMessage(error instanceof Error ? error.message : "Não foi possível solicitar a análise humana."); } finally { setSaving(false); } }
  async function submitReview(event: React.FormEvent<HTMLFormElement>) { event.preventDefault(); setSaving(true); setMessage(""); try { const response = await fetch(`/api/inspections/${encodeURIComponent(externalId)}/review`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ action: "complete", decision, reason, comments, confirmedFindings, discardedFindings, tenantId }) }); const result = await response.json(); if (!response.ok) throw new Error([result.error, result.hint].filter(Boolean).join(" ")); setMessage("Decisão registrada com sucesso."); window.setTimeout(onSaved, 650); } catch (error) { setMessage(error instanceof Error ? error.message : "Não foi possível registrar a decisão."); } finally { setSaving(false); } }
  const aiReady = captured >= required;
  return <section className="analysis-card analysis-card-priority"><div className="analysis-heading"><div><p className="eyebrow">DECISÃO APÓS REVISÃO DAS FOTOS</p><h2>Decisão do analista</h2><p>Depois de revisar as fotos e a pré-análise técnica, registre a decisão final da vistoria.</p></div><span className={review?.review_status === "completed" ? "analysis-complete" : review ? "analysis-human" : "analysis-pending"}>{review?.review_status === "completed" ? "Decisão registrada" : review ? "Aguardando analista" : "Sem análise humana"}</span></div><div className="analysis-tracks"><article><div className="track-icon ai">✦</div><div><p className="eyebrow">IA</p><h3>{aiReady ? "Pré-análise disponível" : "Roteiro incompleto"}</h3><p>{aiReady ? "Achados e confiança ficam em cada foto." : `${captured} de ${required} fotos recebidas.`}</p></div></article><article><div className="track-icon human">⌘</div><div><p className="eyebrow">HUMANA</p><h3>{review?.review_status === "completed" ? `Concluída por ${review.analyst_name}` : review ? "Na fila" : "Sem solicitação"}</h3><p>{review?.review_status === "completed" ? `Decisão: ${decisionLabel(review.decision)}` : "Assuma somente se precisar validar a vistoria."}</p></div></article></div>{review?.review_status === "completed" ? <div className="review-summary"><b>Comentários do analista</b><p>{review.comments}</p><div><span>Regras: {review.rules_version || "Padrão Capital"}</span><span>Concluída em {review.completed_at ? new Date(review.completed_at).toLocaleString("pt-BR") : "—"}</span></div></div> : manualOpen ? <form className="review-form" onSubmit={submitReview}><div className="review-form-title"><div><p className="eyebrow">DECISÃO DO ANALISTA</p><h3>Registrar análise humana</h3><small>Analista identificado automaticamente: <b>{analystName}</b></small></div><span>Obrigatório para liberar o laudo e a integração</span></div><div className="review-grid"><label><span>Decisão final *</span><select value={decision} onChange={(event) => setDecision(event.target.value)}><option value="approved">Aprovada</option><option value="approved_with_notes">Aprovada com ressalvas</option><option value="retriage">Solicitar retriagem</option><option value="rejected">Reprovada</option></select></label><ReviewField label="Motivo da decisão" value={reason} onChange={setReason} required /></div><div className="review-grid findings"><ReviewArea label="Achados/avarias confirmados" value={confirmedFindings} onChange={setConfirmedFindings} placeholder="Um item por linha" /><ReviewArea label="Achados descartados" value={discardedFindings} onChange={setDiscardedFindings} placeholder="Um item por linha" /></div><ReviewArea label="Comentários técnicos do analista" value={comments} onChange={setComments} placeholder="Descreva a análise, divergências e orientações." required /><div className="review-actions"><span>{message}</span><button type="submit" disabled={saving}>{saving ? "Registrando..." : "Registrar decisão final"}</button></div></form> : <div className="analysis-actions"><div><b>{review ? "A vistoria já está na fila humana" : "Há algo que exige validação?"}</b><p>{review ? "Assuma a análise para liberar os comentários por foto e a decisão final." : "Envie esta vistoria para a fila de análise humana da Capital."}</p></div><button onClick={review ? onOpenManual : requestHumanReview} disabled={saving}>{saving ? "Solicitando..." : review ? "Assumir análise manual" : "Iniciar análise manual"}</button>{message && <small>{message}</small>}</div>}</section>;
}

function Data({ label, value }: { label: string; value: string }) { return <div><span>{label}</span><b>{value}</b></div>; }
function ReviewField({ label, value, onChange, required = false }: { label: string; value: string; onChange: (value: string) => void; required?: boolean }) { return <label><span>{label}{required ? " *" : ""}</span><input value={value} onChange={(event) => onChange(event.target.value)} required={required} /></label>; }
function ReviewArea({ label, value, onChange, placeholder, required = false }: { label: string; value: string; onChange: (value: string) => void; placeholder?: string; required?: boolean }) { const isUnconfirmedAlert = label === "Achados descartados"; const displayLabel = isUnconfirmedAlert ? "Alertas da IA não confirmados" : label; return <label><span>{displayLabel}{required ? " *" : ""}</span>{isUnconfirmedAlert && <small className="review-field-help">Opcional: use apenas se a IA sinalizou algo que você verificou e não confirmou.</small>}<textarea value={value} onChange={(event) => onChange(event.target.value)} placeholder={isUnconfirmedAlert ? "Ex.: IA indicou risco de avaria, mas não foi confirmado" : placeholder} required={required} /></label>; }
function decisionLabel(decision: Review["decision"] | "human_review") { return ({ approved: "Aprovada", approved_with_notes: "Aprovada com ressalvas", retriage: "Retriagem", rejected: "Reprovada", human_review: "Análise humana necessária" } as Record<string, string>)[decision || ""] || "—"; }
function parseFindings(value: Photo["analysis_findings"]) { if (Array.isArray(value)) return value.map(String); if (typeof value !== "string") return []; try { const parsed = JSON.parse(value); return Array.isArray(parsed) ? parsed.map(String) : []; } catch { return []; } }
