"use client";

import Link from "next/link";
import { FormEvent, useCallback, useEffect, useState } from "react";
import { userMessage } from "../lib/messages";

const apiBase = process.env.NEXT_PUBLIC_API_BASE_URL || "/api/v1";
const tramitesBase = process.env.NEXT_PUBLIC_TRAMITES_BASE_URL || "https://tramites.documenta.cl";
type Row = Record<string, unknown>;
type Tab = "inicio" | "solicitudes" | "documentos" | "pagos" | "notificaciones" | "perfil" | "privacidad";

const tabs: Array<{id:Tab;label:string}> = [
  {id:"inicio",label:"Inicio"},{id:"solicitudes",label:"Mis solicitudes"},
  {id:"documentos",label:"Documentos"},{id:"pagos",label:"Pagos"},
  {id:"notificaciones",label:"Notificaciones"},{id:"perfil",label:"Mi perfil"},
  {id:"privacidad",label:"Privacidad"},
];

function date(value: unknown) {
  if (!value) return "—";
  return new Intl.DateTimeFormat("es-CL", {dateStyle:"medium",timeStyle:"short"}).format(new Date(String(value)));
}
function money(value: unknown, currency: unknown = "CLP") {
  return new Intl.NumberFormat("es-CL", {style:"currency",currency:String(currency || "CLP"),maximumFractionDigits:0}).format(Number(value || 0));
}
function text(value: unknown) { return String(value ?? ""); }
function label(value: unknown) { return text(value).replaceAll("_", " ").toLowerCase(); }
function errorMessage(detail: unknown, fallback: string) {
  if (typeof detail === "string") return detail;
  if (Array.isArray(detail)) return detail.map((item) => typeof item === "object" && item && "msg" in item ? String(item.msg) : "Dato inválido").join(" · ");
  return fallback;
}

