"use client";

import { useEffect, useMemo, useState } from "react";

import { useLocale } from "@/components/providers/locale-provider";
import { EmptyState } from "@/components/shared/ops-primitives";
import { formatCurrencyAmount } from "@/lib/formatters";
import type { ApiErrorResponse, DetailResponse } from "@/types/api";
import type { FundRequestListItem, FundRequestTransferType } from "@/types/fund-request";
import type { AgentRecord } from "@/types/master-data";

type BootstrapPayload = {
  agents: AgentRecord[];
  company_bank_accounts: Array<{
    id: string;
    bank_id: string;
    bank_code: string;
    bank_name: string;
    account_number: string;
  }>;
  company_bank_name: string;
  company_bank_account_number: string;
  currency_code: string;
};

type CreateForm = {
  transfer_type: FundRequestTransferType;
  reference_no: string;
  agent_id: string;
  agent_bank_account_id: string;
  company_bank_account_id: string;
  amount: string;
  transferred_at: string;
  transfer_proof_file: File | null;
};

function emptyForm(): CreateForm {
  const now = new Date();
  const local = new Date(now.getTime() - now.getTimezoneOffset() * 60_000).toISOString().slice(0, 16);
  return {
    transfer_type: "CAPITAL",
    reference_no: "",
    agent_id: "",
    agent_bank_account_id: "",
    company_bank_account_id: "",
    amount: "",
    transferred_at: local,
    transfer_proof_file: null
  };
}

function statusChip(status: string) {
  return status === "SUBMITTED" ? "ops-chip-active" : "ops-chip-muted";
}

function InfoCard({ label, value }: { label: string; value: string }) {
  return (
    <div className="rounded border border-line/70 bg-white px-4 py-3">
      <p className="ops-overline">{label}</p>
      <p className="mt-2 text-[14px] font-medium text-ink">{value}</p>
    </div>
  );
}

function Field({
  label,
  value,
  onChange,
  type = "text",
  readOnly = false,
  placeholder
}: {
  label: string;
  value: string;
  onChange?: (value: string) => void;
  type?: string;
  readOnly?: boolean;
  placeholder?: string;
}) {
  return (
    <label className="block">
      <span className="ops-label">{label}</span>
      <input
        type={type}
        value={value}
        readOnly={readOnly}
        placeholder={placeholder}
        onChange={(event) => onChange?.(event.target.value)}
        className={`ops-input ${readOnly ? "bg-slate-50 text-slate-600" : ""}`}
      />
    </label>
  );
}

function SelectField({
  label,
  value,
  onChange,
  options,
  placeholder
}: {
  label: string;
  value: string;
  onChange: (value: string) => void;
  options: Array<{ value: string; label: string }>;
  placeholder?: string;
}) {
  return (
    <label className="block">
      <span className="ops-label">{label}</span>
      <select value={value} onChange={(event) => onChange(event.target.value)} className="ops-select">
        {placeholder ? <option value="">{placeholder}</option> : null}
        {options.map((option) => (
          <option key={option.value} value={option.value}>
            {option.label}
          </option>
        ))}
      </select>
    </label>
  );
}

