import Link from "next/link";
import { CalendarPlus, ChevronLeft, Search } from "lucide-react";
import {
  deleteSponsorPaymentAction,
  generateSponsorPaymentsAction,
  undoSponsorPaymentAction,
  updateSponsorPaymentAction
} from "@/app/actions/admin";
import { Notice } from "@/components/dashboard/notice";
import { PageHeader } from "@/components/dashboard/page-header";
import { StatCard } from "@/components/dashboard/stat-card";
import { ConfirmActionForm } from "@/components/forms/confirm-action-form";
import { SubmitButton } from "@/components/forms/submit-button";
import { Badge } from "@/components/ui/badge";
import { Card } from "@/components/ui/card";
import { EmptyState } from "@/components/ui/empty-state";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { formatSdg } from "@/lib/calculations";
import { MISSING_VALUE, paymentStatusLabels } from "@/lib/constants";
import { currentPeriod, formatDate, formatMonthYear, todayIso } from "@/lib/dates";
import { requireProfile } from "@/lib/auth";
import { createAdminSupabaseClient } from "@/lib/supabase/admin";

type SearchParams = {
  year?: string;
  month?: string;
  sponsor?: string;
  orphan?: string;
  status?: string;
  success?: string;
  error?: string;
};

type PaymentRow = {
  id: string;
  expected_amount_snapshot: number;
  received_amount: number;
  payment_status: "unpaid" | "partial" | "paid";
  payment_date: string | null;
  internal_notes: string | null;
  profiles: { full_name: string; phone: string | null } | { full_name: string; phone: string | null }[] | null;
  orphans: { case_number: string; full_name: string | null } | { case_number: string; full_name: string | null }[] | null;
};

function one<T>(value: T | T[] | null): T | null {
  return Array.isArray(value) ? value[0] ?? null : value;
}

