export const REPORT_MONTHS = [
  "يناير",
  "فبراير",
  "مارس",
  "أبريل",
  "مايو",
  "يونيو",
  "يوليو",
  "أغسطس",
  "سبتمبر",
  "أكتوبر",
  "نوفمبر",
  "ديسمبر"
] as const;

export type ReportStatusFilter =
  | "all"
  | "payments_paid"
  | "payments_unpaid"
  | "transfers_completed"
  | "missing_receipt";

export type ReportFilters = {
  month: number | null;
  sponsorId: string | null;
  orphanId: string | null;
  status: ReportStatusFilter;
};

export type ReportPayment = {
  id: string;
  sponsorshipId: string;
  sponsorId: string;
  sponsorName: string;
  sponsorPhone: string | null;
  orphanId: string;
  orphanName: string;
  caseNumber: string;
  year: number;
  month: number;
  expectedAmount: number;
  receivedAmount: number;
  paymentStatus: "paid" | "unpaid";
  paymentDate: string | null;
};

export type ReportTransfer = {
  id: string;
  orphanId: string;
  orphanName: string;
  caseNumber: string;
  sponsorIds: string[];
  sponsorNames: string[];
  year: number;
  month: number;
  amount: number;
  transferDate: string;
  hasReceipt: boolean;
};

export type ReportSponsorship = {
  id: string;
  sponsorId: string;
  sponsorName: string;
  orphanId: string;
  orphanName: string;
  caseNumber: string;
  monthlyAmount: number;
  status: "pending" | "active" | "paused" | "ended" | "rejected";
  startDate: string;
  endDate: string | null;
};

export type ReportOrphan = {
  id: string;
  name: string;
  caseNumber: string;
  status: "available" | "partially_covered" | "fully_covered" | "paused" | "archived";
  monthlyNeed: number | null;
  coveredAmount: number;
  missingItems: string[];
  missingDocumentItems: string[];
  completionPercentage: number;
};

export type ReportOrphanMonthlySnapshot = {
  year: number;
  month: number;
  orphanId: string;
  name: string;
  caseNumber: string;
  monthlyNeed: number | null;
  status: "available" | "partially_covered" | "fully_covered" | "paused" | "archived";
  createdAt: string;
};

export type ReportSponsorshipMonthlySnapshot = {
  year: number;
  month: number;
  sponsorshipId: string;
  sponsorId: string;
  sponsorName: string;
  orphanId: string;
  orphanName: string;
  caseNumber: string;
  monthlyAmount: number;
  startDate: string;
  endDate: string | null;
};

export type ReportingPeriod = {
  year: number;
  month: number;
};

export type ReportDataset = {
  year: number;
  defaultComparisonMonth: number;
  payments: ReportPayment[];
  transfers: ReportTransfer[];
  sponsorships: ReportSponsorship[];
  orphans: ReportOrphan[];
  sponsors: Array<{ id: string; name: string }>;
  history: {
    periods: ReportingPeriod[];
    orphanSnapshots: ReportOrphanMonthlySnapshot[];
    sponsorshipSnapshots: ReportSponsorshipMonthlySnapshot[];
  };
};

export type MonthlyReportPoint = {
  month: number;
  monthLabel: string;
  expectedAmount: number;
  receivedAmount: number;
  unpaidAmount: number;
  transferAmount: number;
  paymentCount: number;
  transferCount: number;
  paidSponsors: number;
  unpaidSponsors: number;
};

export type ReconciliationStatus =
  | "complete"
  | "payment_missing_transfer"
  | "unpaid"
  | "transfer_exists";

export type ReconciliationRow = {
  sponsorshipId: string;
  sponsorId: string;
  sponsorName: string;
  orphanId: string;
  orphanName: string;
  caseNumber: string;
  months: Array<{
    month: number;
    label: string;
    status: ReconciliationStatus;
    hasReceipt: boolean;
  }>;
};

export type HistoricalMonthlyPoint = {
  year: number;
  month: number;
  monthLabel: string;
  captured: boolean;
  sponsoredOrphans: number;
  newOrphans: number;
  activeSponsors: number;
  requiredAmount: number;
  commitmentAmount: number;
  paymentAmount: number;
  transferAmount: number;
};