export function FundRequestsClient() {
  const { locale } = useLocale();
  const [items, setItems] = useState<FundRequestListItem[]>([]);
  const [agents, setAgents] = useState<AgentRecord[]>([]);
  const [companyBankAccounts, setCompanyBankAccounts] = useState<BootstrapPayload["company_bank_accounts"]>([]);
  const [companyBankName, setCompanyBankName] = useState("");
  const [companyBankAccountNumber, setCompanyBankAccountNumber] = useState("");
  const [currencyCode, setCurrencyCode] = useState("IDR");
  const [form, setForm] = useState<CreateForm>(emptyForm);
  const [selectedId, setSelectedId] = useState<string | null>(null);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const selectedAgent = useMemo(
    () => agents.find((agent) => agent.id === form.agent_id) ?? null,
    [agents, form.agent_id]
  );
  const selectedRequest = useMemo(
    () => items.find((item) => item.id === selectedId) ?? null,
    [items, selectedId]
  );
  const selectedCompanyBankAccount = useMemo(
    () => companyBankAccounts.find((account) => account.id === form.company_bank_account_id) ?? null,
    [companyBankAccounts, form.company_bank_account_id]
  );
  const affectedBalanceLabel =
    form.transfer_type === "PROFIT_SHARE"
      ? locale === "id" ? "Saldo bagi hasil akan berkurang" : "Profit-share balance will decrease"
      : locale === "id" ? "Saldo modal akan bertambah" : "Capital balance will increase";
  const affectedBalanceValue = selectedAgent
    ? form.transfer_type === "PROFIT_SHARE"
      ? formatCurrencyAmount(selectedAgent.profit_share_balance, locale, currencyCode)
      : formatCurrencyAmount(selectedAgent.capital_balance, locale, currencyCode)
    : "-";

  async function loadData() {
    setLoading(true);
    setError(null);

    try {
      const [bootstrapResponse, listResponse] = await Promise.all([
        fetch("/api/v1/fund-requests/bootstrap", { cache: "no-store" }),
        fetch("/api/v1/fund-requests", { cache: "no-store" })
      ]);

      const bootstrapPayload = (await bootstrapResponse.json()) as
        | DetailResponse<BootstrapPayload>
        | ApiErrorResponse;
      const listPayload = (await listResponse.json()) as
        | DetailResponse<FundRequestListItem[]>
        | ApiErrorResponse;

      if (
        !bootstrapResponse.ok ||
        !("data" in bootstrapPayload) ||
        !listResponse.ok ||
        !("data" in listPayload)
      ) {
        throw new Error(
          ("message" in bootstrapPayload && bootstrapPayload.message) ||
            ("message" in listPayload && listPayload.message) ||
            "Gagal memuat permintaan dana"
        );
      }

      setAgents(bootstrapPayload.data.agents);
      setCompanyBankAccounts(bootstrapPayload.data.company_bank_accounts);
      setCompanyBankName(bootstrapPayload.data.company_bank_name);
      setCompanyBankAccountNumber(bootstrapPayload.data.company_bank_account_number);
      setCurrencyCode(bootstrapPayload.data.currency_code);
      setItems(listPayload.data);
      setSelectedId((current) => current ?? listPayload.data[0]?.id ?? null);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Gagal memuat permintaan dana");
    } finally {
      setLoading(false);
    }
  }

  useEffect(() => {
    void loadData();
  }, []);

  function patch<K extends keyof CreateForm>(key: K, value: CreateForm[K]) {
    setForm((current) => ({ ...current, [key]: value }));
  }

  async function saveRequest() {
    setSaving(true);
    setError(null);

    try {
      const payload = new FormData();
      payload.append("transfer_type", form.transfer_type);
      payload.append("reference_no", form.reference_no);
      payload.append("agent_id", form.agent_id);
      payload.append("agent_bank_account_id", form.agent_bank_account_id);
      payload.append("company_bank_account_id", form.company_bank_account_id);
      payload.append("amount", form.amount);
      payload.append("transferred_at", form.transferred_at);
      if (form.transfer_proof_file) {
        payload.append("transfer_proof_file", form.transfer_proof_file);
      }

      const response = await fetch("/api/v1/fund-requests", {
        method: "POST",
        body: payload
      });
      const body = (await response.json()) as DetailResponse<FundRequestListItem> | ApiErrorResponse;

      if (!response.ok || !("data" in body)) {
        throw new Error("message" in body ? body.message : "Gagal menyimpan permintaan dana");
      }

      setForm(emptyForm());
      await loadData();
      setSelectedId(body.data.id);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Gagal menyimpan permintaan dana");
    } finally {
      setSaving(false);
    }
  }

  return (
    <section className="grid gap-6 xl:grid-cols-[1fr_1fr]">
      <div className="ops-card p-6">
        <div className="flex items-start justify-between gap-4">
          <div>
            <p className="ops-overline">{locale === "id" ? "Permintaan Dana" : "Fund Request"}</p>
            <h2 className="mt-2 text-[28px] font-semibold tracking-tight text-ink">{locale === "id" ? "Transfer dana agen" : "Agent fund transfer"}</h2>
            <p className="mt-3 text-[13px] leading-6 text-slate-500">
              {locale === "id" ? "Catat transfer dana modal atau bagi hasil ke agen, lengkap dengan snapshot rekening tujuan dan bukti transfer." : "Record capital or profit-share transfers to agents, including destination account snapshots and transfer proof."}
            </p>
          </div>
          <button type="button" onClick={() => setForm(emptyForm())} className="ops-btn-secondary">
            {locale === "id" ? "Reset formulir" : "Reset form"}
          </button>
        </div>

        <div className="mt-6 grid gap-4 md:grid-cols-2">
          <Field label={locale === "id" ? "Kode" : "Code"} value={locale === "id" ? "Otomatis saat disimpan" : "Generated when saved"} readOnly />
          <SelectField
            label={locale === "id" ? "Tipe transfer" : "Transfer type"}
            value={form.transfer_type}
            onChange={(value) => patch("transfer_type", value as FundRequestTransferType)}
            options={[
              { value: "CAPITAL", label: locale === "id" ? "Dana modal" : "Capital fund" },
              { value: "PROFIT_SHARE", label: locale === "id" ? "Bagi hasil" : "Profit share" }
            ]}
          />
          <Field
            label={locale === "id" ? "No. referensi" : "Reference no."}
            value={form.reference_no}
            onChange={(value) => patch("reference_no", value)}
            placeholder={locale === "id" ? "Masukkan nomor referensi transfer" : "Enter transfer reference number"}
          />
          <SelectField
            label={locale === "id" ? "Agen" : "Agent"}
            value={form.agent_id}
            onChange={(value) => {
              patch("agent_id", value);
              patch("agent_bank_account_id", "");
            }}
            options={agents.map((agent) => ({
              value: agent.id,
              label: `${agent.code} - ${agent.name}`
            }))}
            placeholder={locale === "id" ? "Pilih agen" : "Choose agent"}
          />
          <SelectField
            label={locale === "id" ? "Rekening agen" : "Agent bank account"}
            value={form.agent_bank_account_id}
            onChange={(value) => patch("agent_bank_account_id", value)}
            options={(selectedAgent?.bank_accounts ?? []).map((account) => ({
              value: account.id,
              label: `${account.bank_name} · ${account.account_number}`
            }))}
            placeholder={selectedAgent ? (locale === "id" ? "Pilih rekening agen" : "Choose agent bank account") : (locale === "id" ? "Pilih agen terlebih dahulu" : "Choose an agent first")}
          />
          <SelectField
            label={locale === "id" ? "Rekening perusahaan" : "Company bank account"}
            value={form.company_bank_account_id}
            onChange={(value) => patch("company_bank_account_id", value)}
            options={companyBankAccounts.map((account) => ({
              value: account.id,
              label: `${account.bank_name} · ${account.account_number}`
            }))}
            placeholder={locale === "id" ? "Pilih rekening kantor" : "Choose company bank account"}
          />
          <Field
            label={`Nominal transfer (${currencyCode})`}
            value={form.amount}
            onChange={(value) => patch("amount", value)}
            type="number"
            placeholder="0"
          />
          <Field
            label={locale === "id" ? "Waktu transfer" : "Transfer time"}
            value={form.transferred_at}
            onChange={(value) => patch("transferred_at", value)}
            type="datetime-local"
          />
          <label className="block md:col-span-2">
            <span className="ops-label">{locale === "id" ? "Unggah bukti transfer" : "Upload transfer proof"}</span>
            <input
              type="file"
              accept=".jpg,.jpeg,.png,.pdf"
              className="ops-input pt-3"
              onChange={(event) => patch("transfer_proof_file", event.target.files?.[0] ?? null)}
            />
          </label>
        </div>

        <div className="mt-5 grid gap-4 md:grid-cols-2 xl:grid-cols-3">
          <InfoCard
            label="Rekening kantor"
            value={
              selectedCompanyBankAccount
                ? `${selectedCompanyBankAccount.bank_name} · ${selectedCompanyBankAccount.account_number}`
                : companyBankName && companyBankAccountNumber
                  ? `${companyBankName} · ${companyBankAccountNumber}`
                : locale === "id" ? "Lengkapi di pengaturan sistem" : "Complete this in system settings"
            }
          />
          <InfoCard
            label="Saldo bagi hasil agen"
            value={
              selectedAgent
                ? formatCurrencyAmount(selectedAgent.profit_share_balance, locale, currencyCode)
                : "-"
            }
          />
          <InfoCard
            label="Saldo modal agen"
            value={
              selectedAgent
                ? formatCurrencyAmount(selectedAgent.capital_balance, locale, currencyCode)
                : "-"
            }
          />
        </div>

        <div className="mt-4 rounded border border-line/70 bg-slate-50/70 px-4 py-3 text-sm text-slate-600">
          {affectedBalanceLabel}:{" "}
          <span className="font-semibold text-ink">{affectedBalanceValue}</span>
        </div>

        {error ? (
          <div className="mt-5 rounded border border-ember/30 bg-ember/10 px-4 py-3 text-sm text-ember">
            {error}
          </div>
        ) : null}

        <div className="mt-6 flex justify-end">
          <button type="button" onClick={saveRequest} className="ops-btn-primary" disabled={saving}>
            {saving ? (locale === "id" ? "Menyimpan..." : "Saving...") : (locale === "id" ? "Simpan permintaan dana" : "Save fund request")}
          </button>
        </div>
      </div>

      <div className="space-y-6">
        <div className="ops-table-shell">
          <div className="ops-section-head">
            <div>
              <p className="ops-title">{locale === "id" ? "Daftar Permintaan Dana" : "Fund Request List"}</p>
              <p className="ops-copy">{locale === "id" ? "Riwayat transfer dana modal dan bagi hasil ke agen." : "History of capital and profit-share transfers to agents."}</p>
            </div>
            <div className="ops-chip-muted">{items.length} transaksi</div>
          </div>

          {loading ? (
            <div className="px-6 py-8 text-sm text-ink/60">{locale === "id" ? "Memuat data..." : "Loading data..."}</div>
          ) : items.length === 0 ? (
            <EmptyState
              title={locale === "id" ? "Belum ada permintaan dana" : "No fund requests yet"}
              copy={locale === "id" ? "Buat transaksi pertama untuk mulai mencatat transfer dana ke agen." : "Create the first transaction to start recording transfers to agents."}
            />
          ) : (
            <div className="overflow-x-auto">
              <table className="ops-table">
                <thead>
                  <tr>
                    <th>{locale === "id" ? "Kode" : "Code"}</th>
                    <th>{locale === "id" ? "Waktu" : "Time"}</th>
                    <th>{locale === "id" ? "Agen" : "Agent"}</th>
                    <th>{locale === "id" ? "Tipe" : "Type"}</th>
                    <th>{locale === "id" ? "Nominal" : "Amount"}</th>
                    <th>{locale === "id" ? "Status" : "Status"}</th>
                  </tr>
                </thead>
                <tbody>
                  {items.map((item) => (
                    <tr
                      key={item.id}
                      className={selectedId === item.id ? "bg-moss/5" : undefined}
                      onClick={() => setSelectedId(item.id)}
                    >
                      <td className="font-semibold text-ink">{item.request_no}</td>
                      <td className="text-slate-600">
                        {new Date(item.transferred_at).toLocaleString(locale === "id" ? "id-ID" : "en-US")}
                      </td>
                      <td>
                        <div className="font-medium text-ink">{item.agent.name}</div>
                        <div className="text-xs text-slate-500">{item.reference_no}</div>
                      </td>
                      <td>{item.transfer_type === "CAPITAL" ? (locale === "id" ? "Dana modal" : "Capital fund") : (locale === "id" ? "Bagi hasil" : "Profit share")}</td>
                      <td>{formatCurrencyAmount(item.amount, locale, item.currency_code)}</td>
                      <td>
                        <span className={statusChip(item.status)}>{item.status}</span>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}
        </div>

        {!selectedRequest ? (
          <div className="ops-card p-6 text-sm text-ink/60">
            {locale === "id" ? "Pilih transaksi untuk melihat detail rekening agen, rekening kantor, dan bukti transfer." : "Select a transaction to view agent account, company account, and transfer proof details."}
          </div>
        ) : (
          <div className="ops-card p-6">
            <div className="flex items-start justify-between gap-4">
              <div>
                <p className="ops-overline">{locale === "id" ? "Detail Permintaan Dana" : "Fund Request Details"}</p>
                <h2 className="mt-2 text-[28px] font-semibold tracking-tight text-ink">
                  {selectedRequest.request_no}
                </h2>
                <p className="mt-2 text-sm text-slate-500">
                  {selectedRequest.agent.name} ·{" "}
                  {new Date(selectedRequest.transferred_at).toLocaleString(locale === "id" ? "id-ID" : "en-US")}
                </p>
              </div>
              <span className={statusChip(selectedRequest.status)}>{selectedRequest.status}</span>
            </div>

            <div className="mt-4 grid gap-4 md:grid-cols-2 xl:grid-cols-3">
              <InfoCard
                label={locale === "id" ? "Tipe transfer" : "Transfer type"}
                value={selectedRequest.transfer_type === "CAPITAL" ? (locale === "id" ? "Dana modal" : "Capital fund") : (locale === "id" ? "Bagi hasil" : "Profit share")}
              />
              <InfoCard label={locale === "id" ? "Agen" : "Agent"} value={`${selectedRequest.agent.code} · ${selectedRequest.agent.name}`} />
              <InfoCard label={locale === "id" ? "No. referensi" : "Reference no."} value={selectedRequest.reference_no} />
              <InfoCard
                label={locale === "id" ? "Nominal transfer" : "Transfer amount"}
                value={formatCurrencyAmount(selectedRequest.amount, locale, selectedRequest.currency_code)}
              />
              <InfoCard
                label={locale === "id" ? "Rekening agen" : "Agent bank account"}
                value={`${selectedRequest.agent_bank_account.bank_name} · ${selectedRequest.agent_bank_account.account_number}`}
              />
              <InfoCard
                label={locale === "id" ? "Rekening kantor" : "Company bank account"}
                value={`${selectedRequest.company_bank_account.bank_name} · ${selectedRequest.company_bank_account.account_number}`}
              />
              <InfoCard
                label={locale === "id" ? "Waktu transfer" : "Transfer time"}
                value={new Date(selectedRequest.transferred_at).toLocaleString(locale === "id" ? "id-ID" : "en-US")}
              />
            </div>

            {selectedRequest.transfer_proof_file_url ? (
              <div className="mt-4 rounded border border-line/70 bg-slate-50/70 px-4 py-3 text-sm text-slate-600">
                {locale === "id" ? "Bukti transfer" : "Transfer proof"}:{" "}
                <a
                  href={selectedRequest.transfer_proof_file_url}
                  target="_blank"
                  rel="noreferrer"
                  className="font-medium text-azure underline"
                >
                  {locale === "id" ? "Lihat file" : "View file"}
                </a>
              </div>
            ) : null}
          </div>
        )}
      </div>
    </section>
  );
}
