import Link from "next/link";
import {
  createProjectAccountAction,
  updateExpenseFundingAction,
  updateProjectAccountAction
} from "@/app/actions";
import { AppShell } from "@/components/AppShell";
import { EmptyState } from "@/components/EmptyState";
import { FundingFields } from "@/components/FundingFields";
import { FundingSummary } from "@/components/FundingSummary";
import { PageHeader } from "@/components/PageHeader";
import { StatusMessage } from "@/components/StatusMessage";
import { SummaryCard } from "@/components/SummaryCard";
import { fundingSourceOptions, projectAccountTypeOptions } from "@/lib/funding";
import { currency, shortDate } from "@/lib/format";
import { getSelectedProject } from "@/lib/projects";

function firstParam(value: string | string[] | undefined) {
  return Array.isArray(value) ? value[0] : value;
}

export default async function ReviewFundingSourcesPage({
  searchParams
}: {
  searchParams?: Promise<Record<string, string | string[] | undefined>>;
}) {
  const params = (await searchParams) ?? {};
  const selected = firstParam(params.projectId);
  const source = firstParam(params.source) ?? "";
  const partnerId = firstParam(params.partnerId) ?? "";
  const accountId = firstParam(params.accountId) ?? "";
  const categoryId = firstParam(params.categoryId) ?? "";
  const from = firstParam(params.from) ?? "";
  const to = firstParam(params.to) ?? "";
  const reviewOnly = firstParam(params.reviewOnly) !== "0";
  const { user, projects, project, permissions, projectRole } = await getSelectedProject(selected, "expenses.edit");

  if (!project) {
    return (
      <AppShell projects={projects} username={user.name ?? user.username ?? user.email} role={projectRole ?? user.role} permissions={permissions}>
        <EmptyState title="Create a project before reviewing funding sources." href="/projects" actionLabel="Create project" />
      </AppShell>
    );
  }

  const partnerOptions = project.partners.map((partner) => ({ id: partner.id, name: partner.partner.name }));
  const accountOptions = project.projectAccounts.map((account) => ({
    id: account.id,
    accountName: account.accountName,
    active: account.active
  }));
  const categories = project.categories.filter((category) =>
    ["PURCHASE_COST", "RENOVATION_EXPENSE", "OPERATING_EXPENSE"].includes(category.type)
  );
  const filteredExpenses = project.expenses.filter((expense) => {
    const expenseDate = expense.date.toISOString().slice(0, 10);
    const matchesReview = !reviewOnly || expense.fundingSourceType === "UNKNOWN";
    const matchesSource = !source || expense.fundingSourceType === source;
    const matchesPartner =
      !partnerId ||
      expense.paidById === partnerId ||
      expense.fundingPartnerId === partnerId ||
      expense.contributionCreditPartnerId === partnerId;
    const matchesAccount = !accountId || expense.projectAccountId === accountId;
    const matchesCategory = !categoryId || expense.categoryId === categoryId;
    const matchesFrom = !from || expenseDate >= from;
    const matchesTo = !to || expenseDate <= to;
    return matchesReview && matchesSource && matchesPartner && matchesAccount && matchesCategory && matchesFrom && matchesTo;
  });
  const unknownCount = project.expenses.filter((expense) => expense.fundingSourceType === "UNKNOWN").length;
  const projectFundTotal = project.expenses
    .filter((expense) => expense.fundingSourceType === "PROJECT_FUND" || expense.fundingSourceType === "JOINT_ACCOUNT")
    .reduce((sum, expense) => sum + Number(expense.finalCost), 0);
  const outOfPocketTotal = project.expenses
    .filter((expense) => expense.createsContributionCredit)
    .reduce((sum, expense) => sum + Number(expense.contributionCreditAmount ?? expense.finalCost), 0);

  return (
    <AppShell projects={projects} selectedProjectId={project.id} username={user.name ?? user.username ?? user.email} role={projectRole ?? user.role} permissions={permissions}>
      <PageHeader
        title="Review Funding Sources"
        description="Confirm whose money was used separately from who handled the payment."
        actions={<Link className="btn-secondary" href={`/expenses?projectId=${project.id}`}>Open expenses</Link>}
      />
      <StatusMessage updated={params.updated} deleted={params.deleted} error={params.error} />

      <section className="grid gap-4 md:grid-cols-2 xl:grid-cols-4">
        <SummaryCard label="Needs review" value={String(unknownCount)} />
        <SummaryCard label="Showing" value={String(filteredExpenses.length)} />
        <SummaryCard label="Project fund payments" value={projectFundTotal} />
        <SummaryCard label="Partner credit payments" value={outOfPocketTotal} />
      </section>

      <section className="mt-6 grid gap-6 xl:grid-cols-[0.8fr_1.2fr]">
        <div className="grid gap-4">
          <form action={createProjectAccountAction} className="panel grid gap-3 p-4">
            <h3 className="font-semibold text-ink">Add Project Account</h3>
            <input type="hidden" name="projectId" value={project.id} />
            <input className="field" name="accountName" placeholder="Account name" required />
            <select className="field" name="accountType" defaultValue="PROJECT_FUND">
              {projectAccountTypeOptions.map(([value, label]) => (
                <option key={value} value={value}>{label}</option>
              ))}
            </select>
            <input className="field" name="currentBalance" type="number" step="0.01" placeholder="Current balance (optional)" />
            <input className="field" name="notes" placeholder="Notes" />
            <button className="btn-primary">Save account</button>
          </form>

          <div className="panel overflow-hidden">
            <div className="border-b border-line px-4 py-3">
              <h3 className="font-semibold text-ink">Project Accounts</h3>
            </div>
            <div className="grid gap-3 p-4">
              {project.projectAccounts.map((account) => (
                <form key={account.id} action={updateProjectAccountAction} className="grid gap-2 rounded-md border border-line bg-slate-50 p-3">
                  <input type="hidden" name="projectId" value={project.id} />
                  <input type="hidden" name="projectAccountId" value={account.id} />
                  <input type="hidden" name="activePresent" value="1" />
                  <input className="field bg-white" name="accountName" defaultValue={account.accountName} required />
                  <select className="field bg-white" name="accountType" defaultValue={account.accountType}>
                    {projectAccountTypeOptions.map(([value, label]) => (
                      <option key={value} value={value}>{label}</option>
                    ))}
                  </select>
                  <input className="field bg-white" name="currentBalance" type="number" step="0.01" defaultValue={account.currentBalance === null ? "" : Number(account.currentBalance)} placeholder="Untracked balance" />
                  <input className="field bg-white" name="notes" defaultValue={account.notes ?? ""} placeholder="Notes" />
                  <label className="flex items-center gap-2 text-sm font-medium text-slate-700">
                    <input className="h-4 w-4 rounded border-line" name="active" type="checkbox" value="true" defaultChecked={account.active} />
                    Active
                  </label>
                  <button className="btn-secondary justify-self-start">Update account</button>
                </form>
              ))}
              {project.projectAccounts.length === 0 ? <p className="text-sm text-slate-600">No project accounts yet.</p> : null}
            </div>
          </div>
        </div>

        <div className="grid gap-4">
          <form className="panel grid gap-3 p-4 md:grid-cols-2" action="/review-funding-sources">
            <input type="hidden" name="projectId" value={project.id} />
            <select className="field" name="source" defaultValue={source}>
              <option value="">All funding sources</option>
              {fundingSourceOptions.map(([value, label]) => (
                <option key={value} value={value}>{label}</option>
              ))}
            </select>
            <select className="field" name="partnerId" defaultValue={partnerId}>
              <option value="">Any partner</option>
              {project.partners.map((partner) => (
                <option key={partner.id} value={partner.id}>{partner.partner.name}</option>
              ))}
            </select>
            <select className="field" name="accountId" defaultValue={accountId}>
              <option value="">Any account</option>
              {project.projectAccounts.map((account) => (
                <option key={account.id} value={account.id}>{account.accountName}</option>
              ))}
            </select>
            <select className="field" name="categoryId" defaultValue={categoryId}>
              <option value="">Any category</option>
              {categories.map((category) => (
                <option key={category.id} value={category.id}>{category.name}</option>
              ))}
            </select>
            <input className="field" name="from" type="date" defaultValue={from} />
            <input className="field" name="to" type="date" defaultValue={to} />
            <select className="field" name="reviewOnly" defaultValue={reviewOnly ? "1" : "0"}>
              <option value="1">Needs review only</option>
              <option value="0">All records</option>
            </select>
            <button className="btn-secondary md:col-span-2">Apply filters</button>
          </form>

          <section className="panel overflow-hidden">
            <div className="border-b border-line px-4 py-3">
              <h3 className="font-semibold text-ink">Expense Funding Records</h3>
            </div>
            <div className="overflow-x-auto">
              <table className="w-full min-w-[1180px]">
                <thead className="table-head">
                  <tr>
                    <th className="px-3 py-2">Date</th>
                    <th className="px-3 py-2">Expense</th>
                    <th className="px-3 py-2">Final Cost</th>
                    <th className="px-3 py-2">Current Funding</th>
                    <th className="px-3 py-2">Update</th>
                  </tr>
                </thead>
                <tbody>
                  {filteredExpenses.map((expense) => (
                    <tr key={expense.id}>
                      <td className="table-cell">{shortDate(expense.date)}</td>
                      <td className="table-cell">
                        <div className="font-medium text-ink">{expense.vendor ?? expense.description ?? "Expense"}</div>
                        <div className="text-xs text-slate-500">{expense.category?.name ?? "Uncategorized"} · {expense.paidBy?.partner.name ?? "No handler"}</div>
                      </td>
                      <td className="table-cell font-semibold text-ink">{currency(Number(expense.finalCost))}</td>
                      <td className="table-cell"><FundingSummary expense={expense} /></td>
                      <td className="table-cell align-top">
                        <form action={updateExpenseFundingAction} className="grid min-w-[360px] gap-3">
                          <input type="hidden" name="projectId" value={project.id} />
                          <input type="hidden" name="expenseId" value={expense.id} />
                          <FundingFields
                            partners={partnerOptions}
                            accounts={accountOptions}
                            defaultPaidById={expense.paidById}
                            defaultFundingSourceType={expense.fundingSourceType}
                            defaultFundingPartnerId={expense.fundingPartnerId}
                            defaultProjectAccountId={expense.projectAccountId}
                            defaultCreatesContributionCredit={expense.createsContributionCredit}
                            defaultContributionCreditPartnerId={expense.contributionCreditPartnerId}
                            defaultContributionCreditAmount={expense.contributionCreditAmount ? Number(expense.contributionCreditAmount) : ""}
                            defaultPaymentMemo={expense.paymentMemo}
                          />
                          <button className="btn-primary justify-self-start">Save funding</button>
                        </form>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
              {filteredExpenses.length === 0 ? <div className="p-6 text-sm text-slate-600">No funding records match these filters.</div> : null}
            </div>
          </section>
        </div>
      </section>
    </AppShell>
  );
}