export default function PersonasPage() {
  const [tab,setTab] = useState<Tab>("inicio");
  const [me,setMe] = useState<Row|null>(null);
  const [data,setData] = useState<Row|null>(null);
  const [detail,setDetail] = useState<Row|null>(null);
  const [busy,setBusy] = useState(true);
  const [notice,setNotice] = useState("");
  const [error,setError] = useState("");

  const csrf = useCallback(async () => {
    const cached = sessionStorage.getItem("documenta:csrf");
    if (cached) return cached;
    const response = await fetch(`${apiBase}/auth/csrf`, {credentials:"include",cache:"no-store"});
    if (response.status === 401) { window.location.replace("/acceso?motivo=sesion-expirada"); throw new Error("Sesión expirada"); }
    const body = await response.json();
    if (!response.ok) throw new Error(errorMessage(body.detail,"No fue posible validar la sesión."));
    sessionStorage.setItem("documenta:csrf", body.csrf_token);
    return String(body.csrf_token);
  },[]);

  const request = useCallback(async(path:string,options:RequestInit={}) => {
    const response = await fetch(`${apiBase}/personas${path}`, {credentials:"include",cache:"no-store",...options});
    if (response.status === 401) {
      sessionStorage.removeItem("documenta:csrf");
      window.location.replace("/acceso?motivo=sesion-expirada");
      throw new Error("Sesión expirada");
    }
    const contentType=response.headers.get("content-type")||"";
    const body=contentType.includes("application/json") ? await response.json() : null;
    if (!response.ok) throw new Error(errorMessage(body?.detail,"No fue posible completar la operación."));
    return body as Row;
  },[]);

  const load = useCallback(async(next:Tab) => {
    setBusy(true); setError(""); setDetail(null);
    const routes:Record<Tab,string>={inicio:"",solicitudes:"/requests",documentos:"/documents",pagos:"/payments",notificaciones:"/notifications",perfil:"/profile",privacidad:"/privacy"};
    try { setData(await request(routes[next])); setTab(next); }
    catch(reason) { setError(userMessage(reason, "No fue posible cargar el portal.")); }
    finally { setBusy(false); }
  },[request]);

  useEffect(() => { (async()=>{
    try {
      const response=await fetch(`${apiBase}/auth/me`,{credentials:"include",cache:"no-store"});
      if(!response.ok){window.location.replace("/acceso");return;}
      const identity=await response.json(); setMe(identity); await load("inicio");
    } catch { setError("No fue posible conectar con Documenta."); setBusy(false); }
  })(); },[load]);

  async function openRequest(id:number){setBusy(true);setError("");try{const [opened,list]=await Promise.all([request(`/requests/${id}`),request("/requests")]);setData(list);setDetail(opened);setTab("solicitudes");}catch(reason){setError(reason instanceof Error?reason.message:"No fue posible abrir la solicitud.");}finally{setBusy(false)}}
  async function mutate(path:string,method="POST",body?:unknown){
    const token=await csrf();
    const result=await request(path,{method,headers:{"X-CSRF-Token":token,...(body?{"Content-Type":"application/json"}:{})},body:body?JSON.stringify(body):undefined});
    setNotice("Cambio guardado correctamente."); setTimeout(()=>setNotice(""),4500); return result;
  }
  async function documentAction(id:number,action:"read"|"accept"){
    setBusy(true);setError("");try{await mutate(`/documents/${id}/${action}`);await load("documentos");}catch(reason){setError(reason instanceof Error?reason.message:"No fue posible actualizar el documento.");}finally{setBusy(false)}
  }
  async function download(id:number,format:"pdf"|"docx"){
    setBusy(true);setError("");try{
      const response=await fetch(`${apiBase}/personas/documents/${id}/download?format=${format}`,{credentials:"include"});
      if(response.status===401){window.location.replace("/acceso?motivo=sesion-expirada");return;}
      if(!response.ok){const body=await response.json();throw new Error(errorMessage(body.detail,"No fue posible descargar el archivo."));}
      const blob=await response.blob(),url=URL.createObjectURL(blob),anchor=document.createElement("a");
      anchor.href=url;anchor.download=`documenta-${id}.${format}`;anchor.click();URL.revokeObjectURL(url);
      await load("documentos");
    }catch(reason){setError(reason instanceof Error?reason.message:"No fue posible descargar el documento.");}finally{setBusy(false)}
  }
  async function share(event:FormEvent<HTMLFormElement>,requestId:number){event.preventDefault();setBusy(true);setError("");try{const form=new FormData(event.currentTarget);await mutate(`/documents/${requestId}/share`,"POST",{email:form.get("email"),permiso:form.get("permiso"),dias_vigencia:Number(form.get("dias_vigencia"))});event.currentTarget.reset();await openRequest(requestId);}catch(reason){setError(reason instanceof Error?reason.message:"No fue posible compartir el documento.");}finally{setBusy(false)}}
  async function revoke(accessId:number,requestId:number){if(!window.confirm("¿Revocar este acceso al documento?"))return;setBusy(true);try{await mutate(`/shares/${accessId}`,"DELETE");await openRequest(requestId);}catch(reason){setError(reason instanceof Error?reason.message:"No fue posible revocar el acceso.");}finally{setBusy(false)}}
  async function saveProfile(event:FormEvent<HTMLFormElement>){event.preventDefault();setBusy(true);setError("");try{const form=new FormData(event.currentTarget);await mutate("/profile","PUT",{nombres:form.get("nombres"),apellidos:form.get("apellidos"),telefono:form.get("telefono")||null,notificaciones_email:form.get("notificaciones_email")==="on",notificaciones_portal:form.get("notificaciones_portal")==="on",resumen_actividad:form.get("resumen_actividad")==="on"});await load("perfil");}catch(reason){setError(reason instanceof Error?reason.message:"No fue posible guardar el perfil.");}finally{setBusy(false)}}
  async function logout(){try{const token=await csrf();await fetch(`${apiBase}/auth/logout`,{method:"POST",credentials:"include",headers:{"X-CSRF-Token":token}});}finally{sessionStorage.removeItem("documenta:csrf");window.location.replace("/acceso");}}

  if(!me)return <main className="session-gate" aria-label="Validando sesión"/>;
  const unread=Number((data?.metrics as Row|undefined)?.no_leidas || 0);
  return <main className="people-shell">
    <header className="people-topbar"><Link href="/personas" className="people-logo"><img src="/media/brand/logo-horizontal.svg" alt="Documenta" /></Link><div><span>Portal de personas</span><strong>{text(me?.nombres)} {text(me?.apellidos)}</strong></div><a className="button button-primary people-new" href={tramitesBase}>Nuevo trámite</a><button className="people-logout" onClick={logout}>Cerrar sesión</button></header>
    <div className="people-layout">
      <aside className="people-sidebar"><div className="people-welcome"><span>Mi espacio</span><strong>Hola, {text(me?.nombres).split(" ")[0] || "bienvenido"}</strong><small>Todo lo que solicitas y recibes, en un lugar seguro.</small></div><nav>{tabs.map(item=><button key={item.id} className={tab===item.id?"active":""} onClick={()=>load(item.id)}>{item.label}{item.id==="notificaciones"&&unread>0?<b>{unread}</b>:null}</button>)}</nav><a href={tramitesBase}>Ir a Trámites Documenta ↗</a></aside>
      <section className="people-content">
        {notice&&<div className="people-toast" role="status">{notice}<button onClick={()=>setNotice("")}>×</button></div>}
        {error&&<div className="form-error people-error" role="alert">{error}<button onClick={()=>setError("")}>×</button></div>}
        {busy&&!data?<div className="people-loading">Cargando tu espacio seguro…</div>:<PortalContent tab={tab} data={data} detail={detail} busy={busy} openRequest={openRequest} documentAction={documentAction} download={download} share={share} revoke={revoke} saveProfile={saveProfile} mutate={mutate} reload={()=>load(tab)} />}
      </section>
    </div>
  </main>;
}