export type HistoricalAnnualPoint = {
  year: number;
  yearLabel: string;
  sponsoredOrphans: number;
  newOrphans: number;
  activeSponsors: number;
  requiredAmount: number;
  commitmentAmount: number;
  paymentAmount: number;
  transferAmount: number;
};

export type HistoricalMetricKey =
  | "sponsoredOrphans"
  | "newOrphans"
  | "activeSponsors"
  | "requiredAmount"
  | "commitmentAmount"
  | "paymentAmount"
  | "transferAmount";

export type HistoricalComparison = {
  current: number;
  previous: number;
  difference: number;
  percentage: number | null;
};

export type ReportAnalytics = {
  payments: ReportPayment[];
  transfers: ReportTransfer[];
  sponsorships: ReportSponsorship[];
  orphans: ReportOrphan[];
  kpis: {
    expectedAmount: number;
    receivedAmount: number;
    unpaidAmount: number;
    transferAmount: number;
    paidSponsors: number;
    unpaidSponsors: number;
    activeCases: number;
    missingReceipts: number;
  };
  paymentStatus: Array<{ key: "paid" | "unpaid"; label: string; value: number }>;
  transferCoverage: Array<{ key: "transferred" | "not_transferred"; label: string; value: number }>;
  receiptStatus: Array<{ key: "with_receipt" | "missing_receipt"; label: string; value: number }>;
  annualMonthly: MonthlyReportPoint[];
  periodMonthly: MonthlyReportPoint[];
  transfersBySponsor: Array<{ id: string; label: string; value: number }>;
  transfersByOrphan: Array<{ id: string; label: string; value: number }>;
  commitmentsBySponsor: Array<{ id: string; label: string; value: number }>;
  orphanCountBySponsor: Array<{ id: string; label: string; value: number }>;
  sponsorshipStatus: Array<{ key: "active" | "stopped"; label: string; value: number }>;
  coverageStatus: Array<{ key: "full" | "partial" | "uncovered"; label: string; value: number }>;
  coverageTotals: {
    need: number;
    covered: number;
    remaining: number;
  };
  orphanCoverage: Array<{
    id: string;
    name: string;
    caseNumber: string;
    need: number | null;
    covered: number;
    remaining: number | null;
    percentage: number | null;
    category: "full" | "partial" | "uncovered";
  }>;
  missingData: Array<{ label: string; value: number }>;
  orphanCompletion: ReportOrphan[];
  reconciliation: ReconciliationRow[];
  annualTotals: {
    expectedAmount: number;
    receivedAmount: number;
    unpaidAmount: number;
    transferAmount: number;
  };
  monthChange: {
    month: number;
    payments: number | null;
    transfers: number | null;
  };
  history: {
    selectedMonth: number;
    current: HistoricalMonthlyPoint;
    previous: HistoricalMonthlyPoint;
    monthly: HistoricalMonthlyPoint[];
    monthlyComparisons: Array<{
      point: HistoricalMonthlyPoint;
      previous: HistoricalMonthlyPoint;
      comparisons: Record<HistoricalMetricKey, HistoricalComparison>;
    }>;
    annual: HistoricalAnnualPoint[];
    comparisons: Record<HistoricalMetricKey, HistoricalComparison>;
  };
};

function safeAmount(value: number): number {
  return Number.isFinite(value) ? Math.max(0, value) : 0;
}

function sumBy<T>(items: T[], value: (item: T) => number): number {
  return items.reduce((total, item) => total + safeAmount(value(item)), 0);
}

function monthMatches(month: number, selectedMonth: number | null): boolean {
  return selectedMonth === null || month === selectedMonth;
}

function sponsorMatches(sponsorId: string, selectedSponsor: string | null): boolean {
  return selectedSponsor === null || sponsorId === selectedSponsor;
}

function orphanMatches(orphanId: string, selectedOrphan: string | null): boolean {
  return selectedOrphan === null || orphanId === selectedOrphan;
}

function paidAndUnpaidSponsorCounts(payments: ReportPayment[]): { paid: number; unpaid: number } {
  const state = new Map<string, boolean>();

  for (const payment of payments) {
    const prior = state.get(payment.sponsorId);
    state.set(payment.sponsorId, (prior ?? true) && payment.paymentStatus === "paid");
  }

  let paid = 0;
  let unpaid = 0;
  for (const isPaid of state.values()) {
    if (isPaid) paid += 1;
    else unpaid += 1;
  }
  return { paid, unpaid };
}

