"use client";
import { useState } from "react";
import { useStore, findPatient, pushFeed, uid } from "@/lib/store";
import { acceptBudget, budgetSplit, fdate, includedLeft, membershipDiscount, mxn, patientBalance, recordProcedure } from "@/lib/logic";
import type { ClinicalHistory, Patient, ToothState } from "@/lib/types";
import { Odontogram, TOOTH_STATES } from "../Odontogram";
import { SignaturePad } from "../SignaturePad";
import { Kpi, Note, Pill, useUI, WaBubble } from "../ui";
import { BudgetForm, ChargeForm, ClaimModal, ReferralForm, RxForm } from "../modals";
import { PrescriptionDoc, ReceiptDoc } from "../docs";

type P = { p: Patient };
const usePatientMutate = (id: string) => {
  const { mutate } = useStore();
  return (fn: (p: Patient, d: Parameters<Parameters<typeof mutate>[0]>[0]) => void) =>
    mutate((d) => fn(d.patients.find((x) => x.id === id)!, d));
};

/* ---------- Historia clínica (NOM-004) ---------- */
export function HistoryTab({ p }: P) {
  const upd = usePatientMutate(p.id);
  const { toast } = useUI();
  const [h, setH] = useState<ClinicalHistory>(p.hist);
  const [id, setId] = useState({ name: p.name, age: p.age, tel: p.tel, email: p.email });
  const ck = (k: keyof ClinicalHistory, l: string) => (
    <label className="chk"><input type="checkbox" checked={!!h[k]} onChange={(e) => setH({ ...h, [k]: e.target.checked })} /> {l}</label>
  );
  const tx = (k: keyof ClinicalHistory, l: string, big = false) => (
    <label className="f">{l}{big
      ? <textarea value={String(h[k] ?? "")} onChange={(e) => setH({ ...h, [k]: e.target.value })} />
      : <input value={String(h[k] ?? "")} onChange={(e) => setH({ ...h, [k]: e.target.value })} />}</label>
  );
  return (
    <form style={{ display: "flex", flexDirection: "column", gap: 14 }} onSubmit={(e) => { e.preventDefault(); upd((x) => { x.hist = h; Object.assign(x, id); }); toast("Historia clínica guardada"); }}>
      <Note>Campos basados en la NOM-004-SSA3-2012 (expediente clínico). Validar con asesoría legal antes de operar.</Note>
      <h3>Ficha de identificación</h3>
      <div className="fgrid">
        <label className="f">Nombre<input value={id.name} onChange={(e) => setId({ ...id, name: e.target.value })} /></label>
        <label className="f">Edad<input type="number" value={id.age} onChange={(e) => setId({ ...id, age: +e.target.value })} /></label>
        <label className="f">Teléfono (WhatsApp)<input value={id.tel} onChange={(e) => setId({ ...id, tel: e.target.value })} /></label>
        <label className="f">Correo<input value={id.email} onChange={(e) => setId({ ...id, email: e.target.value })} /></label>
      </div>
      <h3>Motivo de consulta</h3>{tx("motivo", "Motivo", true)}
      <h3>Antecedentes patológicos</h3>
      <div className="row" style={{ gap: 16 }}>{ck("diabetes", "Diabetes")}{ck("hiper", "Hipertensión")}{ck("cardio", "Cardiopatía")}{ck("coag", "Trastorno de coagulación")}{ck("embarazo", "Embarazo")}</div>
      <div className="fgrid">{tx("alergias", "Alergias")}{tx("medact", "Medicamentos actuales")}{tx("ta", "Tensión arterial")}{tx("fc", "Frecuencia cardiaca")}</div>
      <h3>Exploración y diagnóstico</h3>
      <div className="fgrid">{tx("explor", "Exploración bucal", true)}{tx("dx", "Diagnóstico", true)}</div>
      <h3>Consentimiento informado</h3>
      {ck("consent", "El paciente leyó y aceptó el consentimiento y el aviso de privacidad")}
      <SignaturePad value={h.signature} onChange={(sig) => setH({ ...h, signature: sig })} />
      <div className="row"><button className="btn pri" type="submit">Guardar historia clínica</button></div>
    </form>
  );
}

