"use client";

import { useState } from "react";
import { ActionForm } from "@/components/action-form";
import { Badge } from "@/components/ui";
import { formatDateTime } from "@/lib/format";
import { PROPOSAL_TYPES, displayFieldValue, proposalType, type ProposalField, type ProposalTypeKey } from "@/lib/proposal-types";
import type { ChainOptions, ProposalApproverRow, ProposalRow } from "@/lib/proposals";
import { AuditEntryRow } from "@/components/entity-history";
import type { AuditEntry } from "@/lib/audit-view";
import { createProposalAction, decideProposalAction, deleteProposalAction, updateProposalAction, withdrawProposalAction } from "./actions";

type Course = { id: string; name: string };
type CustomerOption = { id: string; label: string };

/** `initial` = giá trị đã lưu khi Ban giám đốc sửa phiếu (trường chọn khoá/khách nhận thêm mã đã lưu). */
type Initial = { text?: string; id?: string };

function FieldInput({ field, courses, customers, initial, idPrefix = "f" }: { field: ProposalField; courses: Course[]; customers: CustomerOption[]; initial?: Initial; idPrefix?: string }) {
  const name = `d_${field.key}`;
  const id = `${idPrefix}-${field.key}`;
  const initialText = initial?.text ?? "";
  // Phiếu cũ có thể chỉ lưu TÊN khoá (không lưu mã): khi sửa, tìm lại khoá theo tên; không thấy thì cho chọn "Giữ nguyên" — tuyệt đối không tự đổi sang khoá khác.
  const NEW_COURSE_TEXT = "Khoá mới (mô tả trong nội dung)";
  const matchedCourse = initial?.id ?? courses.find((c) => c.name === initialText)?.id;
  const keepCourse = !!initial && !!initialText && !matchedCourse && initialText !== NEW_COURSE_TEXT;
  const courseDefault = !initial ? "" : (matchedCourse ?? (initialText === NEW_COURSE_TEXT ? "NEW" : keepCourse ? "KEEP" : ""));
  const label = (
    <label htmlFor={id} className="label-caps mb-1.5 block">
      {field.label} {field.required && <span className="text-red-600">*</span>}
    </label>
  );
  switch (field.kind) {
    case "textarea":
      return (
        <div className="lg:col-span-2">
          {label}
          <textarea id={id} name={name} rows={2} required={field.required} placeholder={field.placeholder} defaultValue={initialText} className="input" />
        </div>
      );
    case "date":
      return (
        <div>
          {label}
          <input id={id} name={name} type="date" required={field.required} defaultValue={initialText} className="input" />
        </div>
      );
    case "number":
    case "money":
      return (
        <div>
          {label}
          <input id={id} name={name} type="number" min={0} step={1} required={field.required} placeholder={field.kind === "money" ? "0" : undefined} defaultValue={initialText} className="input tnum" />
        </div>
      );
    case "course":
      return (
        <div className="lg:col-span-2">
          {label}
          <select id={id} name={name} required={field.required} defaultValue={courseDefault} className="input">
            <option value="" disabled>
              — Chọn khoá chuyển giao —
            </option>
            {courses.map((c) => (
              <option key={c.id} value={c.id}>
                {c.name}
              </option>
            ))}
            <option value="NEW">Khoá mới (mô tả trong nội dung)</option>
            {keepCourse && <option value="KEEP">Giữ nguyên: {initialText}</option>}
          </select>
        </div>
      );
    case "customer":
      return (
        <div className="lg:col-span-2">
          {label}
          <select id={id} name={name} required={field.required} defaultValue={initial?.id ?? (initialText ? "KEEP" : "")} className="input">
            <option value="">— Không chọn / tặng chung —</option>
            {customers.map((c) => (
              <option key={c.id} value={c.id}>
                {c.label}
              </option>
            ))}
            {initialText && !initial?.id && <option value="KEEP">Giữ nguyên: {initialText}</option>}
          </select>
        </div>
      );
    default:
      return (
        <div className={field.key === "target" || field.key === "audience" ? "lg:col-span-2" : undefined}>
          {label}
          <input id={id} name={name} required={field.required} placeholder={field.placeholder} defaultValue={initialText} className="input" />
        </div>
      );
  }
}