function buildMonthlySeries(payments: ReportPayment[], transfers: ReportTransfer[]): MonthlyReportPoint[] {
  return REPORT_MONTHS.map((monthLabel, index) => {
    const month = index + 1;
    const monthPayments = payments.filter((item) => item.month === month);
    const monthTransfers = transfers.filter((item) => item.month === month);
    const sponsorCounts = paidAndUnpaidSponsorCounts(monthPayments);
    const expectedAmount = sumBy(monthPayments, (item) => item.expectedAmount);
    const receivedAmount = sumBy(monthPayments, (item) => item.receivedAmount);

    return {
      month,
      monthLabel,
      expectedAmount,
      receivedAmount,
      unpaidAmount: sumBy(monthPayments, (item) => item.expectedAmount - item.receivedAmount),
      transferAmount: sumBy(monthTransfers, (item) => item.amount),
      paymentCount: monthPayments.length,
      transferCount: monthTransfers.length,
      paidSponsors: sponsorCounts.paid,
      unpaidSponsors: sponsorCounts.unpaid
    };
  });
}

function groupValues<T>(
  items: T[],
  entries: (item: T) => Array<{ id: string; label: string; value: number }>
): Array<{ id: string; label: string; value: number }> {
  const grouped = new Map<string, { id: string; label: string; value: number }>();

  for (const item of items) {
    for (const entry of entries(item)) {
      const current = grouped.get(entry.id);
      if (current) current.value += safeAmount(entry.value);
      else grouped.set(entry.id, { ...entry, value: safeAmount(entry.value) });
    }
  }

  return [...grouped.values()].sort((left, right) => right.value - left.value || left.label.localeCompare(right.label, "ar"));
}

function isSponsorshipInPeriod(sponsorship: ReportSponsorship, year: number, month: number | null): boolean {
  const start = month === null ? `${year}-01-01` : `${year}-${String(month).padStart(2, "0")}-01`;
  const end =
    month === null
      ? `${year}-12-31`
      : new Date(Date.UTC(year, month, 0)).toISOString().slice(0, 10);

  return sponsorship.startDate <= end && (!sponsorship.endDate || sponsorship.endDate >= start);
}

function percentageChange(current: number, previous: number): number | null {
  if (previous === 0) return current === 0 ? 0 : null;
  return Math.round(((current - previous) / previous) * 1000) / 10;
}

const HISTORICAL_METRICS: HistoricalMetricKey[] = [
  "sponsoredOrphans",
  "newOrphans",
  "activeSponsors",
  "requiredAmount",
  "commitmentAmount",
  "paymentAmount",
  "transferAmount"
];

function periodKey(year: number, month: number): string {
  return `${year}-${String(month).padStart(2, "0")}`;
}