/* ---------- Odontograma ---------- */
export function OdontogramTab({ p }: P) {
  const { s, mutate } = useStore();
  const { toast } = useUI();
  const [t, setT] = useState<string | null>(null);
  const [svc, setSvc] = useState(s.services[0].name);
  const st: ToothState = t ? p.teeth[t] ?? "sano" : "sano";
  const service = s.services.find((x) => x.name === svc)!;
  const setState = (k: ToothState) => mutate((d) => { const x = d.patients.find((y) => y.id === p.id)!; if (k === "sano") delete x.teeth[t!]; else x.teeth[t!] = k; });
  return (
    <>
      <div className="spread"><h3>Odontograma (numeración FDI)</h3><span className="muted" style={{ fontSize: ".85rem" }}>Toca una pieza para registrar su estado</span></div>
      <Odontogram teeth={p.teeth} selected={t} onSelect={setT} />
      {t && (
        <div className="panel" style={{ background: "var(--sunk)" }}>
          <div className="spread"><h3>Pieza <span className="mono">{t}</span></h3><Pill tone="info">{TOOTH_STATES[st][0]}</Pill></div>
          <div className="row" style={{ marginTop: 10 }}>
            {(Object.keys(TOOTH_STATES) as ToothState[]).map((k) => <button key={k} className={`btn sm${k === st ? " pri" : ""}`} onClick={() => setState(k)}>{TOOTH_STATES[k][0]}</button>)}
          </div>
          <div className="fgrid" style={{ marginTop: 12 }}>
            <label className="f">Tratamiento<select value={svc} onChange={(e) => setSvc(e.target.value)}>{s.services.map((c) => <option key={c.id}>{c.name}</option>)}</select></label>
          </div>
          {includedLeft(p, svc, s.membershipPlans, s.today) > 0 && <p className="muted" style={{ margin: "8px 0 0", fontSize: ".85rem" }}>Incluido en su membresía: le quedan {includedLeft(p, svc, s.membershipPlans, s.today)}.</p>}
          <div className="row" style={{ marginTop: 10 }}>
            <button className="btn" onClick={() => { const inc = includedLeft(p, svc, s.membershipPlans, s.today) > 0; mutate((d) => { const i = d.patients.findIndex((y) => y.id === p.id); d.patients[i] = recordProcedure(d.patients[i], t, service, d.membershipPlans, d.today, d.doctorId); }); toast(inc ? "Registrado como incluido en la membresía" : `Registrado: ${svc} en pieza ${t}`); }}>Marcar como realizado hoy</button>
            <button className="btn" onClick={() => { mutate((d) => { d.patients.find((y) => y.id === p.id)!.next.push({ tooth: t, name: svc }); }); toast("Agregado a la próxima cita"); }}>Programar para próxima cita</button>
            <button className="btn" onClick={() => { mutate((d) => { const x = d.patients.find((y) => y.id === p.id)!; let b = x.budgets.find((y) => y.status === "pendiente"); if (!b) { b = { id: uid(), date: d.today, status: "pendiente", items: [] }; x.budgets.push(b); } b.items.push({ tooth: t, name: svc, price: service.price }); }); toast("Agregado al presupuesto pendiente"); }}>Agregar a presupuesto</button>
          </div>
        </div>
      )}
    </>
  );
}