function PortalContent({tab,data,detail,busy,openRequest,documentAction,download,share,revoke,saveProfile,mutate,reload}:{tab:Tab;data:Row|null;detail:Row|null;busy:boolean;openRequest:(id:number)=>void;documentAction:(id:number,action:"read"|"accept")=>void;download:(id:number,format:"pdf"|"docx")=>void;share:(event:FormEvent<HTMLFormElement>,id:number)=>void;revoke:(access:number,requestId:number)=>void;saveProfile:(event:FormEvent<HTMLFormElement>)=>void;mutate:(path:string,method?:string,body?:unknown)=>Promise<Row>;reload:()=>void}){
  if(!data)return <div className="people-loading">Sin información disponible.</div>;
  if(tab==="inicio")return <Home data={data} openRequest={openRequest}/>;
  if(tab==="solicitudes")return <><SectionTitle eyebrow="Actividad" title="Mis solicitudes" description="Sigue cada trámite desde su ingreso hasta la entrega."/><RequestTable items={(data.items||[]) as Row[]} openRequest={openRequest}/>{detail&&<RequestDetail data={detail} busy={busy} share={share} revoke={revoke}/>}</>;
  if(tab==="documentos")return <Documents items={(data.items||[]) as Row[]} busy={busy} action={documentAction} download={download}/>;
  if(tab==="pagos")return <Payments items={(data.items||[]) as Row[]}/>;
  if(tab==="notificaciones")return <Notifications items={(data.items||[]) as Row[]} read={async(id)=>{await mutate(`/notifications/${id}/read`,"PUT");reload();}}/>;
  if(tab==="perfil")return <Profile data={data} save={saveProfile}/>;
  return <Privacy data={data}/>;
}

function SectionTitle({eyebrow,title,description}:{eyebrow:string;title:string;description:string}){return <header className="people-heading"><span>{eyebrow}</span><h1>{title}</h1><p>{description}</p></header>}
function Status({value}:{value:unknown}){return <span className={`people-status status-${text(value).toLowerCase()}`}>{label(value)}</span>}