export default async function PaymentsPage({ searchParams }: { searchParams: Promise<SearchParams> }) {
  const params = await searchParams;
  const current = currentPeriod();
  const year = Math.min(2200, Math.max(2020, Number(params.year) || current.year));
  const month = Math.min(12, Math.max(1, Number(params.month) || current.month));
  const profile = await requireProfile("admin");
  const supabase = createAdminSupabaseClient();

  // Opening the page materializes missing obligations for the selected month.
  // ON CONFLICT keeps this idempotent and preserves historical snapshots.
  await supabase.rpc("ensure_sponsor_monthly_payments", {
    target_year: year,
    target_month: month,
    actor: profile.id
  });

  let paymentsQuery = supabase
    .from("sponsor_monthly_payments")
    .select("id,expected_amount_snapshot,received_amount,payment_status,payment_date,internal_notes,profiles!sponsor_monthly_payments_sponsor_id_fkey(full_name,phone),orphans(case_number,full_name)")
    .eq("payment_year", year)
    .eq("payment_month", month)
    .order("payment_status")
    .order("created_at");
  if (params.sponsor && /^[0-9a-f-]{36}$/i.test(params.sponsor)) paymentsQuery = paymentsQuery.eq("sponsor_id", params.sponsor);
  if (params.orphan && /^[0-9a-f-]{36}$/i.test(params.orphan)) paymentsQuery = paymentsQuery.eq("orphan_id", params.orphan);
  if (params.status && params.status in paymentStatusLabels) paymentsQuery = paymentsQuery.eq("payment_status", params.status);

  const [paymentsResult, sponsorsResult, orphansResult] = await Promise.all([
    paymentsQuery.limit(500),
    supabase.from("profiles").select("id,full_name").eq("role", "donor").order("full_name"),
    supabase.from("orphans").select("id,case_number,full_name").order("case_number")
  ]);
  const payments = (paymentsResult.data ?? []) as PaymentRow[];
  const totals = payments.reduce(
    (sum, payment) => ({
      expected: sum.expected + Number(payment.expected_amount_snapshot),
      received: sum.received + Number(payment.received_amount),
      paid: sum.paid + (payment.payment_status === "paid" ? 1 : 0),
      partial: sum.partial + (payment.payment_status === "partial" ? 1 : 0),
      unpaid: sum.unpaid + (payment.payment_status === "unpaid" ? 1 : 0)
    }),
    { expected: 0, received: 0, paid: 0, partial: 0, unpaid: 0 }
  );
  const query = new URLSearchParams({
    year: String(year),
    month: String(month),
    ...(params.sponsor ? { sponsor: params.sponsor } : {}),
    ...(params.orphan ? { orphan: params.orphan } : {}),
    ...(params.status ? { status: params.status } : {})
  });
  const returnTo = `/admin/payments?${query.toString()}`;
  const previous = month === 1 ? { year: year - 1, month: 12 } : { year, month: month - 1 };

  return (
    <>
      <PageHeader
        title="دفعات المتبرعين"
        description={`متابعة الدفع الشهري من المتبرع إلى المبادرة لشهر ${formatMonthYear(year, month)}.`}
        action={
          <Link href={`/admin/payments?year=${previous.year}&month=${previous.month}`} className="inline-flex h-10 items-center gap-2 rounded-md border bg-white px-3 text-sm font-bold">
            عرض الشهر السابق <ChevronLeft size={16} aria-hidden />
          </Link>
        }
      />
      <Notice success={params.success} error={params.error} />

      <div className="grid gap-4 sm:grid-cols-2 xl:grid-cols-5">
        <StatCard label="إجمالي المتوقع" value={formatSdg(totals.expected)} />
        <StatCard label="إجمالي المستلم" value={formatSdg(totals.received)} />
        <StatCard label="المبلغ المتبقي" value={formatSdg(Math.max(0, totals.expected - totals.received))} />
        <StatCard label="المتبرعون المدفوعون" value={totals.paid} note={`${totals.partial} دفع جزئي`} />
        <StatCard label="المتبرعون غير المدفوعين" value={totals.unpaid} />
      </div>

      <Card className="my-6 p-5">
        <form className="grid gap-4 sm:grid-cols-2 xl:grid-cols-6">
          <div><Label>السنة</Label><Input name="year" type="number" min={2020} max={2200} defaultValue={year} /></div>
          <div><Label>الشهر</Label><Input name="month" type="number" min={1} max={12} defaultValue={month} /></div>
          <div>
            <Label>المتبرع</Label>
            <select name="sponsor" defaultValue={params.sponsor ?? ""} className="h-11 w-full rounded-md border bg-white px-3 text-sm">
              <option value="">جميع المتبرعين</option>
              {sponsorsResult.data?.map((sponsor) => <option key={sponsor.id} value={sponsor.id}>{sponsor.full_name}</option>)}
            </select>
          </div>
          <div>
            <Label>الحالة</Label>
            <select name="orphan" defaultValue={params.orphan ?? ""} className="h-11 w-full rounded-md border bg-white px-3 text-sm">
              <option value="">جميع الحالات</option>
              {orphansResult.data?.map((orphan) => <option key={orphan.id} value={orphan.id}>{orphan.full_name ?? `حالة ${orphan.case_number}`} - {orphan.case_number}</option>)}
            </select>
          </div>
          <div>
            <Label>حالة الدفع</Label>
            <select name="status" defaultValue={params.status ?? ""} className="h-11 w-full rounded-md border bg-white px-3 text-sm">
              <option value="">كل الحالات</option>
              {Object.entries(paymentStatusLabels).map(([value, label]) => <option key={value} value={value}>{label}</option>)}
            </select>
          </div>
          <button className="inline-flex h-11 items-center justify-center gap-2 self-end rounded-md border bg-white px-4 text-sm font-bold">
            <Search size={17} aria-hidden /> تصفية
          </button>
        </form>
      </Card>

      <Card className="mb-6 p-5">
        <form action={generateSponsorPaymentsAction} className="flex flex-wrap items-end gap-4">
          <input type="hidden" name="year" value={year} />
          <input type="hidden" name="month" value={month} />
          <input type="hidden" name="returnTo" value={returnTo} />
          <div>
            <p className="text-sm font-black">استعادة السجلات الناقصة</p>
            <p className="mt-1 text-xs leading-6 text-[var(--ink-soft)]">ينشئ فقط التزامات الكفالات الصالحة غير الموجودة لهذه الفترة.</p>
          </div>
          <SubmitButton pendingText="جارٍ إنشاء السجلات..." size="sm" className="w-full sm:mr-auto sm:w-auto">
            <CalendarPlus size={16} aria-hidden /> إنشاء السجلات الناقصة
          </SubmitButton>
        </form>
      </Card>

      {payments.length ? (
        <>
          <div className="grid gap-4 xl:hidden">
            {payments.map((payment) => (
              <PaymentCard key={payment.id} payment={payment} returnTo={returnTo} />
            ))}
          </div>
          <Card className="hidden overflow-hidden xl:block">
            <div className="table-scroll">
              <table className="w-full min-w-[1100px] text-right text-sm">
                <thead className="bg-[var(--surface-muted)] text-xs text-[var(--ink-soft)]">
                  <tr>
                    <th className="px-4 py-3">المتبرع</th>
                    <th className="px-4 py-3">الحالة</th>
                    <th className="px-4 py-3">المتوقع</th>
                    <th className="px-4 py-3">المستلم</th>
                    <th className="px-4 py-3">الحالة</th>
                    <th className="px-4 py-3">تاريخ الدفع</th>
                    <th className="px-4 py-3">الإجراء</th>
                  </tr>
                </thead>
                <tbody className="divide-y">
                  {payments.map((payment) => {
                    const sponsor = one(payment.profiles);
                    const orphan = one(payment.orphans);
                    return (
                      <tr key={payment.id} className={payment.payment_status === "unpaid" ? "bg-[#fffaf3]" : undefined}>
                        <td className="px-4 py-3"><p className="font-bold">{sponsor?.full_name ?? MISSING_VALUE}</p><p className="mt-1 text-xs text-[var(--ink-faint)]" dir="ltr">{sponsor?.phone ?? ""}</p></td>
                        <td className="px-4 py-3 font-bold">{orphan?.full_name ?? `حالة ${orphan?.case_number}`}<p className="mt-1 text-xs text-[var(--ink-faint)]" dir="ltr">{orphan?.case_number}</p></td>
                        <td className="px-4 py-3">{formatSdg(Number(payment.expected_amount_snapshot))}</td>
                        <td className="px-4 py-3 font-black">{formatSdg(Number(payment.received_amount))}</td>
                        <td className="px-4 py-3"><PaymentBadge status={payment.payment_status} /></td>
                        <td className="px-4 py-3">{formatDate(payment.payment_date)}</td>
                        <td className="px-4 py-3"><details><summary className="cursor-pointer font-bold text-[var(--primary)]">{payment.payment_status === "unpaid" ? "تأكيد دفع هذا الشهر" : "تصحيح الدفعة"}</summary><div className="mt-3 w-[460px] max-w-[70vw]"><PaymentEditor payment={payment} returnTo={returnTo} /></div></details></td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </div>
          </Card>
        </>
      ) : (
        <Card><EmptyState title="لا توجد سجلات مطابقة" description="غيّر عوامل التصفية أو أنشئ السجلات الشهرية الناقصة." /></Card>
      )}
    </>
  );
}

function PaymentCard({ payment, returnTo }: { payment: PaymentRow; returnTo: string }) {
  const sponsor = one(payment.profiles);
  const orphan = one(payment.orphans);
  return (
    <Card className={payment.payment_status === "unpaid" ? "min-w-0 border-[#dfc48f] p-4 sm:p-5" : "min-w-0 p-4 sm:p-5"}>
      <div className="flex items-start justify-between gap-3">
        <div className="min-w-0">
          <h2 className="break-words font-black">{sponsor?.full_name ?? MISSING_VALUE}</h2>
          <p className="mt-1 break-words text-xs leading-6 text-[var(--ink-faint)]">{orphan?.full_name ?? `حالة ${orphan?.case_number}`} - {orphan?.case_number}</p>
        </div>
        <PaymentBadge status={payment.payment_status} />
      </div>
      <dl className="mt-4 grid grid-cols-2 gap-4 text-sm">
        <div className="min-w-0"><dt className="text-xs text-[var(--ink-faint)]">المتوقع</dt><dd className="mt-1 break-words font-black">{formatSdg(Number(payment.expected_amount_snapshot))}</dd></div>
        <div className="min-w-0"><dt className="text-xs text-[var(--ink-faint)]">المستلم</dt><dd className="mt-1 break-words font-black">{formatSdg(Number(payment.received_amount))}</dd></div>
        <div className="min-w-0"><dt className="text-xs text-[var(--ink-faint)]">تاريخ الدفع</dt><dd className="mt-1 break-words font-bold">{formatDate(payment.payment_date)}</dd></div>
      </dl>
      <details className="mt-5 border-t pt-4">
        <summary className="cursor-pointer text-sm font-black text-[var(--primary)]">
          {payment.payment_status === "unpaid" ? "تأكيد دفع هذا الشهر" : "تصحيح الدفعة"}
        </summary>
        <div className="mt-4"><PaymentEditor payment={payment} returnTo={returnTo} /></div>
      </details>
    </Card>
  );
}

function PaymentEditor({ payment, returnTo }: { payment: PaymentRow; returnTo: string }) {
  return (
    <div className="grid gap-3">
      <form action={updateSponsorPaymentAction} className="grid gap-3 sm:grid-cols-2">
        <input type="hidden" name="id" value={payment.id} />
        <input type="hidden" name="returnTo" value={returnTo} />
        <div><Label>المبلغ المتوقع</Label><Input name="expectedAmount" type="number" min={0} defaultValue={payment.expected_amount_snapshot} required /></div>
        <div><Label>المبلغ المستلم</Label><Input name="receivedAmount" type="number" min={0} defaultValue={payment.received_amount || payment.expected_amount_snapshot} required /></div>
        <div><Label>تاريخ الدفع</Label><Input name="paymentDate" type="date" defaultValue={payment.payment_date ?? todayIso()} /></div>
        <div><Label>ملاحظة داخلية</Label><Input name="internalNotes" defaultValue={payment.internal_notes ?? ""} /></div>
        <SubmitButton pendingText="جارٍ تأكيد الدفع..." size="sm" className="w-full sm:w-auto sm:justify-self-start">
          {payment.payment_status === "unpaid" ? "تأكيد الدفع" : "حفظ التصحيح"}
        </SubmitButton>
      </form>
      <div className="flex flex-wrap gap-2">
        {payment.payment_status !== "unpaid" ? (
          <ConfirmActionForm
            action={undoSponsorPaymentAction}
            fields={{ id: payment.id, returnTo }}
            label="إلغاء التأكيد"
            pendingText="جارٍ إلغاء التأكيد..."
            confirmMessage="هل تريد إعادة هذه الدفعة إلى غير مدفوع؟"
          />
        ) : null}
        <ConfirmActionForm
          action={deleteSponsorPaymentAction}
          fields={{ id: payment.id, returnTo }}
          label="حذف السجل"
          confirmMessage="هل تريد حذف هذا السجل الشهري؟ يمكنك إعادة إنشائه لاحقاً."
        />
      </div>
    </div>
  );
}

function PaymentBadge({ status }: { status: PaymentRow["payment_status"] }) {
  return (
    <Badge tone={status === "paid" ? "success" : status === "partial" ? "warning" : "danger"}>
      {paymentStatusLabels[status]}
    </Badge>
  );
}