export function ProposalForm({ options, courses, customers }: { options: ChainOptions; courses: Course[]; customers: CustomerOption[] }) {
  const [type, setType] = useState<ProposalTypeKey | "">("");
  const [formKey, setFormKey] = useState(0);
  const config = proposalType(type);

  return (
    <ActionForm
      key={formKey}
      action={async (formData) => {
        const result = await createProposalAction(formData);
        // Gửi xong: dựng lại form trống (kể cả loại phiếu) để khỏi bấm gửi trùng.
        if (result.ok) {
          setType("");
          setFormKey((k) => k + 1);
        }
        return result;
      }}
      success="Đã gửi đề xuất."
      className="card flex flex-col gap-4 p-4"
    >
      <div className="grid gap-4 lg:grid-cols-2">
        <div>
          <label htmlFor="type" className="label-caps mb-1.5 block">
            Loại phiếu <span className="text-red-600">*</span>
          </label>
          <select id="type" name="type" required value={type} onChange={(event) => setType(event.target.value as ProposalTypeKey)} className="input">
            <option value="" disabled>
              — Chọn loại phiếu —
            </option>
            {PROPOSAL_TYPES.map((t) => (
              <option key={t.key} value={t.key}>
                {t.label}
              </option>
            ))}
          </select>
          {config && <p className="mt-1 text-[11px] text-ink-400">{config.hint}</p>}
        </div>
        <div>
          <label htmlFor="title" className="label-caps mb-1.5 block">
            Tiêu đề <span className="text-red-600">*</span>
          </label>
          <input id="title" name="title" required className="input" placeholder="Ví dụ: Mở lớp Filler nâng cao cho khách miền Nam tháng 10" />
        </div>
      </div>

      {config && config.fields.length > 0 && (
        <div className="grid gap-4 rounded-lg bg-ink-50 p-3 lg:grid-cols-2">
          {config.fields.map((field) => (
            <FieldInput key={`${type}-${field.key}`} field={field} courses={courses} customers={customers} />
          ))}
        </div>
      )}

      <div>
        <label htmlFor="content" className="label-caps mb-1.5 block">
          Nội dung / lý do đề xuất <span className="text-red-600">*</span>
        </label>
        <textarea id="content" name="content" required rows={3} className="input" placeholder="Trình bày lý do, hiệu quả kỳ vọng, số liệu liên quan…" />
      </div>

      {/* Chuỗi duyệt: Người đề xuất → Trưởng bộ phận → Trưởng bộ phận liên quan → TGĐ */}
      <div>
        <div className="label-caps mb-1.5">Chuỗi duyệt (lần lượt)</div>
        <ol className="flex flex-col gap-3 rounded-lg border border-[var(--color-line)] p-3 text-sm">
          <li className="flex flex-wrap items-center gap-2">
            <Badge tone="green">Bước 0</Badge>
            <span className="text-ink-700">Người đề xuất — chính bạn</span>
          </li>
          <li className="flex flex-wrap items-center gap-2">
            <Badge tone="brand">Bước 1</Badge>
            <span className="text-ink-700">Trưởng bộ phận:</span>
            {options.head ? (
              <b className="text-ink-700">
                {options.head.name} <span className="font-normal text-ink-400">({options.head.departmentName})</span>
              </b>
            ) : (
              <span className="text-ink-400">chưa xác định (bạn là trưởng bộ phận hoặc bộ phận chưa có trưởng) — bỏ qua bước này</span>
            )}
          </li>
          <li>
            <div className="mb-1.5 flex flex-wrap items-center gap-2">
              <Badge tone="brand">Bước 2</Badge>
              <span className="text-ink-700">Trưởng bộ phận liên quan (tuỳ nội dung — chọn các bộ phận, duyệt song song):</span>
            </div>
            {options.departments.length === 0 ? (
              <p className="text-xs text-ink-400">Chưa có bộ phận nào được đặt trưởng bộ phận (Danh mục → Phòng ban).</p>
            ) : (
              <div className="flex flex-wrap gap-x-4 gap-y-1.5">
                {options.departments.map((d) => (
                  <label key={d.id} className="flex items-center gap-2 text-sm text-ink-600">
                    <input type="checkbox" name="relatedDept" value={d.id} className="h-4 w-4 accent-brand-500" />
                    {d.name} <span className="text-[11px] text-ink-400">— {d.headName}</span>
                  </label>
                ))}
              </div>
            )}
          </li>
          {options.colleagues.length > 0 && (
            <li>
              <details>
                <summary className="cursor-pointer text-xs font-semibold text-brand-600">Gắn thêm người duyệt khác (tuỳ chọn, duyệt trước TGĐ)</summary>
                <div className="mt-2 flex flex-wrap gap-x-4 gap-y-1.5">
                  {options.colleagues.map((c) => (
                    <label key={c.id} className="flex items-center gap-2 text-sm text-ink-600">
                      <input type="checkbox" name="extraApprover" value={c.id} className="h-4 w-4 accent-brand-500" />
                      {c.name}
                    </label>
                  ))}
                </div>
              </details>
            </li>
          )}
          <li className="flex flex-wrap items-center gap-2">
            <Badge tone="brand">Bước cuối</Badge>
            <span className="text-ink-700">TGĐ:</span>
            {options.directors.length === 0 ? (
              <span className="text-ink-400">không có (bạn là TGĐ) — bỏ qua</span>
            ) : (
              <select name="directorId" required defaultValue={options.directors[0].id} className="input w-auto" aria-label="TGĐ duyệt">
                {options.directors.map((d) => (
                  <option key={d.id} value={d.id}>
                    {d.name}
                  </option>
                ))}
              </select>
            )}
          </li>
        </ol>
        <p className="mt-1 text-[11px] text-ink-400">Mỗi người chỉ duyệt khi các bước trước đã duyệt xong. Một người từ chối là cả phiếu bị từ chối. Thu hồi được khi chưa ai duyệt.</p>
      </div>

      <div>
        <button type="submit" className="btn-primary">
          Gửi đề xuất
        </button>
      </div>
    </ActionForm>
  );
}