function Home({data,openRequest}:{data:Row;openRequest:(id:number)=>void}){
  const metrics=(data.metrics||{}) as Row,recent=(data.recent||[]) as Row[],notices=(data.notifications||[]) as Row[];
  return <><SectionTitle eyebrow="Tu actividad" title="Todo en orden, desde aquí" description="Consulta tus solicitudes, pagos y documentos recibidos sin perder trazabilidad."/><div className="people-metrics"><Metric value={metrics.solicitudes} label="Solicitudes"/><Metric value={metrics.activas} label="En curso"/><Metric value={metrics.compartidos} label="Compartidos contigo"/><Metric value={metrics.no_leidas} label="Avisos nuevos"/></div><div className="people-two"><section className="people-card"><div className="people-card-head"><h2>Actividad reciente</h2></div><RequestTable items={recent} openRequest={openRequest} compact/></section><section className="people-card"><div className="people-card-head"><h2>Últimos avisos</h2></div><div className="people-notice-list">{notices.length?notices.map(item=><article key={Number(item.id)}><i className={item.leida_en?"":"new"}/><div><strong>{text(item.titulo)}</strong><p>{text(item.mensaje)}</p><small>{date(item.creada_en)}</small></div></article>):<Empty text="No tienes avisos pendientes."/>}</div></section></div></>;
}
function Metric({value,label:caption}:{value:unknown;label:string}){return <article><strong>{Number(value||0)}</strong><span>{caption}</span></article>}
function Empty({text:message}:{text:string}){return <div className="people-empty"><strong>Aún no hay información</strong><p>{message}</p></div>}
function RequestTable({items,openRequest,compact=false}:{items:Row[];openRequest:(id:number)=>void;compact?:boolean}){if(!items.length)return <Empty text="Cuando inicies un trámite, aparecerá aquí."/>;return <div className="people-table-wrap"><table className="people-table"><thead><tr><th>Solicitud</th><th>Servicio</th>{!compact&&<th>Entidad</th>}<th>Estado</th><th>Actualización</th><th/></tr></thead><tbody>{items.map(item=><tr key={Number(item.id)}><td><strong>{text(item.folio)}</strong></td><td>{text(item.servicio)}</td>{!compact&&<td>{text(item.entidad)}</td>}<td><Status value={item.estado}/></td><td>{date(item.actualizada_en)}</td><td><button onClick={()=>openRequest(Number(item.id))}>Ver detalle</button></td></tr>)}</tbody></table></div>}

