"use client";

import { type ChangeEvent, type CSSProperties, useEffect, useState } from "react";

type Branding = { displayName: string; logoUrl: string | null; primaryColor: string; accentColor: string; backgroundColor: string };
type CapturePolicy = { qualityAction: "human_review" | "retriage"; plateUnreadableAction: "human_review" | "retriage"; plateMismatchAction: "human_review" | "block_approval" };

export default function ClientSettingsPage() {
  const [branding, setBranding] = useState<Branding | null>(null);
  const [policy, setPolicy] = useState<CapturePolicy | null>(null);
  const [logo, setLogo] = useState<File | null>(null);
  const [logoPreview, setLogoPreview] = useState<string | null>(null);
  const [message, setMessage] = useState(""); const [policyMessage, setPolicyMessage] = useState("");
  const [saving, setSaving] = useState(false); const [savingPolicy, setSavingPolicy] = useState(false); const [allowed, setAllowed] = useState<boolean | null>(null);

  useEffect(() => {
    fetch("/api/client/branding").then(async response => ({ response, body: await response.json() })).then(({ response, body }) => { if (!response.ok) { setMessage(body.error || "Não foi possível abrir a personalização."); setAllowed(false); return; } setBranding(body.branding); setAllowed(Boolean(body.canManage)); }).catch(() => { setMessage("Não foi possível carregar a personalização."); setAllowed(false); });
    fetch("/api/client/capture-policy").then(async response => ({ response, body: await response.json() })).then(({ response, body }) => { if (response.ok) setPolicy(body.policy); else setPolicyMessage(body.error || "Não foi possível carregar os critérios de captura."); }).catch(() => setPolicyMessage("Não foi possível carregar os critérios de captura."));
  }, []);

  function color(field: keyof Branding, event: ChangeEvent<HTMLInputElement>) { setBranding(current => current ? { ...current, [field]: event.target.value } : current); }
  function chooseLogo(event: ChangeEvent<HTMLInputElement>) { const file = event.target.files?.[0] || null; setLogo(file); setLogoPreview(file ? URL.createObjectURL(file) : null); }
  function updatePolicy(field: keyof CapturePolicy, value: string) { setPolicy(current => current ? { ...current, [field]: value } as CapturePolicy : current); }
  async function save(event: React.FormEvent<HTMLFormElement>) { event.preventDefault(); if (!branding) return; setSaving(true); setMessage(""); const form = new FormData(); form.set("displayName", branding.displayName); form.set("primaryColor", branding.primaryColor); form.set("accentColor", branding.accentColor); form.set("backgroundColor", branding.backgroundColor); if (logo) form.set("logo", logo); try { const response = await fetch("/api/client/branding", { method: "PUT", body: form }); const body = await response.json(); if (!response.ok) throw new Error(body.error || "Não foi possível salvar."); setMessage(body.message); setLogo(null); setLogoPreview(null); const fresh = await fetch("/api/client/branding").then(response => response.json()); if (fresh.branding) setBranding(fresh.branding); } catch (error) { setMessage(error instanceof Error ? error.message : "Não foi possível salvar."); } finally { setSaving(false); } }
  async function savePolicy(event: React.FormEvent<HTMLFormElement>) { event.preventDefault(); if (!policy) return; setSavingPolicy(true); setPolicyMessage(""); try { const response = await fetch("/api/client/capture-policy", { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify(policy) }); const body = await response.json(); if (!response.ok) throw new Error(body.error || "Não foi possível salvar."); setPolicy(body.policy); setPolicyMessage(body.message); } catch (error) { setPolicyMessage(error instanceof Error ? error.message : "Não foi possível salvar os critérios."); } finally { setSavingPolicy(false); } }

  if (allowed === false) return <main className="brand-settings-page"><a href="/cliente">← Voltar ao portal</a><section className="brand-settings-card"><p className="eyebrow">ACESSO RESTRITO</p><h1>Configurações do portal</h1><p>{message || "Somente o administrador do cliente pode alterar a identidade visual e os critérios de captura."}</p></section></main>;
  if (!branding) return <main className="brand-settings-page"><p className="eyebrow">CARREGANDO</p><h1>Preparando configurações...</h1></main>;
  const style = { "--client-primary": branding.primaryColor, "--client-accent": branding.accentColor, "--client-background": branding.backgroundColor } as CSSProperties; const previewLogo = logoPreview || branding.logoUrl;
  return <main className="brand-settings-page" style={style}><header><a className="client-brand" href="/cliente">{branding.logoUrl ? <img className="client-brand-logo" src={branding.logoUrl} alt="Logo atual" /> : <><span>✓</span><b>{branding.displayName}</b><i>·</i> Autovistoria Veicular</>}</a><a href="/cliente">← Voltar ao portal</a></header><section className="brand-settings-wrap"><div className="brand-settings-intro"><p className="eyebrow">ADMINISTRAÇÃO DO CLIENTE</p><h1>Portal e critérios de vistoria</h1><p>Personalize a identidade visual e determine como o sistema deve orientar quem tira as fotos. As políticas afetam a continuidade da captura e a decisão final de forma separada.</p></div><div className="brand-settings-forms"><form className="brand-settings-card" onSubmit={save}><div className={previewLogo ? "brand-preview has-logo" : "brand-preview"}><div className="brand-preview-logo">{previewLogo ? <img src={previewLogo} alt="Prévia do logo" /> : <span>✓</span>}</div>{previewLogo ? <small>Prévia do logo no cabeçalho</small> : <div><b>{branding.displayName}</b><small>Autovistoria Veicular</small></div>}</div><h2>Marca do portal</h2><label>Nome exibido no portal<input value={branding.displayName} onChange={event => setBranding({ ...branding, displayName: event.target.value })} maxLength={160} required /></label><label>Logo da empresa<input type="file" accept="image/png,image/jpeg,image/webp" onChange={chooseLogo} /><small>PNG, JPG ou WebP, até 2 MB. A prévia aparece antes de salvar; o novo arquivo substitui o logo anterior.</small></label><div className="brand-color-grid"><label>Cor principal<input type="color" value={branding.primaryColor} onChange={event => color("primaryColor", event)} /><code>{branding.primaryColor}</code></label><label>Cor de destaque<input type="color" value={branding.accentColor} onChange={event => color("accentColor", event)} /><code>{branding.accentColor}</code></label><label>Cor de fundo<input type="color" value={branding.backgroundColor} onChange={event => color("backgroundColor", event)} /><code>{branding.backgroundColor}</code></label></div><div className="brand-swatch-preview"><span>Principal</span><span>Destaque</span><span>Fundo</span></div>{message && <p className="brand-message">{message}</p>}<button disabled={saving}>{saving ? "Salvando..." : "Salvar personalização"}</button></form><form className="brand-settings-card capture-policy-card" onSubmit={savePolicy}><p className="eyebrow">CAPTURA E IDENTIFICAÇÃO</p><h2>Critérios da vistoria</h2><p className="form-copy">O padrão é tolerante: a vistoria não perde uma foto aceitável por um alerta de IA. Casos marcados seguem registrados para a decisão final.</p><label>Foto com alerta de qualidade, enquadramento ou iluminação<select value={policy?.qualityAction || "human_review"} onChange={event => updatePolicy("qualityAction", event.target.value)} disabled={!policy}><option value="human_review">Aceitar a foto e encaminhar para análise humana</option><option value="retriage">Solicitar nova foto antes de avançar</option></select><small>Use nova foto apenas quando quiser uma captura estritamente padronizada. O padrão reduz atrito para o vistoriador.</small></label><label>Placa traseira não legível<select value={policy?.plateUnreadableAction || "human_review"} onChange={event => updatePolicy("plateUnreadableAction", event.target.value)} disabled={!policy}><option value="human_review">Aceitar e encaminhar para análise humana</option><option value="retriage">Solicitar nova foto da placa</option></select><small>A foto de placa deve mostrar a placa traseira; quando existir, mantenha também o QR Code Mercosul visível.</small></label><label>Placa lida diferente da solicitação<select value={policy?.plateMismatchAction || "human_review"} onChange={event => updatePolicy("plateMismatchAction", event.target.value)} disabled={!policy}><option value="human_review">Encaminhar para análise humana</option><option value="block_approval">Impedir aprovação automática</option></select><small>Em ambas as opções o vistoriador continua para a próxima foto e conclui o roteiro. A diferença é aplicada somente na decisão da vistoria.</small></label>{policyMessage && <p className="brand-message">{policyMessage}</p>}<button disabled={savingPolicy || !policy}>{savingPolicy ? "Salvando..." : "Salvar critérios de vistoria"}</button></form></div></section></main>;
}