/* ---------- Tratamientos realizados y próxima cita ---------- */
export function ProceduresTab({ p }: P) {
  const { s, mutate } = useStore();
  const { toast } = useUI();
  const [sel, setSel] = useState(s.services[0].name);
  const price = (n: string) => s.services.find((c) => c.name === n)?.price ?? 0;
  return (
    <>
      <h3>Piezas atendidas</h3>
      <div className="tscroll"><table>
        <thead><tr><th>Fecha</th><th>Pieza</th><th>Tratamiento</th><th>Doctor</th><th className="n">Importe</th></tr></thead>
        <tbody>{p.procs.length ? [...p.procs].reverse().map((x, i) => (
          <tr key={i}><td>{fdate(x.date)}</td><td className="mono">{x.tooth || "—"}</td><td>{x.name}</td><td style={{ fontSize: ".85rem" }}>{s.doctors.find((d) => d.id === x.doctorId)?.name ?? "—"}</td>
            <td className="n">{x.includedByMembership ? <Pill tone="ok">Membresía</Pill> : mxn(x.price)}</td></tr>
        )) : <tr><td colSpan={5} className="muted">Aún no hay tratamientos. Regístralos desde el odontograma.</td></tr>}</tbody>
      </table></div>
      <h3>Servicios para la próxima cita</h3>
      <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
        {p.next.length ? p.next.map((x, i) => (
          <div key={i} className="spread" style={{ padding: "8px 10px", background: "var(--sunk)", borderRadius: 8 }}>
            <span>{x.tooth && <><span className="mono">{x.tooth}</span> · </>}{x.name}</span>
            <span className="row"><span className="mono muted">{mxn(price(x.name))}</span>
              <button className="btn sm" onClick={() => mutate((d) => { d.patients.find((y) => y.id === p.id)!.next.splice(i, 1); })}>Quitar</button></span>
          </div>
        )) : <span className="muted">Nada programado.</span>}
      </div>
      <div className="row">
        <select value={sel} onChange={(e) => setSel(e.target.value)} style={{ maxWidth: 320 }} aria-label="Servicio">{s.services.map((c) => <option key={c.id}>{c.name}</option>)}</select>
        <button className="btn" onClick={() => mutate((d) => { d.patients.find((y) => y.id === p.id)!.next.push({ tooth: "", name: sel }); })}>Agregar</button>
        {p.next.length > 0 && <button className="btn pri" onClick={() => { mutate((d) => { d.patients.find((y) => y.id === p.id)!.budgets.push({ id: uid(), date: d.today, status: "pendiente", items: p.next.map((x) => ({ ...x, price: price(x.name) })) }); }); toast("Presupuesto creado"); }}>Convertir en presupuesto</button>}
      </div>
    </>
  );
}

/* ---------- Recetas ---------- */
export function RxTab({ p }: P) {
  const { s } = useStore();
  const { open } = useUI();
  return (
    <>
      <div className="spread"><h3>Recetas</h3><button className="btn pri" onClick={() => open(<RxForm patientId={p.id} />)}>Nueva receta</button></div>
      {p.rx.length ? [...p.rx].reverse().map((r) => (
        <div key={r.id} className="spread" style={{ padding: 10, background: "var(--sunk)", borderRadius: 8 }}>
          <div><b>{fdate(r.date)}</b> · <small className="muted">{s.doctors.find((d) => d.id === r.doctorId)?.name}</small>
            <div className="muted" style={{ fontSize: ".88rem" }}>{r.meds.map((m) => m.name).join(" · ")}</div></div>
          <button className="btn sm" onClick={() => open(<PrescriptionDoc patientId={p.id} rxId={r.id} />)}>Ver receta</button>
        </div>
      )) : <span className="muted">Sin recetas.</span>}
    </>
  );
}

/* ---------- Radiografías y estudios ---------- */
export function StudiesTab({ p }: P) {
  const upd = usePatientMutate(p.id);
  const { open, toast } = useUI();
  return (
    <>
      <div className="spread"><h3>Radiografías y estudios</h3>
        <span className="row">
          <button className="btn" onClick={() => open(<ReferralForm patientId={p.id} />)}>Referir a estudio</button>
          <label className="btn pri" style={{ cursor: "pointer" }}>Subir imagen
            <input type="file" accept="image/*" hidden onChange={(e) => {
              const f = e.target.files?.[0]; if (!f) return;
              const r = new FileReader();
              r.onload = () => { upd((x, d) => x.studies.push({ id: uid(), date: d.today, label: f.name.replace(/\.[^.]+$/, ""), img: String(r.result) })); toast("Imagen agregada al expediente"); };
              r.readAsDataURL(f);
            }} />
          </label>
        </span>
      </div>
      <div className="xr">
        {p.studies.length ? p.studies.map((x) => (
          <figure key={x.id}>
            {x.img ? <img src={x.img} alt={x.label} /> : <div style={{ aspectRatio: "4/3", background: "radial-gradient(circle at 50% 45%, #6a7a80, #0b0f10 70%)" }} aria-label="Estudio sin imagen todavía" />}
            <figcaption>{x.label}<br /><span className="mono">{x.date}</span></figcaption>
          </figure>
        )) : <span className="muted">Sin estudios. Sube una periapical, panorámica o foto intraoral.</span>}
      </div>
      <Note>En producción las imágenes se guardan en almacenamiento privado por clínica (no en la base de datos) y se abren con enlaces temporales.</Note>
    </>
  );
}