function RequestDetail({data,busy,share,revoke}:{data:Row;busy:boolean;share:(event:FormEvent<HTMLFormElement>,id:number)=>void;revoke:(access:number,requestId:number)=>void}){
  const item=data.solicitud as Row,history=(data.historial||[]) as Row[],payments=(data.pagos||[]) as Row[],shares=(data.comparticiones||[]) as Row[];
  return <section className="people-detail"><div className="people-card-head"><div><span>Detalle de solicitud</span><h2>{text(item.folio)}</h2></div><Status value={item.estado}/></div><div className="people-detail-grid"><article><small>Servicio</small><strong>{text(item.servicio)}</strong></article><article><small>Entidad</small><strong>{text(item.entidad)}</strong></article><article><small>Total</small><strong>{money(item.total,item.moneda)}</strong></article><article><small>Creada</small><strong>{date(item.creada_en)}</strong></article></div><div className="people-two"><div><h3>Historial</h3><ol className="people-timeline">{history.map((row,index)=><li key={index}><i/><div><strong>{label(row.estado_destino)}</strong><p>{text(row.motivo)||"Actualización registrada"}</p><small>{date(row.creado_en)}</small></div></li>)}</ol></div><div><h3>Pagos</h3>{payments.length?payments.map(row=><div className="people-payment-mini" key={Number(row.id)}><strong>{text(row.proveedor_codigo)} · {money(row.monto,row.moneda)}</strong><Status value={row.estado}/><small>{date(row.confirmado_en||row.iniciado_en)}</small></div>):<Empty text="Esta solicitud no registra pagos."/>}</div></div>{item.estado==="COMPLETADA"&&<div className="people-share"><h3>Compartir el documento</h3><p>Sólo una persona con cuenta activa en Documenta podrá abrirlo. Puedes revocar el acceso cuando quieras.</p><form onSubmit={(event)=>share(event,Number(item.id))}><input name="email" type="email" placeholder="correo@ejemplo.cl" required/><select name="permiso" defaultValue="LECTURA"><option value="LECTURA">Sólo lectura</option><option value="DESCARGA">Lectura y descarga</option><option value="ACEPTACION">Lectura y aceptación</option></select><input name="dias_vigencia" type="number" min="1" max="365" defaultValue="30" required/><button disabled={busy}>Compartir</button></form>{shares.map(row=><div className="people-share-row" key={Number(row.id)}><div><strong>{text(row.destinatario)}</strong><small>{label(row.permiso)} · vence {date(row.expira_en)}</small></div>{row.revocado_en?<Status value="REVOCADO"/>:<button onClick={()=>revoke(Number(row.id),Number(item.id))}>Revocar</button>}</div>)}</div>}</section>;
}
function Documents({items,busy,action,download}:{items:Row[];busy:boolean;action:(id:number,type:"read"|"accept")=>void;download:(id:number,format:"pdf"|"docx")=>void}){return <><SectionTitle eyebrow="Archivo personal" title="Mis documentos" description="Documentos emitidos para ti y archivos que otras personas compartieron contigo."/>{items.length?<div className="people-document-grid">{items.map((item,index)=><article key={`${item.solicitud_id}-${index}`}><div className="people-doc-icon">PDF</div><Status value={item.propietario?"PROPIO":item.permiso}/><h2>{text(item.documento)}</h2><p>{text(item.remitente)}</p><small>{text(item.folio)} · {date(item.fecha)}</small>{Boolean(item.codigo_verificacion)&&<a className="people-doc-verification" href={`https://documenta.cl/verificar?codigo=${encodeURIComponent(text(item.codigo_verificacion))}`} target="_blank" rel="noreferrer">Verificar: {text(item.codigo_verificacion)} ↗</a>}<div className="people-doc-flags"><span>{item.leido?"Leído":"No leído"}</span>{Boolean(item.aceptado)&&<span>Aceptado</span>}</div><div className="people-doc-actions">{!item.leido&&<button disabled={busy} onClick={()=>action(Number(item.solicitud_id),"read")}>Marcar leído</button>}{Boolean(item.propietario||item.permiso!=="LECTURA")&&<button disabled={busy} onClick={()=>download(Number(item.solicitud_id),"pdf")}>Descargar PDF</button>}{Boolean(item.propietario)&&<button disabled={busy} onClick={()=>download(Number(item.solicitud_id),"docx")}>Descargar Word</button>}{Boolean((item.propietario||item.permiso==="ACEPTACION")&&!item.aceptado)&&<button className="primary" disabled={busy} onClick={()=>action(Number(item.solicitud_id),"accept")}>Aceptar</button>}</div></article>)}</div>:<Empty text="Los documentos entregados y compartidos aparecerán aquí."/>}</>}
function Payments({items}:{items:Row[]}){return <><SectionTitle eyebrow="Comprobantes" title="Mis pagos" description="Historial de pagos asociado a tus solicitudes Documenta."/>{items.length?<div className="people-table-wrap"><table className="people-table"><thead><tr><th>Solicitud</th><th>Servicio</th><th>Medio</th><th>Monto</th><th>Estado</th><th>Fecha</th></tr></thead><tbody>{items.map(row=><tr key={Number(row.id)}><td><strong>{text(row.folio)}</strong></td><td>{text(row.servicio)}</td><td>{text(row.proveedor_codigo)}</td><td>{money(row.monto,row.moneda)}</td><td><Status value={row.estado}/></td><td>{date(row.confirmado_en||row.iniciado_en)}</td></tr>)}</tbody></table></div>:<Empty text="Aún no tienes pagos asociados a tu cuenta."/>}</>}
function Notifications({items,read}:{items:Row[];read:(id:number)=>void}){return <><SectionTitle eyebrow="Novedades" title="Notificaciones" description="Cambios de estado, documentos recibidos y actividad importante."/><div className="people-notifications">{items.length?items.map(row=><article className={row.leida_en?"":"unread"} key={Number(row.id)}><i/><div><strong>{text(row.titulo)}</strong><p>{text(row.mensaje)}</p><small>{date(row.creada_en)}</small></div>{!row.leida_en&&<button onClick={()=>read(Number(row.id))}>Marcar leída</button>}</article>):<Empty text="No tienes notificaciones."/>}</div></>}
function Profile({data,save}:{data:Row;save:(event:FormEvent<HTMLFormElement>)=>void}){return <><SectionTitle eyebrow="Cuenta" title="Mi perfil" description="Mantén actualizados tus datos y elige cómo quieres recibir novedades."/><form className="people-profile people-card" onSubmit={save}><div className="people-form-grid"><label>Nombres<input name="nombres" defaultValue={text(data.nombres)} required minLength={2}/></label><label>Apellidos<input name="apellidos" defaultValue={text(data.apellidos)} required minLength={2}/></label><label>Correo<input value={text(data.email)} disabled/></label><label>RUT<input value={text(data.rut)} disabled/></label><label>Teléfono<input name="telefono" defaultValue={text(data.telefono)}/></label><label>Seguridad<input value={data.mfa_habilitado?"Segundo factor habilitado":"Segundo factor pendiente"} disabled/></label></div><fieldset><legend>Preferencias</legend><label><input type="checkbox" name="notificaciones_email" defaultChecked={Boolean(data.notificaciones_email)}/> Recibir avisos por correo</label><label><input type="checkbox" name="notificaciones_portal" defaultChecked={Boolean(data.notificaciones_portal)}/> Mostrar avisos en el portal</label><label><input type="checkbox" name="resumen_actividad" defaultChecked={Boolean(data.resumen_actividad)}/> Recibir resumen de actividad</label></fieldset><button className="button button-primary">Guardar perfil</button></form></>}
function Privacy({data}:{data:Row}){const summary=(data.summary||{}) as Row,consents=(data.consentimientos||[]) as Row[],events=(data.eventos_documentales||[]) as Row[];return <><SectionTitle eyebrow="Control y transparencia" title="Privacidad y trazabilidad" description="Revisa qué actividad conserva Documenta para proteger y acreditar tus operaciones."/><div className="people-metrics"><Metric value={summary.solicitudes} label="Solicitudes"/><Metric value={summary.eventos_documentales} label="Eventos documentales"/><Metric value={summary.compartidos_por_mi} label="Compartidos por mí"/><Metric value={summary.sesiones_activas} label="Sesiones activas"/></div><div className="people-two"><section className="people-card"><h2>Consentimientos</h2>{consents.length?consents.map((row,index)=><div className="people-ledger" key={index}><div><strong>{text(row.tipo)} · v{text(row.version)}</strong><small>{text(row.folio)} · {date(row.registrado_en)}</small></div><Status value={row.decision}/></div>):<Empty text="No hay consentimientos registrados."/>}</section><section className="people-card"><h2>Actividad documental</h2>{events.length?events.map((row,index)=><div className="people-ledger" key={index}><div><strong>{label(row.evento)} · {text(row.documento)}</strong><small>{text(row.folio)} · {date(row.creado_en)}</small></div></div>):<Empty text="Aún no hay actividad documental."/>}</section></div></>}