const STATUS_LABEL = { PENDING: "Chờ duyệt", APPROVED: "Đã duyệt", REJECTED: "Từ chối" } as const;
const STATUS_TONE = { PENDING: "gold", APPROVED: "green", REJECTED: "red" } as const;

/** Nhóm người duyệt theo bước để hiển thị "Bước 1 · Trưởng bộ phận" … */
function groupSteps(approvers: ProposalApproverRow[]) {
  const steps = new Map<number, ProposalApproverRow[]>();
  for (const a of approvers) steps.set(a.step, [...(steps.get(a.step) ?? []), a]);
  return [...steps.entries()].sort((x, y) => x[0] - y[0]);
}

function DecisionForm({ proposalId }: { proposalId: string }) {
  return (
    <ActionForm action={decideProposalAction} success="Đã ghi nhận quyết định." className="mt-2 flex flex-col gap-2 rounded-lg bg-ink-50 p-2.5">
      <input type="hidden" name="proposalId" value={proposalId} />
      <input name="note" placeholder="Ghi chú (bắt buộc khi từ chối)" className="input text-xs" />
      <div className="flex gap-2">
        <button type="submit" name="decision" value="APPROVED" className="btn-ghost text-xs text-emerald-700">
          Duyệt
        </button>
        <button type="submit" name="decision" value="REJECTED" className="btn-ghost text-xs text-red-600">
          Từ chối
        </button>
      </div>
    </ActionForm>
  );
}

export type AdminTools = { courses: Course[]; customers: CustomerOption[]; history: Record<string, AuditEntry[]> };

export function ProposalList({ proposals, currentUserId, admin }: { proposals: ProposalRow[]; currentUserId: string; admin?: AdminTools }) {
  return (
    <div className="flex flex-col gap-3">
      {proposals.map((p) => (
        <ProposalCard key={p.id} proposal={p} currentUserId={currentUserId} admin={admin} />
      ))}
    </div>
  );
}

