import { useState } from "preact/hooks";
import { Breadcrumb } from "@/layouts/Breadcrumb";
import { Badge } from "@/components/Badge";
import { FKChip } from "@/components/FKChip";
import { FieldLabel } from "@/components/FieldLabel";
import { resolveBadgeColor } from "@/theme/accents";
import { formatFieldValue, formatNum, resolveFK, isImageUrl } from "@/utils/format";
import type { PageSpec, RecordSpec, DataRow } from "@/types/spec";
import type { TableData } from "@/hooks/useData";

interface DetailViewProps {
  page: PageSpec;
  rec: RecordSpec | undefined;
  record: DataRow;
  allRecords: RecordSpec[];
  allData: TableData;
  tabName: string;
  onBack: () => void;
  onViewDetail: (table: string, id: string) => void;
  onSave: (table: string, id: string, changes: Record<string, unknown>) => void;
  onDelete: (table: string, id: string) => void;
}

export function DetailView({ page, rec, record, allRecords, allData, tabName, onBack, onViewDetail, onSave, onDelete }: DetailViewProps) {
  const [editing, setEditing] = useState(false);
  const [formData, setFormData] = useState<Record<string, unknown>>({});
  const [inlineEdit, setInlineEdit] = useState<string | null>(null);

  const titleF = rec?.display || Object.keys(record).find((k) => k !== "id" && k !== "created_at" && k !== "updated_at" && !k.endsWith("_id"));
  const titleVal = titleF ? String(record[titleF] || "—") : "Detail";

  function startEdit() {
    setFormData({ ...record });
    setEditing(true);
  }

  function saveEdit() {
    const changes: Record<string, unknown> = {};
    for (const [k, v] of Object.entries(formData)) {
      if (k === "id" || k === "created_at" || k === "updated_at") continue;
      if (v !== record[k]) changes[k] = v;
    }
    if (Object.keys(changes).length) onSave(page.record!, String(record.id), changes);
    setEditing(false);
    setFormData({});
  }

  // Hero image
  let heroImage: string | null = null;
  if (rec) {
    for (const [fn, fm] of Object.entries(rec.fields)) {
      if ((fm.type === "image" || isImageUrl(record[fn])) && record[fn]) {
        heroImage = String(record[fn]);
        break;
      }
    }
  }

  // Related records
  const relations: { name: string; table: string; rows: DataRow[]; fields: RecordSpec["fields"] }[] = [];
  for (const otherRec of allRecords) {
    if (otherRec.table === page.record) continue;
    for (const [fname, fmeta] of Object.entries(otherRec.fields)) {
      if (fmeta.link === page.record) {
        const related = (allData[otherRec.table] || []).filter((r) => String(r[fname + "_id"]) === String(record.id));
        if (related.length) relations.push({ name: otherRec.name, table: otherRec.table, rows: related, fields: otherRec.fields });
      }
    }
  }

  return (
    <div>
      <Breadcrumb items={[{ label: tabName, onClick: onBack }, { label: titleVal }]} />

      {/* Header */}
      <div class="flex items-center justify-between mb-5">
        <h2 class="text-xl font-semibold">{titleVal}</h2>
        <div class="flex gap-1.5">
          {editing ? (
            <>
              <button onClick={saveEdit} class="px-3 py-1.5 text-xs rounded-md font-medium text-white" style={{ background: "var(--z-accent)" }}>Save</button>
              <button onClick={() => { setEditing(false); setFormData({}); }} class="px-3 py-1.5 text-xs rounded-md" style={{ color: "var(--z-muted)", border: "1px solid var(--z-border)" }}>Cancel</button>
            </>
          ) : (
            <>
              <button onClick={startEdit} class="px-3 py-1.5 text-xs rounded-md" style={{ background: "var(--z-card-bg)", color: "var(--z-text)", border: "1px solid var(--z-border)" }}>Edit</button>
              <button onClick={() => onDelete(page.record!, String(record.id))} class="px-3 py-1.5 text-xs rounded-md text-red-400/50 hover:text-red-400" style={{ border: "1px solid rgba(239,68,68,0.15)" }}>Delete</button>
            </>
          )}
        </div>
      </div>

      {/* Hero image */}
      {heroImage && (
        <div class="mb-5 rounded-[var(--z-radius-card)] overflow-hidden" style={{ border: "var(--z-card-border)" }}>
          <img src={heroImage} alt="" class="w-full max-h-60 object-cover" />
        </div>
      )}

      {/* Fields */}
      <div class="max-w-[560px]">
        {Object.entries(record)
          .filter(([k]) => k !== "id" && k !== "created_at" && k !== "updated_at" && k !== titleF)
          .filter(([, v]) => editing || (v != null && v !== ""))
          .filter(([k]) => {
            const fm = rec?.fields[k] || rec?.fields[k.replace("_id", "")];
            return !(fm && (fm.type === "image" || isImageUrl(record[k])) && record[k]);
          })
          .map(([key, val]) => {
            const fieldMeta = rec?.fields[key] || rec?.fields[key.replace("_id", "")] || { type: "text" as const };

            // FK chip
            const fkRef = !editing ? resolveFK(key, val, rec, allRecords, allData) : null;
            if (fkRef) {
              return (
                <div key={key} class="flex items-center justify-between" style={{ borderBottom: "1px solid var(--z-border)", padding: "var(--z-density-padding)" }}>
                  <FieldLabel field={key} />
                  <FKChip name={fkRef.name} onClick={() => onViewDetail(fkRef.table, fkRef.id)} />
                </div>
              );
            }

            if (editing) {
              const editVal = formData[key] !== undefined ? formData[key] : val;
              return (
                <div key={key} class="flex items-center justify-between" style={{ borderBottom: "1px solid var(--z-border)", padding: "var(--z-density-padding)" }}>
                  <FieldLabel field={key} />
                  <EditInput field={key} value={editVal} fieldMeta={fieldMeta} rec={rec} allRecords={allRecords} allData={allData} onChange={(v: unknown) => setFormData({ ...formData, [key]: v })} />
                </div>
              );
            }

            // Display mode
            const formatted = formatFieldValue(key, val, fieldMeta);
            const displayVal = formatted ?? (val != null ? (typeof val === "number" ? formatNum(val) : String(val)) : "—");
            const isChoice = fieldMeta.type === "choice" && fieldMeta.choices && val;

            return (
              <div
                key={key}
                class="flex items-center justify-between rounded-md transition-colors cursor-pointer"
                style={{ borderBottom: "1px solid var(--z-border)", padding: "var(--z-density-padding)" }}
                onClick={() => setInlineEdit(inlineEdit === key ? null : key)}
                onMouseOver={(e) => { (e.currentTarget as HTMLElement).style.background = "var(--z-card-bg)"; }}
                onMouseOut={(e) => { (e.currentTarget as HTMLElement).style.background = "transparent"; }}
              >
                <FieldLabel field={key} />
                {inlineEdit === key ? (
                  <InlineEditInput table={page.record!} id={String(record.id)} field={key} value={val} fieldMeta={fieldMeta} onSave={(v: unknown) => { onSave(page.record!, String(record.id), { [key]: v }); setInlineEdit(null); }} onCancel={() => setInlineEdit(null)} />
                ) : isChoice ? (
                  <Badge text={String(val)} color={resolveBadgeColor(String(val), fieldMeta.choices, fieldMeta.colors)} />
                ) : (
                  <span class="text-[var(--z-font-md)]" dangerouslySetInnerHTML={{ __html: displayVal }} />
                )}
              </div>
            );
          })}
      </div>

      {/* Related records */}
      {relations.length > 0 && (
        <div class="mt-8 pt-4" style={{ borderTop: "1px solid var(--z-border)" }}>
          {relations.map((rel) => (
            <div key={rel.table}>
              <div class="font-mono text-[var(--z-font-sm)] uppercase tracking-wider mt-4 mb-2" style={{ color: "var(--z-muted)" }}>
                {rel.name} <span style={{ opacity: 0.5 }}>({rel.rows.length})</span>
              </div>
              <div class="space-y-1">
                {rel.rows.map((row) => {
                  const rtf = Object.keys(rel.fields).find((f) => f !== "id" && !f.endsWith("_id") && (rel.fields[f].type === "text")) || Object.keys(rel.fields).find((f) => f !== "id" && !f.endsWith("_id")) || "id";
                  const rbf = Object.keys(rel.fields).find((f) => rel.fields[f].type === "choice");
                  return (
                    <div
                      key={String(row.id)}
                      class="flex items-center justify-between rounded-[var(--z-radius-card)] cursor-pointer transition-all"
                      style={{ border: "var(--z-card-border)", boxShadow: "var(--z-card-shadow)", padding: "var(--z-density-padding)" }}
                      onClick={() => onViewDetail(rel.table, String(row.id))}
                      onMouseOver={(e) => { (e.currentTarget as HTMLElement).style.borderColor = "var(--z-border-hover)"; }}
                      onMouseOut={(e) => { (e.currentTarget as HTMLElement).style.borderColor = "var(--z-border)"; }}
                    >
                      <span class="text-[var(--z-font-md)]">{String(row[rtf] || "—")}</span>
                      <div class="flex items-center gap-2">
                        {rbf && row[rbf] && <Badge text={String(row[rbf])} color={resolveBadgeColor(String(row[rbf]), rel.fields[rbf].choices, rel.fields[rbf].colors)} />}
                        <span class="text-[var(--z-font-xs)] opacity-30" style={{ color: "var(--z-muted)" }}>→</span>
                      </div>
                    </div>
                  );
                })}
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

function EditInput({ field, value, fieldMeta, rec, allRecords, allData, onChange }: any) {
  const inputStyle = "flex-1 rounded-md px-2 py-1 text-[var(--z-font-md)] outline-none text-right";
  const style = { background: "var(--z-card-bg)", border: "1px solid var(--z-border)", color: "var(--z-text)" };

  if (fieldMeta.type === "choice" && fieldMeta.choices) {
    return <select value={String(value || "")} onChange={(e) => onChange((e.target as HTMLSelectElement).value)} class={inputStyle} style={style}>
      {fieldMeta.choices.map((c: string) => <option key={c} value={c}>{c}</option>)}
    </select>;
  }
  if (field.endsWith("_id") && fieldMeta.link) {
    const linkedRec = allRecords.find((r: RecordSpec) => r.table === fieldMeta.link);
    const options = allData[fieldMeta.link] || [];
    return <select value={String(value || "")} onChange={(e) => onChange((e.target as HTMLSelectElement).value)} class={inputStyle} style={style}>
      <option value="">Select...</option>
      {options.map((o: DataRow) => <option key={String(o.id)} value={String(o.id)}>{String(o[linkedRec?.display || "id"] || o.id)}</option>)}
    </select>;
  }
  if (fieldMeta.type === "number" || typeof value === "number") {
    return <input type="number" step="any" value={String(value || "")} onChange={(e) => onChange(parseFloat((e.target as HTMLInputElement).value))} class={inputStyle} style={style} />;
  }
  return <input type="text" value={String(value || "")} onChange={(e) => onChange((e.target as HTMLInputElement).value)} class={inputStyle} style={style} />;
}

function InlineEditInput({ table, id, field, value, fieldMeta, onSave, onCancel }: any) {
  const [v, setV] = useState(value);
  const style = { background: "var(--z-card-bg)", border: "1px solid var(--z-accent-border)", color: "var(--z-text)" };

  if (fieldMeta.type === "choice" && fieldMeta.choices) {
    return <select value={String(v || "")} onChange={(e) => { onSave((e.target as HTMLSelectElement).value); }} onBlur={onCancel} autoFocus class="rounded-md px-2 py-1 text-[var(--z-font-md)] outline-none" style={style}>
      {fieldMeta.choices.map((c: string) => <option key={c} value={c}>{c}</option>)}
    </select>;
  }
  return <input type={fieldMeta.type === "number" ? "number" : "text"} value={String(v || "")} onInput={(e) => setV((e.target as HTMLInputElement).value)}
    onKeyDown={(e) => { if (e.key === "Enter") onSave(fieldMeta.type === "number" ? parseFloat(v) : v); if (e.key === "Escape") onCancel(); }}
    onBlur={onCancel} autoFocus class="rounded-md px-2 py-1 text-[var(--z-font-md)] outline-none text-right w-36" style={style} />;
}