/* ---------- Presupuestos ---------- */
export function BudgetsTab({ p }: P) {
  const { s, mutate, ctx } = useStore();
  const { open, toast } = useUI();
  const ins = ctx.insurersOn && p.ins ? s.insurers.find((i) => i.id === p.ins!.insurerId) : null;
  const total3 = s.membershipPlans.reduce((a, m) => (m.disc > a.disc ? m : a), s.membershipPlans[0]);
  return (
    <>
      <div className="spread"><h3>Presupuestos</h3><button className="btn pri" onClick={() => open(<BudgetForm patientId={p.id} />)}>Nuevo presupuesto</button></div>
      {p.budgets.length ? [...p.budgets].reverse().map((b) => {
        const sp = budgetSplit(p, b, ctx);
        const hasClaim = s.claims.some((c) => c.budgetId === b.id);
        const row = (l: string, v: string, color?: string) => <tr><td /><td>{l}</td><td className="n" style={color ? { color } : undefined}>{v}</td></tr>;
        return (
          <div key={b.id} className="panel" style={{ background: "var(--sunk)" }}>
            <div className="spread"><b>Presupuesto {fdate(b.date)}</b><Pill tone={b.status === "aceptado" ? "ok" : b.status === "rechazado" ? "bad" : "warn"}>{b.status}</Pill></div>
            <div className="tscroll"><table style={{ marginTop: 8 }}><tbody>
              {b.items.map((i, k) => <tr key={k}><td className="mono" style={{ width: 44 }}>{i.tooth || "—"}</td><td>{i.name}</td><td className="n">{mxn(i.price)}</td></tr>)}
              {(sp.tabAdj || sp.memOff || sp.insPay) ? row("Subtotal a precio particular", mxn(sp.gross)) : null}
              {sp.tabAdj ? row(`Ajuste a tabulador ${sp.insurer!.name}`, "−" + mxn(sp.tabAdj)) : null}
              {sp.memOff ? row(`Descuento de membresía (${sp.disc}%)`, "−" + mxn(sp.memOff), "var(--ok)") : null}
              {sp.insPay ? row(`Paga ${sp.insurer!.name} (coaseguro del paciente ${sp.insurer!.coaseg}%)`, "−" + mxn(sp.insPay), "var(--info)") : null}
              <tr><td /><td><b>{sp.insPay ? "Paga el paciente" : "Total"}</b></td><td className="n"><b>{mxn(sp.patPay)}</b></td></tr>
              {sp.needsPreauth && <tr><td /><td colSpan={2}><Pill tone="warn">Requiere pre-autorización (más de {mxn(sp.insurer!.preauth)})</Pill></td></tr>}
            </tbody></table></div>
            {!p.mem && b.status === "pendiente" && sp.gross > 2000 && <Note style={{ marginTop: 8 }}>Con {total3.name} ({mxn(total3.price)}/mes) este paciente ahorraría {mxn((sp.gross * total3.disc) / 100)} en este presupuesto.</Note>}
            <div className="row" style={{ marginTop: 8 }}>
              {b.status === "pendiente" && <>
                <button className="btn sm pri" onClick={() => { mutate((d) => { const i = d.patients.findIndex((x) => x.id === p.id); d.patients[i] = acceptBudget(d.patients[i], b.id, d.membershipPlans, d.today); pushFeed(d, `${p.name} aprobó su presupuesto`, "ok"); }); toast("Presupuesto aprobado; los tratamientos pasan al plan"); }}>Paciente acepta</button>
                <button className="btn sm" onClick={() => mutate((d) => { d.patients.find((x) => x.id === p.id)!.budgets.find((y) => y.id === b.id)!.status = "rechazado"; })}>Rechaza</button>
              </>}
              <button className="btn sm" onClick={() => open(<><h2>Enviar presupuesto</h2><WaBubble text={`Hola ${p.name.split(" ")[0]}, te compartimos tu presupuesto de ${s.clinic.name}:\n${b.items.map((i) => `• ${i.name}${i.tooth ? ` (${i.tooth})` : ""}`).join("\n")}\nA tu cargo: ${mxn(sp.patPay)}${membershipDiscount(p, s.membershipPlans, s.today) ? " (con tu descuento de membresía)" : ""}\n\nResponde APROBAR para continuar.`} /><button className="btn pri" onClick={() => { open(null); toast("Enviado por WhatsApp (simulado)"); }}>Enviar</button></>)}>Enviar por WhatsApp</button>
              {ins && b.status !== "rechazado" && !hasClaim && (
                <button className="btn sm" onClick={() => {
                  const id = uid();
                  mutate((d) => { d.claims.push({ id, patientId: p.id, insurerId: ins.id, budgetId: b.id, date: d.today, step: 0, docs: ins.reqs.map((r) => (/odontograma/i.test(r) && Object.keys(p.teeth).length > 0) || (/p[oó]liza/i.test(r) && !!p.ins?.policy)) }); });
                  setTimeout(() => open(<ClaimModal id={id} />), 0);
                }}>Crear trámite con {ins.name}</button>
              )}
            </div>
          </div>
        );
      }) : <span className="muted">Sin presupuestos. Arma uno desde el odontograma o desde “Servicios para la próxima cita”.</span>}
    </>
  );
}