/** Ngoại lệ của Ban giám đốc: sửa nội dung phiếu đã gửi. Chuỗi duyệt và kết quả duyệt giữ nguyên. */
function AdminEditForm({ proposal: p, admin, onDone }: { proposal: ProposalRow; admin: AdminTools; onDone: () => void }) {
  const config = proposalType(p.details?.type);
  const values = p.details?.values ?? {};
  return (
    <ActionForm
      action={async (formData) => {
        const result = await updateProposalAction(formData);
        if (result.ok) onDone();
        return result;
      }}
      success="Đã cập nhật phiếu đề xuất."
      className="mt-3 flex flex-col gap-3 rounded-lg border border-gold-500 bg-gold-100/40 p-3"
    >
      <input type="hidden" name="proposalId" value={p.id} />
      <div className="text-xs font-semibold text-ink-600">Ban giám đốc sửa phiếu — chuỗi duyệt và kết quả duyệt không đổi; mọi thay đổi được ghi vào nhật ký.</div>
      <div>
        <label htmlFor={`t-${p.id}`} className="label-caps mb-1.5 block">
          Tiêu đề
        </label>
        <input id={`t-${p.id}`} name="title" required defaultValue={p.title} className="input" />
      </div>
      {config && config.fields.length > 0 && (
        <div className="grid gap-4 rounded-lg bg-white p-3 lg:grid-cols-2">
          {config.fields.map((field) => (
            <FieldInput
              key={field.key}
              field={field}
              courses={admin.courses}
              customers={admin.customers}
              idPrefix={`e-${p.id}`}
              initial={{ text: values[field.key] ?? "", id: values[`${field.key}Id`] }}
            />
          ))}
        </div>
      )}
      <div>
        <label htmlFor={`c-${p.id}`} className="label-caps mb-1.5 block">
          Nội dung / lý do đề xuất
        </label>
        <textarea id={`c-${p.id}`} name="content" required rows={3} defaultValue={p.content} className="input" />
      </div>
      <div className="flex gap-2">
        <button type="submit" className="btn-primary">
          Lưu thay đổi
        </button>
        <button type="button" onClick={onDone} className="btn-ghost">
          Đóng
        </button>
      </div>
    </ActionForm>
  );
}