function buildHistoricalMonthlyPoint(
  dataset: ReportDataset,
  filters: ReportFilters,
  year: number,
  month: number,
  capturedPeriods: Set<string>
): HistoricalMonthlyPoint {
  const orphanSnapshots = dataset.history.orphanSnapshots.filter(
    (item) =>
      item.year === year &&
      item.month === month &&
      orphanMatches(item.orphanId, filters.orphanId)
  );
  const sponsorshipSnapshots = dataset.history.sponsorshipSnapshots.filter(
    (item) =>
      item.year === year &&
      item.month === month &&
      sponsorMatches(item.sponsorId, filters.sponsorId) &&
      orphanMatches(item.orphanId, filters.orphanId)
  );
  const sponsoredOrphanIds = new Set(sponsorshipSnapshots.map((item) => item.orphanId));
  const activeSponsorIds = new Set(sponsorshipSnapshots.map((item) => item.sponsorId));
  const newOrphanScope =
    filters.sponsorId === null
      ? orphanSnapshots
      : orphanSnapshots.filter((item) => sponsoredOrphanIds.has(item.orphanId));

  const periodPayments = filterPaymentsByStatus(
    dataset.payments.filter(
      (item) =>
        item.year === year &&
        item.month === month &&
        sponsorMatches(item.sponsorId, filters.sponsorId) &&
        orphanMatches(item.orphanId, filters.orphanId)
    ),
    filters.status
  );
  const periodTransfers = filterTransfersByStatus(
    dataset.transfers.filter(
      (item) =>
        item.year === year &&
        item.month === month &&
        (filters.sponsorId === null || item.sponsorIds.includes(filters.sponsorId)) &&
        orphanMatches(item.orphanId, filters.orphanId)
    ),
    filters.status
  );

  return {
    year,
    month,
    monthLabel: REPORT_MONTHS[month - 1],
    captured: capturedPeriods.has(periodKey(year, month)),
    sponsoredOrphans: sponsoredOrphanIds.size,
    newOrphans: newOrphanScope.filter((item) => {
      const createdAt = new Date(item.createdAt);
      return createdAt.getUTCFullYear() === year && createdAt.getUTCMonth() + 1 === month;
    }).length,
    activeSponsors: activeSponsorIds.size,
    requiredAmount: sumBy(
      orphanSnapshots.filter((item) => sponsoredOrphanIds.has(item.orphanId)),
      (item) => item.monthlyNeed ?? 0
    ),
    commitmentAmount: sumBy(sponsorshipSnapshots, (item) => item.monthlyAmount),
    paymentAmount: sumBy(periodPayments, (item) => item.receivedAmount),
    transferAmount: sumBy(periodTransfers, (item) => item.amount)
  };
}

function buildHistoricalComparison(
  current: HistoricalMonthlyPoint,
  previous: HistoricalMonthlyPoint
): Record<HistoricalMetricKey, HistoricalComparison> {
  return Object.fromEntries(
    HISTORICAL_METRICS.map((metric) => {
      const currentValue = current[metric];
      const previousValue = previous[metric];
      return [
        metric,
        {
          current: currentValue,
          previous: previousValue,
          difference: currentValue - previousValue,
          percentage: percentageChange(currentValue, previousValue)
        }
      ];
    })
  ) as Record<HistoricalMetricKey, HistoricalComparison>;
}

function coverageCategory(orphan: ReportOrphan): "full" | "partial" | "uncovered" {
  const covered = safeAmount(orphan.coveredAmount);
  if (orphan.monthlyNeed !== null && orphan.monthlyNeed > 0 && covered >= orphan.monthlyNeed) return "full";
  if (covered > 0) return "partial";
  return "uncovered";
}

function filterPaymentsByStatus(payments: ReportPayment[], status: ReportStatusFilter): ReportPayment[] {
  if (status === "payments_paid") return payments.filter((item) => item.paymentStatus === "paid");
  if (status === "payments_unpaid") return payments.filter((item) => item.paymentStatus === "unpaid");
  return payments;
}

function filterTransfersByStatus(transfers: ReportTransfer[], status: ReportStatusFilter): ReportTransfer[] {
  if (status === "transfers_completed") return transfers.filter((item) => item.hasReceipt);
  if (status === "missing_receipt") return transfers.filter((item) => !item.hasReceipt);
  return transfers;
}

