import { describe, expect, it } from "vitest";
import { filterExpenses, summarizeExpenses, weekKey, type ExpenseRecord } from "./expenseFilters";

function expense(overrides: Record<string, any>): ExpenseRecord {
  return {
    id: overrides.id ?? "expense",
    projectId: "project",
    categoryId: overrides.categoryId ?? "cat-home",
    paidById: overrides.paidById ?? "sujoy",
    fundingSourceType: overrides.fundingSourceType ?? "PARTNER_PERSONAL",
    fundingPartnerId: overrides.fundingPartnerId ?? overrides.paidById ?? "sujoy",
    projectAccountId: overrides.projectAccountId ?? null,
    createsContributionCredit: overrides.createsContributionCredit ?? true,
    contributionCreditPartnerId: overrides.contributionCreditPartnerId ?? overrides.paidById ?? "sujoy",
    contributionCreditAmount: overrides.contributionCreditAmount ?? overrides.finalCost ?? (270 as never),
    paymentMemo: overrides.paymentMemo ?? null,
    createdById: "admin",
    transactionKind: overrides.transactionKind ?? "STANDARD",
    workerId: overrides.workerId ?? null,
    workStartDate: overrides.workStartDate ?? null,
    workEndDate: overrides.workEndDate ?? null,
    actualPaidWorkDays: overrides.actualPaidWorkDays ?? null,
    laborPaymentBasis: overrides.laborPaymentBasis ?? null,
    laborPaymentStatus: overrides.laborPaymentStatus ?? null,
    workDescription: overrides.workDescription ?? null,
    workArea: overrides.workArea ?? null,
    createdBy: {
      id: "admin",
      name: "Admin",
      email: "admin@example.com",
      username: "admin",
      phone: null,
      passwordHash: "hash",
      status: "ACTIVE",
      role: "ADMIN",
      notes: null,
      lastLoginAt: null,
      createdAt: new Date("2026-06-10T00:00:00"),
      updatedAt: new Date("2026-06-10T00:00:00")
    },
    date: overrides.date ?? new Date("2026-06-10T00:00:00"),
    vendor: overrides.vendor ?? "Home Depot",
    description: overrides.description ?? "Materials",
    amount: overrides.amount ?? (300 as never),
    discount: overrides.discount ?? (30 as never),
    finalCost: overrides.finalCost ?? (270 as never),
    phase: overrides.phase ?? "RENOVATION_CAPITAL_IMPROVEMENT",
    recordType: overrides.recordType ?? "EXPENSE",
    splitMethod: overrides.splitMethod ?? "EQUAL",
    receiptUrl: null,
    archived: false,
    archivedAt: null,
    archivedById: null,
    updatedById: null,
    sourceSheet: null,
    sourceRow: null,
    sourceHash: null,
    notes: overrides.notes ?? null,
    createdAt: new Date("2026-06-10T00:00:00"),
    updatedAt: new Date("2026-06-10T00:00:00"),
    category: overrides.category ?? {
      id: overrides.categoryId ?? "cat-home",
      userId: "admin",
      projectId: "project",
      name: overrides.category?.name ?? "Home Depot Materials",
      type: "RENOVATION_EXPENSE",
      archived: false,
      createdAt: new Date("2026-06-10T00:00:00"),
      updatedAt: new Date("2026-06-10T00:00:00")
    },
    paidBy: overrides.paidBy ?? {
      id: overrides.paidById ?? "sujoy",
      projectId: "project",
      partnerId: "partner-sujoy",
      ownershipPercentage: 33.33 as never,
      active: true,
      notes: null,
      archivedAt: null,
      archivedById: null,
      createdAt: new Date("2026-06-10T00:00:00"),
      updatedAt: new Date("2026-06-10T00:00:00"),
      partner: {
        id: "partner-sujoy",
        userId: "admin",
        name: "Sujoy",
        phone: null,
        email: null,
        notes: null,
        createdAt: new Date("2026-06-10T00:00:00"),
        updatedAt: new Date("2026-06-10T00:00:00")
      }
    },
    fundingPartner: overrides.fundingPartner ?? null,
    projectAccount: overrides.projectAccount ?? null,
    contributionCreditPartner: overrides.contributionCreditPartner ?? null,
    worker: overrides.worker ?? null,
    shares: overrides.shares ?? [
      {
        id: "share-sujoy",
        expenseId: "expense",
        projectPartnerId: "sujoy",
        shareAmount: 90 as never,
        sharePercentage: 33.33 as never,
        projectPartner: {
          id: "sujoy",
          projectId: "project",
          partnerId: "partner-sujoy",
          ownershipPercentage: 33.33 as never,
          active: true,
          notes: null,
          archivedAt: null,
          archivedById: null,
          createdAt: new Date("2026-06-10T00:00:00"),
          updatedAt: new Date("2026-06-10T00:00:00"),
          partner: {
            id: "partner-sujoy",
            userId: "admin",
            name: "Sujoy",
            phone: null,
            email: null,
            notes: null,
            createdAt: new Date("2026-06-10T00:00:00"),
            updatedAt: new Date("2026-06-10T00:00:00")
          }
        }
      }
    ],
    receiptFiles: []
  } as ExpenseRecord;
}

const expenses = [
  expense({ id: "one", date: new Date("2026-06-10T00:00:00"), categoryId: "cat-home" }),
  expense({
    id: "two",
    date: new Date("2026-06-17T00:00:00"),
    categoryId: "cat-food",
    vendor: "Dunkin",
    finalCost: 40 as never,
    category: {
      id: "cat-food",
      userId: "admin",
      projectId: "project",
      name: "Worker Food",
      type: "RENOVATION_EXPENSE",
      archived: false,
      createdAt: new Date("2026-06-10T00:00:00"),
      updatedAt: new Date("2026-06-10T00:00:00")
    }
  })
];

describe("expense filters", () => {
  it("filters by day", () => {
    expect(filterExpenses(expenses, { day: "2026-06-10" }).map((item) => item.id)).toEqual(["one"]);
  });

  it("filters by week", () => {
    expect(filterExpenses(expenses, { week: weekKey(new Date("2026-06-17T00:00:00")) }).map((item) => item.id)).toEqual(["two"]);
  });

  it("filters by month and category", () => {
    expect(filterExpenses(expenses, { month: "2026-06", category: "cat-food" }).map((item) => item.id)).toEqual(["two"]);
  });

  it("summarizes filtered expenses", () => {
    const summary = summarizeExpenses(filterExpenses(expenses, { month: "2026-06" }));
    expect(summary.count).toBe(2);
    expect(summary.totalFinalCost).toBe(310);
    expect(summary.topCategory?.name).toBe("Home Depot Materials");
  });
});