function ProposalCard({ proposal: p, currentUserId, admin }: { proposal: ProposalRow; currentUserId: string; admin?: AdminTools }) {
  const [open, setOpen] = useState(!!p.myTurnRowId);
  const [editing, setEditing] = useState(false);
  const history = admin?.history[p.id] ?? [];
  const config = proposalType(p.details?.type);
  const values = p.details?.values ?? {};
  const detailRows = (config?.fields ?? []).map((field) => ({ field, text: displayFieldValue(field, values[field.key] ?? "") })).filter((row) => row.text);

  return (
    <div className={`card p-4 ${p.myTurnRowId ? "border-2 border-gold-500" : ""}`}>
      <div className="flex flex-wrap items-start justify-between gap-2">
        <div className="min-w-0">
          <div className="flex flex-wrap items-center gap-2">
            {p.kind && <Badge tone="brand">{p.kind}</Badge>}
            <span className="font-semibold text-ink-700">{p.title}</span>
            {p.details?.withdrawnAt ? <Badge tone="neutral">Đã thu hồi</Badge> : <Badge tone={STATUS_TONE[p.status]}>{STATUS_LABEL[p.status]}</Badge>}
            {p.myTurnRowId && <Badge tone="gold">Đến lượt bạn duyệt</Badge>}
          </div>
          <p className="mt-1 text-[11px] text-ink-400">
            {p.createdByName}
            {p.createdBy === currentUserId ? " (bạn)" : ""} · {formatDateTime(p.createdAt)}
            {p.decidedAt ? ` · có kết quả ${formatDateTime(p.decidedAt)}` : ""}
          </p>
        </div>
        <button type="button" onClick={() => setOpen((v) => !v)} className="btn-ghost px-3 py-1 text-xs">
          {open ? "Thu gọn" : "Xem phiếu"}
        </button>
      </div>

      {open && (
        <div className="mt-3">
          {detailRows.length > 0 && (
            <dl className="mb-2 grid gap-x-6 gap-y-1 rounded-lg bg-ink-50 px-3 py-2 text-sm lg:grid-cols-2">
              {detailRows.map((row) => (
                <div key={row.field.key} className="flex gap-2">
                  <dt className="shrink-0 text-ink-400">{row.field.label}:</dt>
                  <dd className="text-ink-700">{row.text}</dd>
                </div>
              ))}
            </dl>
          )}
          <p className="whitespace-pre-line text-sm text-ink-600">{p.content}</p>
        </div>
      )}

      <div className="mt-3 flex flex-col gap-2 border-t border-[var(--color-line)] pt-3">
        <div className="flex flex-wrap items-center gap-2 text-sm">
          <Badge tone="green">Đề xuất</Badge>
          <span className="text-ink-600">{p.createdByName}</span>
        </div>
        {groupSteps(p.approvers).map(([step, list]) => (
          <div key={step} className="flex flex-col gap-1">
            <div className="text-[11px] font-semibold uppercase tracking-wide text-ink-400">
              Bước {step + 1} · {list[0].stepLabel ?? "Người duyệt"}
            </div>
            {list.map((a) => (
              <div key={a.id} className="flex flex-wrap items-center gap-2 text-sm">
                <span className="text-ink-600">{a.approverName}</span>
                <Badge tone={a.decision === "APPROVED" ? "green" : a.decision === "REJECTED" ? "red" : a.isTurn ? "gold" : "neutral"}>
                  {a.decision === "PENDING" ? (a.isTurn ? "Đang chờ duyệt" : p.status === "PENDING" ? "Chờ đến lượt" : "Không cần duyệt nữa") : STATUS_LABEL[a.decision]}
                </Badge>
                {a.decidedAt && <span className="text-[11px] text-ink-400">{formatDateTime(a.decidedAt)}</span>}
                {a.note && <span className="text-xs text-ink-500">— {a.note}</span>}
              </div>
            ))}
          </div>
        ))}

        {p.myTurnRowId && <DecisionForm proposalId={p.id} />}

        {admin && (
          <div className="flex flex-wrap items-center gap-2">
            <button type="button" onClick={() => setEditing((v) => !v)} className="btn-ghost px-2 py-1 text-xs">
              {editing ? "Đóng khung sửa" : "Sửa phiếu (Ban giám đốc)"}
            </button>
            <ActionForm action={deleteProposalAction} success="Đã xoá phiếu đề xuất." confirm="Xoá hẳn phiếu đề xuất này cùng kết quả duyệt? Nhật ký vẫn giữ lại toàn bộ nội dung phiếu. Không hoàn tác được.">
              <input type="hidden" name="proposalId" value={p.id} />
              <button type="submit" className="btn-ghost px-2 py-1 text-xs text-red-600">
                Xoá phiếu
              </button>
            </ActionForm>
          </div>
        )}
        {admin && editing && <AdminEditForm proposal={p} admin={admin} onDone={() => setEditing(false)} />}
        {admin && (
          <details className="rounded-lg border border-[var(--color-line)]">
            <summary className="cursor-pointer px-3 py-2 text-xs font-semibold text-ink-600">Lịch sử chỉnh sửa ({history.length})</summary>
            {history.length === 0 ? (
              <p className="px-3 pb-3 text-xs text-ink-400">Phiếu chưa được chỉnh sửa lần nào.</p>
            ) : (
              <ul className="divide-y divide-[var(--color-line)] border-t border-[var(--color-line)]">
                {history.map((entry) => (
                  <AuditEntryRow key={entry.id} entry={entry} showEntity={false} />
                ))}
              </ul>
            )}
          </details>
        )}

        {p.canWithdraw && (
          <ActionForm action={withdrawProposalAction} success="Đã thu hồi phiếu." confirm="Thu hồi phiếu đề xuất này? Phiếu được giữ lại trong lịch sử với trạng thái “Đã thu hồi”." className="self-start">
            <input type="hidden" name="proposalId" value={p.id} />
            <button type="submit" className="btn-ghost px-2 py-1 text-xs text-red-600">
              Thu hồi phiếu
            </button>
          </ActionForm>
        )}
      </div>
    </div>
  );
}