export function buildReportAnalytics(dataset: ReportDataset, filters: ReportFilters): ReportAnalytics {
  const entityPayments = dataset.payments.filter(
    (item) =>
      item.year === dataset.year &&
      sponsorMatches(item.sponsorId, filters.sponsorId) &&
      orphanMatches(item.orphanId, filters.orphanId)
  );
  const entityTransfers = dataset.transfers.filter(
    (item) =>
      item.year === dataset.year &&
      (filters.sponsorId === null || item.sponsorIds.includes(filters.sponsorId)) &&
      orphanMatches(item.orphanId, filters.orphanId)
  );

  const annualPayments = filterPaymentsByStatus(entityPayments, filters.status);
  const annualTransfers = filterTransfersByStatus(entityTransfers, filters.status);
  const payments = annualPayments.filter((item) => monthMatches(item.month, filters.month));
  const transfers = annualTransfers.filter((item) => monthMatches(item.month, filters.month));

  const sponsorships = dataset.sponsorships.filter(
    (item) =>
      sponsorMatches(item.sponsorId, filters.sponsorId) &&
      orphanMatches(item.orphanId, filters.orphanId) &&
      isSponsorshipInPeriod(item, dataset.year, filters.month)
  );
  const sponsorOrphanIds =
    filters.sponsorId === null
      ? null
      : new Set(
          dataset.sponsorships
            .filter((item) => item.sponsorId === filters.sponsorId)
            .map((item) => item.orphanId)
        );
  const orphans = dataset.orphans.filter(
    (item) =>
      orphanMatches(item.id, filters.orphanId) &&
      (sponsorOrphanIds === null || sponsorOrphanIds.has(item.id))
  );

  const sponsorCounts = paidAndUnpaidSponsorCounts(payments);
  const expectedAmount = sumBy(payments, (item) => item.expectedAmount);
  const receivedAmount = sumBy(payments, (item) => item.receivedAmount);
  const unpaidAmount = sumBy(payments, (item) => item.expectedAmount - item.receivedAmount);
  const transferAmount = sumBy(transfers, (item) => item.amount);
  const paidPaymentCount = payments.filter((item) => item.paymentStatus === "paid").length;
  const unpaidPaymentCount = payments.length - paidPaymentCount;
  const transferredOrphanIds = new Set(transfers.map((item) => item.orphanId));
  const activeSponsorships = sponsorships.filter((item) => item.status === "active");

  const annualMonthly = buildMonthlySeries(annualPayments, annualTransfers);
  const periodMonthly =
    filters.month === null
      ? annualMonthly
      : annualMonthly.filter((item) => item.month === filters.month);

  const transfersBySponsor = groupValues(transfers, (item) =>
    item.sponsorIds.map((id, index) => ({
      id,
      label: item.sponsorNames[index] ?? "متبرع غير معروف",
      value: 1
    }))
  );
  const transfersByOrphan = groupValues(transfers, (item) => [
    { id: item.orphanId, label: item.orphanName, value: 1 }
  ]);
  const commitmentsBySponsor = groupValues(activeSponsorships, (item) => [
    { id: item.sponsorId, label: item.sponsorName, value: item.monthlyAmount }
  ]);
  const orphanCountBySponsor = groupValues(
    [...new Map(activeSponsorships.map((item) => [`${item.sponsorId}:${item.orphanId}`, item])).values()],
    (item) => [{ id: item.sponsorId, label: item.sponsorName, value: 1 }]
  );

  const coverageCounts = { full: 0, partial: 0, uncovered: 0 };
  const orphanCoverage = orphans
    .map((orphan) => {
      const category = coverageCategory(orphan);
      coverageCounts[category] += 1;
      const need = orphan.monthlyNeed === null ? null : safeAmount(orphan.monthlyNeed);
      const covered = safeAmount(orphan.coveredAmount);
      const remaining = need === null ? null : Math.max(0, need - covered);
      const percentage = need === null || need === 0 ? null : Math.min(100, Math.round((covered / need) * 100));
      return {
        id: orphan.id,
        name: orphan.name,
        caseNumber: orphan.caseNumber,
        need,
        covered,
        remaining,
        percentage,
        category
      };
    })
    .sort((left, right) => (left.percentage ?? -1) - (right.percentage ?? -1) || left.name.localeCompare(right.name, "ar"));

  const missingDataMap = new Map<string, number>();
  for (const orphan of orphans) {
    for (const item of orphan.missingItems) {
      missingDataMap.set(item, (missingDataMap.get(item) ?? 0) + 1);
    }
  }
  const missingData = [...missingDataMap.entries()]
    .map(([label, value]) => ({ label, value }))
    .sort((left, right) => right.value - left.value || left.label.localeCompare(right.label, "ar"));

  const displayMonths = filters.month === null ? REPORT_MONTHS.map((_, index) => index + 1) : [filters.month];
  const reconciliation = sponsorships.map((sponsorship) => {
    const months = displayMonths.map((month) => {
      const payment = entityPayments.find(
        (item) => item.sponsorshipId === sponsorship.id && item.month === month
      );
      const matchingTransfers = entityTransfers.filter(
        (item) =>
          item.month === month &&
          item.orphanId === sponsorship.orphanId &&
          item.sponsorIds.includes(sponsorship.sponsorId)
      );
      const hasTransfer = matchingTransfers.length > 0;
      const hasCompletedTransfer = matchingTransfers.some((item) => item.hasReceipt);
      const sponsorPaid = payment?.paymentStatus === "paid";
      let status: ReconciliationStatus = "unpaid";

      if (sponsorPaid && hasCompletedTransfer) status = "complete";
      else if (sponsorPaid && !hasTransfer) status = "payment_missing_transfer";
      else if (hasTransfer) status = "transfer_exists";

      return {
        month,
        label: REPORT_MONTHS[month - 1],
        status,
        hasReceipt: hasCompletedTransfer
      };
    });

    return {
      sponsorshipId: sponsorship.id,
      sponsorId: sponsorship.sponsorId,
      sponsorName: sponsorship.sponsorName,
      orphanId: sponsorship.orphanId,
      orphanName: sponsorship.orphanName,
      caseNumber: sponsorship.caseNumber,
      months
    };
  });

  const annualExpected = sumBy(annualPayments, (item) => item.expectedAmount);
  const annualReceived = sumBy(annualPayments, (item) => item.receivedAmount);
  const annualTransfersTotal = sumBy(annualTransfers, (item) => item.amount);
  const activityMonths = annualMonthly.filter(
    (item) => item.expectedAmount > 0 || item.receivedAmount > 0 || item.transferAmount > 0
  );
  const comparisonMonth = filters.month ?? activityMonths.at(-1)?.month ?? 12;
  const currentMonth = annualMonthly[comparisonMonth - 1];
  const previousMonth = comparisonMonth > 1 ? annualMonthly[comparisonMonth - 2] : null;
  const capturedPeriods = new Set(
    dataset.history.periods.map((period) => periodKey(period.year, period.month))
  );
  const capturedMonths = dataset.history.periods
    .filter((period) => period.year === dataset.year)
    .map((period) => period.month)
    .sort((left, right) => left - right);
  const selectedHistoryMonth =
    filters.month ?? capturedMonths.at(-1) ?? dataset.defaultComparisonMonth;
  const historyCurrent = buildHistoricalMonthlyPoint(
    dataset,
    filters,
    dataset.year,
    selectedHistoryMonth,
    capturedPeriods
  );
  const previousHistoryYear =
    selectedHistoryMonth === 1 ? dataset.year - 1 : dataset.year;
  const previousHistoryMonth =
    selectedHistoryMonth === 1 ? 12 : selectedHistoryMonth - 1;
  const historyPrevious = buildHistoricalMonthlyPoint(
    dataset,
    filters,
    previousHistoryYear,
    previousHistoryMonth,
    capturedPeriods
  );
  const historicalMonthly = capturedMonths.map((historyMonth) =>
    buildHistoricalMonthlyPoint(
      dataset,
      filters,
      dataset.year,
      historyMonth,
      capturedPeriods
    )
  );
  const historicalMonthlyComparisons = historicalMonthly.map((point) => {
    const previousYear = point.month === 1 ? point.year - 1 : point.year;
    const previousPointMonth = point.month === 1 ? 12 : point.month - 1;
    const previousPoint = buildHistoricalMonthlyPoint(
      dataset,
      filters,
      previousYear,
      previousPointMonth,
      capturedPeriods
    );

    return {
      point,
      previous: previousPoint,
      comparisons: buildHistoricalComparison(point, previousPoint)
    };
  });
  const historicalYears = new Set<number>([
    dataset.year,
    ...dataset.history.periods.map((period) => period.year),
    ...dataset.payments.map((item) => item.year),
    ...dataset.transfers.map((item) => item.year)
  ]);
  const historicalAnnual = [...historicalYears]
    .sort((left, right) => left - right)
    .map((historyYear): HistoricalAnnualPoint => {
      const yearMonths = dataset.history.periods
        .filter((period) => period.year === historyYear)
        .map((period) => period.month)
        .sort((left, right) => left - right);
      const points = yearMonths.map((historyMonth) =>
        buildHistoricalMonthlyPoint(
          dataset,
          filters,
          historyYear,
          historyMonth,
          capturedPeriods
        )
      );
      const latest = points.at(-1) ?? buildHistoricalMonthlyPoint(
        dataset,
        filters,
        historyYear,
        12,
        capturedPeriods
      );

      return {
        year: historyYear,
        yearLabel: String(historyYear),
        sponsoredOrphans: latest.sponsoredOrphans,
        newOrphans: sumBy(points, (point) => point.newOrphans),
        activeSponsors: latest.activeSponsors,
        requiredAmount: latest.requiredAmount,
        commitmentAmount: latest.commitmentAmount,
        paymentAmount: sumBy(points, (point) => point.paymentAmount),
        transferAmount: sumBy(points, (point) => point.transferAmount)
      };
    });

  return {
    payments,
    transfers,
    sponsorships,
    orphans,
    kpis: {
      expectedAmount,
      receivedAmount,
      unpaidAmount,
      transferAmount,
      paidSponsors: sponsorCounts.paid,
      unpaidSponsors: sponsorCounts.unpaid,
      activeCases: orphans.filter((item) => item.status !== "paused" && item.status !== "archived").length,
      missingReceipts: transfers.filter((item) => !item.hasReceipt).length
    },
    paymentStatus: [
      { key: "paid", label: "مدفوع", value: paidPaymentCount },
      { key: "unpaid", label: "غير مدفوع", value: unpaidPaymentCount }
    ],
    transferCoverage: [
      { key: "transferred", label: "تم التحويل", value: transferredOrphanIds.size },
      {
        key: "not_transferred",
        label: "لم يتم التحويل",
        value: Math.max(0, orphans.length - transferredOrphanIds.size)
      }
    ],
    receiptStatus: [
      { key: "with_receipt", label: "بإيصال", value: transfers.filter((item) => item.hasReceipt).length },
      { key: "missing_receipt", label: "بدون إيصال", value: transfers.filter((item) => !item.hasReceipt).length }
    ],
    annualMonthly,
    periodMonthly,
    transfersBySponsor,
    transfersByOrphan,
    commitmentsBySponsor,
    orphanCountBySponsor,
    sponsorshipStatus: [
      { key: "active", label: "نشطة", value: activeSponsorships.length },
      { key: "stopped", label: "موقوفة أو منتهية", value: sponsorships.length - activeSponsorships.length }
    ],
    coverageStatus: [
      { key: "full", label: "مغطاة بالكامل", value: coverageCounts.full },
      { key: "partial", label: "مغطاة جزئياً", value: coverageCounts.partial },
      { key: "uncovered", label: "غير مغطاة", value: coverageCounts.uncovered }
    ],
    coverageTotals: {
      need: sumBy(orphans, (item) => item.monthlyNeed ?? 0),
      covered: sumBy(orphans, (item) =>
        item.monthlyNeed === null ? item.coveredAmount : Math.min(item.monthlyNeed, item.coveredAmount)
      ),
      remaining: sumBy(orphans, (item) =>
        item.monthlyNeed === null ? 0 : Math.max(0, item.monthlyNeed - item.coveredAmount)
      )
    },
    orphanCoverage,
    missingData,
    orphanCompletion: [...orphans].sort(
      (left, right) => left.completionPercentage - right.completionPercentage || left.name.localeCompare(right.name, "ar")
    ),
    reconciliation,
    annualTotals: {
      expectedAmount: annualExpected,
      receivedAmount: annualReceived,
      unpaidAmount: sumBy(annualPayments, (item) => item.expectedAmount - item.receivedAmount),
      transferAmount: annualTransfersTotal
    },
    monthChange: {
      month: comparisonMonth,
      payments: previousMonth ? percentageChange(currentMonth.receivedAmount, previousMonth.receivedAmount) : null,
      transfers: previousMonth ? percentageChange(currentMonth.transferAmount, previousMonth.transferAmount) : null
    },
    history: {
      selectedMonth: selectedHistoryMonth,
      current: historyCurrent,
      previous: historyPrevious,
      monthly: historicalMonthly,
      monthlyComparisons: historicalMonthlyComparisons,
      annual: historicalAnnual,
      comparisons: buildHistoricalComparison(historyCurrent, historyPrevious)
    }
  };
}

export function formatReportAmount(value: number): string {
  return `${new Intl.NumberFormat("en-US", { maximumFractionDigits: 0 }).format(safeAmount(value))} ج.س`;
}

export function formatReportCount(value: number): string {
  return new Intl.NumberFormat("en-US", { maximumFractionDigits: 0 }).format(Math.max(0, value));
}