/* ---------- Cobros ---------- */
export function PaymentsTab({ p }: P) {
  const { ctx } = useStore();
  const { open } = useUI();
  const b = patientBalance(p, ctx);
  return (
    <>
      <div className="grid g3">
        <Kpi panel={false} value={mxn(b.accepted)} label="Tratamiento aceptado (su parte)" />
        <Kpi panel={false} value={mxn(b.paid)} label="Pagado" />
        <Kpi panel={false} value={mxn(b.due)} label="Saldo pendiente" color={b.due ? "var(--warn)" : "var(--ok)"} />
      </div>
      <div className="row"><button className="btn pri" onClick={() => open(<ChargeForm patientId={p.id} />)}>Registrar cobro</button></div>
      <div className="tscroll"><table>
        <thead><tr><th>Folio</th><th>Fecha</th><th>Concepto</th><th>Forma</th><th className="n">Monto</th><th /></tr></thead>
        <tbody>{p.pays.length ? [...p.pays].reverse().map((x) => (
          <tr key={x.folio}><td className="mono">{x.folio}</td><td>{fdate(x.date)}</td><td>{x.concept}{x.membership && <> <Pill tone="info">Membresía</Pill></>}</td><td>{x.method}</td><td className="n">{mxn(x.amount)}</td>
            <td><button className="btn sm" onClick={() => open(<ReceiptDoc folio={x.folio} />)}>Recibo</button></td></tr>
        )) : <tr><td colSpan={6} className="muted">Sin pagos.</td></tr>}</tbody>
      </table></div>
    </>
  );
}

/* ---------- Seguro ---------- */
export function InsuranceTab({ p }: P) {
  const { s, mutate } = useStore();
  const { open, toast } = useUI();
  const [f, setF] = useState({ insurerId: p.ins?.insurerId ?? "", policy: p.ins?.policy ?? "", holder: p.ins?.holder ?? p.name });
  const ins = s.insurers.find((i) => i.id === f.insurerId);
  const claims = s.claims.filter((c) => c.patientId === p.id);
  return (
    <>
      <h3>Seguro del paciente</h3>
      <div className="fgrid">
        <label className="f">Aseguradora<select value={f.insurerId} onChange={(e) => setF({ ...f, insurerId: e.target.value })}><option value="">Sin seguro (particular)</option>{s.insurers.map((i) => <option key={i.id} value={i.id}>{i.name}</option>)}</select></label>
        <label className="f">Número de póliza<input value={f.policy} onChange={(e) => setF({ ...f, policy: e.target.value })} /></label>
        <label className="f">Titular<input value={f.holder} onChange={(e) => setF({ ...f, holder: e.target.value })} /></label>
      </div>
      <div className="row"><button className="btn pri" onClick={() => { mutate((d) => { d.patients.find((x) => x.id === p.id)!.ins = f.insurerId ? { ...f } : null; }); toast("Seguro actualizado"); }}>Guardar</button></div>
      {ins && <Note>{ins.name}: coaseguro del paciente {ins.coaseg}%{ins.preauth ? `, pre-autorización arriba de ${mxn(ins.preauth)}` : ""}, paga al consultorio en {ins.payDays} días.</Note>}
      <h3>Trámites</h3>
      {claims.length ? claims.map((c) => (
        <div key={c.id} className="spread" style={{ padding: "8px 10px", background: "var(--sunk)", borderRadius: 8 }}>
          <span>{s.insurers.find((i) => i.id === c.insurerId)?.name} · {fdate(c.date)}</span>
          <button className="btn sm" onClick={() => open(<ClaimModal id={c.id} />)}>Abrir</button>
        </div>
      )) : <span className="muted">Sin trámites. Se crean desde un presupuesto.</span>}
    </>
  );
}

export { findPatient };
