import { Fragment, useMemo, useState } from "react";
import { ChevronDown, ChevronUp, FileSpreadsheet, FileText } from "lucide-react";

import type {
  BreakdownRow,
  DayDetailsResponse,
  PercentageRow,
  TableReportResponse,
  UserReportSummary,
  UserScopedTableReport,
} from "../../api/reports";
import { useTranslation } from "../../hooks/useTranslation";
import { Modal } from "../Modal";

const PERSIAN_DIGITS = "۰۱۲۳۴۵۶۷۸۹";

const toPersianDigits = (value: string) =>
  value.replace(/\d/g, (digit) => PERSIAN_DIGITS[Number(digit)] || digit);

const localizeDigits = (value: string, lang: "en" | "fa") => (lang === "fa" ? toPersianDigits(value) : value);

const shouldTrimCurrencyDecimals = (currency?: string | null) => {
  const normalized = (currency || "").toUpperCase();
  return normalized === "IRR" || normalized === "IRT";
};

const formatAmount = (value: string, lang: "en" | "fa", currency?: string | null) => {
  const trimmed = value.trim();
  if (!trimmed) return trimmed;

  const numeric = Number(trimmed.replace(/,/g, ""));
  if (Number.isNaN(numeric)) return localizeDigits(trimmed, lang);

  const [integerPart, fractionalPart] = trimmed.replace(/,/g, "").split(".");
  const grouped = Math.abs(Number(integerPart)).toLocaleString("en-US");
  const signed = trimmed.startsWith("-") ? `-${grouped}` : grouped;
  const normalizedFraction =
    fractionalPart && !shouldTrimCurrencyDecimals(currency) ? fractionalPart.replace(/0+$/, "") : "";
  const normalized = normalizedFraction ? `${signed}.${normalizedFraction}` : signed;
  return localizeDigits(normalized, lang);
};

const currencyLabel = (currency: string, lang: "en" | "fa") => {
  const normalized = currency.toUpperCase();
  if (lang !== "fa") return normalized;

  return (
    {
      USD: "دلار آمریکا",
      EUR: "یورو",
      GBP: "پوند",
      IRR: "ریال",
      IRT: "تومان",
      AED: "درهم",
      TRY: "لیر",
    }[normalized] || normalized
  );
};

const formatMoneyTotals = (totals: { currency: string; amount: string }[], lang: "en" | "fa") => {
  if (!totals.length) return "-";
  return totals
    .map((item) => `${formatAmount(item.amount, lang, item.currency)} ${currencyLabel(item.currency, lang)}`)
    .join(" | ");
};

const formatHourlyRate = (rate: { currency: string; amount: string } | null, lang: "en" | "fa") => {
  if (!rate) return "-";
  return `${formatAmount(rate.amount, lang, rate.currency)} ${currencyLabel(rate.currency, lang)}`;
};

const formatDisplayDate = (value: string, lang: "en" | "fa") => {
  const parsed = new Date(`${value}T00:00:00`);
  return new Intl.DateTimeFormat(lang === "fa" ? "fa-IR" : "en-US", {
    dateStyle: "medium",
  }).format(parsed);
};

const formatRateToLabel = (value: string | null | undefined, lang: "en" | "fa", nowLabel: string) => {
  if (!value) return nowLabel;
  return formatDisplayDate(value, lang);
};

const formatDisplayDateTime = (value: string, lang: "en" | "fa") => {
  const parsed = new Date(value);
  return new Intl.DateTimeFormat(lang === "fa" ? "fa-IR" : "en-US", {
    dateStyle: "medium",
    timeStyle: "short",
  }).format(parsed);
};

const percentageMap = (rows?: PercentageRow[]) =>
  new Map((rows || []).map((row) => [row.id, `${formatAmount(row.percentage, "en")}%`]));

function LoadingBlock({ className }: { className: string }) {
  return <div className={`animate-pulse rounded-2xl bg-slate-200/80 dark:bg-slate-800/80 ${className}`} />;
}

function ReportsTableSkeleton({ labels }: { labels: Record<string, string> }) {
  return (
    <div className="space-y-4">
      <div className="rounded-3xl border border-slate-200 bg-white p-4 shadow-sm dark:border-slate-800 dark:bg-slate-900 sm:p-5">
        <div className="mb-4 flex items-center justify-between gap-3">
          <div className="text-sm font-semibold text-slate-900 dark:text-white">{labels.userSummaryTitle}</div>
          <div className="text-xs text-slate-500 dark:text-slate-400">{labels.loading}</div>
        </div>
        <div className="space-y-3">
          <LoadingBlock className="h-11 w-full" />
          <LoadingBlock className="h-11 w-full" />
          <LoadingBlock className="h-11 w-full" />
        </div>
      </div>

      <div className="flex flex-col gap-2 sm:flex-row sm:justify-end">
        <LoadingBlock className="h-11 w-full sm:w-40" />
        <LoadingBlock className="h-11 w-full sm:w-40" />
      </div>

      <div className="grid gap-4 xl:grid-cols-3">
        <div className="rounded-3xl border border-slate-200 bg-white p-4 shadow-sm dark:border-slate-800 dark:bg-slate-900 sm:p-5">
          <LoadingBlock className="mb-4 h-5 w-36" />
          <LoadingBlock className="h-44 w-full" />
        </div>
        <div className="rounded-3xl border border-slate-200 bg-white p-4 shadow-sm dark:border-slate-800 dark:bg-slate-900 sm:p-5">
          <LoadingBlock className="mb-4 h-5 w-36" />
          <LoadingBlock className="h-44 w-full" />
        </div>
        <div className="rounded-3xl border border-slate-200 bg-white p-4 shadow-sm dark:border-slate-800 dark:bg-slate-900 sm:p-5">
          <LoadingBlock className="mb-4 h-5 w-36" />
          <LoadingBlock className="h-44 w-full" />
        </div>
      </div>
    </div>
  );
}

function BreakdownTable({
  title,
  rows,
  hourPercentages,
  incomePercentages,
  labels,
  lang,
  financialOnly,
}: {
  title: string;
  rows: BreakdownRow[];
  hourPercentages?: PercentageRow[];
  incomePercentages?: PercentageRow[];
  labels: Record<string, string>;
  lang: "en" | "fa";
  financialOnly: boolean;
}) {
  const hourPercentageById = useMemo(() => percentageMap(hourPercentages), [hourPercentages]);
  const incomePercentageById = useMemo(() => percentageMap(incomePercentages), [incomePercentages]);

  return (
    <div className="rounded-3xl border border-slate-200 bg-white p-4 shadow-sm dark:border-slate-800 dark:bg-slate-900 sm:p-5">
      <div className="mb-4 text-sm font-semibold text-slate-900 dark:text-white">{title}</div>

      <div className="space-y-3 sm:hidden">
        {rows.map((row) => (
          <div key={row.id} className="rounded-2xl border border-slate-200 bg-slate-50/80 p-3 dark:border-slate-800 dark:bg-slate-950/70">
            <div className="text-sm font-semibold text-slate-900 dark:text-white">{row.name}</div>
            <div className="mt-3 grid grid-cols-2 gap-3 text-xs text-slate-600 dark:text-slate-300">
              <div>
                <div className="mb-1 text-[11px] uppercase tracking-[0.12em] text-slate-400 dark:text-slate-500">{labels.workingHours}</div>
                <div className="font-medium">{localizeDigits(row.billable_duration, lang)}</div>
              </div>
              <div>
                <div className="mb-1 text-[11px] uppercase tracking-[0.12em] text-slate-400 dark:text-slate-500">{labels.hourPercentage}</div>
                <div className="font-medium">{localizeDigits(hourPercentageById.get(row.id) || "0%", lang)}</div>
              </div>
              {!financialOnly ? (
                <>
                  <div>
                    <div className="mb-1 text-[11px] uppercase tracking-[0.12em] text-slate-400 dark:text-slate-500">{labels.nonWorkingHours}</div>
                    <div className="font-medium">{localizeDigits(row.non_billable_duration, lang)}</div>
                  </div>
                  <div>
                    <div className="mb-1 text-[11px] uppercase tracking-[0.12em] text-slate-400 dark:text-slate-500">{labels.totalHours}</div>
                    <div className="font-medium">{localizeDigits(row.total_duration, lang)}</div>
                  </div>
                </>
              ) : null}
              <div className={financialOnly ? "" : "col-span-2"}>
                <div className="mb-1 text-[11px] uppercase tracking-[0.12em] text-slate-400 dark:text-slate-500">{labels.totalIncome}</div>
                <div className="font-medium">{formatMoneyTotals(row.income_totals, lang)}</div>
              </div>
              <div className={financialOnly ? "" : "col-span-2"}>
                <div className="mb-1 text-[11px] uppercase tracking-[0.12em] text-slate-400 dark:text-slate-500">{labels.incomePercentage}</div>
                <div className="font-medium">{localizeDigits(incomePercentageById.get(row.id) || "-", lang)}</div>
              </div>
            </div>
          </div>
        ))}
      </div>

      <div className="hidden overflow-x-auto sm:block">
        <table className="min-w-full table-auto text-sm">
          {financialOnly ? (
            <colgroup>
              <col />
              <col style={{ width: "8rem" }} />
              <col style={{ width: "6.5rem" }} />
              <col style={{ width: "15rem" }} />
              <col style={{ width: "7rem" }} />
            </colgroup>
          ) : (
            <colgroup>
              <col />
              <col style={{ width: "8rem" }} />
              <col style={{ width: "6.5rem" }} />
              <col style={{ width: "8rem" }} />
              <col style={{ width: "8rem" }} />
              <col style={{ width: "15rem" }} />
              <col style={{ width: "7rem" }} />
            </colgroup>
          )}
          <thead>
            <tr className="border-b border-slate-200 text-slate-500 dark:border-slate-800 dark:text-slate-400">
              <th className="px-3 py-3 text-start font-medium">{labels.name}</th>
              <th className="px-3 py-3 text-start font-medium">{labels.workingHours}</th>
              <th className="px-3 py-3 text-start font-medium">{labels.hourPercentage}</th>
              {!financialOnly ? <th className="px-3 py-3 text-start font-medium">{labels.nonWorkingHours}</th> : null}
              {!financialOnly ? <th className="px-3 py-3 text-start font-medium">{labels.totalHours}</th> : null}
              <th className="px-3 py-3 text-start font-medium">{labels.totalIncome}</th>
              <th className="px-3 py-3 text-start font-medium">{labels.incomePercentage}</th>
            </tr>
          </thead>
          <tbody>
            {rows.map((row) => (
              <tr key={row.id} className="border-b border-slate-100 last:border-b-0 dark:border-slate-800/80">
                <td className="px-3 py-3 font-medium text-slate-900 dark:text-slate-100">{row.name}</td>
                <td className="px-3 py-3 text-slate-700 dark:text-slate-300">{localizeDigits(row.billable_duration, lang)}</td>
                <td className="px-3 py-3 text-slate-700 dark:text-slate-300">{localizeDigits(hourPercentageById.get(row.id) || "0%", lang)}</td>
                {!financialOnly ? <td className="px-3 py-3 text-slate-700 dark:text-slate-300">{localizeDigits(row.non_billable_duration, lang)}</td> : null}
                {!financialOnly ? <td className="px-3 py-3 text-slate-700 dark:text-slate-300">{localizeDigits(row.total_duration, lang)}</td> : null}
                <td className="px-3 py-3 text-slate-700 dark:text-slate-300">{formatMoneyTotals(row.income_totals, lang)}</td>
                <td className="px-3 py-3 text-slate-700 dark:text-slate-300">{localizeDigits(incomePercentageById.get(row.id) || "-", lang)}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}

function UserSummaryDetailsModal({
  summary,
  report,
  isLoading,
  errorMessage,
  labels,
  lang,
  onClose,
}: {
  summary: UserReportSummary | null;
  report: UserScopedTableReport | null;
  isLoading: boolean;
  errorMessage: string | null;
  labels: Record<string, string>;
  lang: "en" | "fa";
  onClose: () => void;
}) {
  if (!summary) return null;

  const activeSummary = report?.user_summary || summary;

  return (
    <Modal
      isOpen
      onClose={onClose}
      title={labels.userSummaryDetailsTitle.replace("{name}", summary.user.name)}
      description={labels.userSummaryDetailsDescription}
      maxWidth="max-w-6xl"
    >
      <div className="space-y-6">
        <div className="grid gap-3 sm:grid-cols-3">
          <div className="rounded-2xl border border-slate-200 bg-slate-50/80 p-4 dark:border-slate-800 dark:bg-slate-950/70">
            <div className="mb-1 text-xs uppercase tracking-[0.12em] text-slate-400 dark:text-slate-500">{labels.mobile}</div>
            <div className="text-sm font-semibold text-slate-900 dark:text-slate-100">{localizeDigits(activeSummary.user.mobile, lang)}</div>
          </div>
          <div className="rounded-2xl border border-slate-200 bg-slate-50/80 p-4 dark:border-slate-800 dark:bg-slate-950/70">
            <div className="mb-1 text-xs uppercase tracking-[0.12em] text-slate-400 dark:text-slate-500">{labels.workingHours}</div>
            <div className="text-sm font-semibold text-slate-900 dark:text-slate-100">{localizeDigits(activeSummary.billable_duration, lang)}</div>
          </div>
          <div className="rounded-2xl border border-slate-200 bg-slate-50/80 p-4 dark:border-slate-800 dark:bg-slate-950/70">
            <div className="mb-1 text-xs uppercase tracking-[0.12em] text-slate-400 dark:text-slate-500">{labels.totalIncome}</div>
            <div className="text-sm font-semibold text-slate-900 dark:text-slate-100">{formatMoneyTotals(activeSummary.income_totals, lang)}</div>
          </div>
        </div>

        {errorMessage ? (
          <div className="rounded-2xl border border-rose-200 bg-rose-50 px-4 py-3 text-sm text-rose-700 dark:border-rose-500/30 dark:bg-rose-500/10 dark:text-rose-200">
            {errorMessage}
          </div>
        ) : null}

        <section className="space-y-3">
          <div className="text-sm font-semibold text-slate-900 dark:text-white">{labels.rateHistory}</div>
          <div className="overflow-x-auto rounded-2xl border border-slate-200 dark:border-slate-800">
            <table className="min-w-full table-fixed text-sm">
              <colgroup>
                <col />
                <col style={{ width: "10rem" }} />
                <col style={{ width: "10rem" }} />
              </colgroup>
              <thead>
                <tr className="border-b border-slate-200 bg-slate-50 text-slate-500 dark:border-slate-800 dark:bg-slate-950/70 dark:text-slate-400">
                  <th className="px-4 py-3 text-start font-medium">{labels.hourlyRate}</th>
                  <th className="px-4 py-3 text-start font-medium">{labels.fromDate}</th>
                  <th className="px-4 py-3 text-start font-medium">{labels.toDate}</th>
                </tr>
              </thead>
              <tbody>
                {isLoading ? (
                  Array.from({ length: 3 }).map((_, index) => (
                    <tr key={index} className="border-b border-slate-100 last:border-b-0 dark:border-slate-800/80">
                      <td className="px-4 py-3" colSpan={3}>
                        <LoadingBlock className="h-5 w-full" />
                      </td>
                    </tr>
                  ))
                ) : activeSummary.rate_periods.length ? (
                  activeSummary.rate_periods.map((row, index) => (
                    <tr
                      key={`${row.amount}-${row.currency}-${row.from_date}-${index}`}
                      className="border-b border-slate-100 last:border-b-0 dark:border-slate-800/80"
                    >
                      <td className="px-4 py-3 text-slate-700 dark:text-slate-300">
                        {`${formatAmount(row.amount, lang, row.currency)} ${currencyLabel(row.currency, lang)}`}
                      </td>
                      <td className="whitespace-nowrap px-4 py-3 text-slate-700 dark:text-slate-300">{formatDisplayDate(row.from_date, lang)}</td>
                      <td className="whitespace-nowrap px-4 py-3 text-slate-700 dark:text-slate-300">{formatRateToLabel(row.to_date, lang, labels.now)}</td>
                    </tr>
                  ))
                ) : (
                  <tr>
                    <td colSpan={3} className="px-4 py-5 text-center text-slate-500 dark:text-slate-400">
                      {labels.noData}
                    </td>
                  </tr>
                )}
              </tbody>
            </table>
          </div>
        </section>

        <section className="space-y-3">
          <div className="text-sm font-semibold text-slate-900 dark:text-white">{labels.details}</div>
          {isLoading ? (
            <div className="rounded-2xl border border-slate-200 bg-white p-4 dark:border-slate-800 dark:bg-slate-900">
              <LoadingBlock className="h-44 w-full" />
            </div>
          ) : report ? (
            <div className="overflow-x-auto rounded-2xl border border-slate-200 dark:border-slate-800">
              <table className="min-w-full table-auto text-sm">
                <colgroup>
                  <col />
                  <col style={{ width: "8rem" }} />
                  <col style={{ width: "8rem" }} />
                  <col style={{ width: "8rem" }} />
                  <col style={{ width: "10rem" }} />
                  <col />
                </colgroup>
                <thead>
                  <tr className="border-b border-slate-200 bg-slate-50 text-slate-500 dark:border-slate-800 dark:bg-slate-950/70 dark:text-slate-400">
                    <th className="px-4 py-3 text-start font-medium">{labels.date}</th>
                    <th className="px-4 py-3 text-start font-medium">{labels.billableHours}</th>
                    <th className="px-4 py-3 text-start font-medium">{labels.nonBillableHours}</th>
                    <th className="px-4 py-3 text-start font-medium">{labels.totalHours}</th>
                    <th className="px-4 py-3 text-start font-medium">{labels.hourlyRate}</th>
                    <th className="px-4 py-3 text-start font-medium">{labels.totalIncome}</th>
                  </tr>
                </thead>
                <tbody>
                  {report.days.length ? (
                    report.days.map((day) => (
                      <tr key={day.date} className="border-b border-slate-100 last:border-b-0 dark:border-slate-800/80">
                        <td className="px-4 py-3 text-slate-700 dark:text-slate-300">{formatDisplayDate(day.date, lang)}</td>
                        <td className="px-4 py-3 text-slate-700 dark:text-slate-300">{localizeDigits(day.billable_duration, lang)}</td>
                        <td className="px-4 py-3 text-slate-700 dark:text-slate-300">{localizeDigits(day.non_billable_duration, lang)}</td>
                        <td className="px-4 py-3 text-slate-700 dark:text-slate-300">{localizeDigits(day.total_duration, lang)}</td>
                        <td className="px-4 py-3 text-slate-700 dark:text-slate-300">{formatHourlyRate(day.latest_hourly_rate, lang)}</td>
                        <td className="px-4 py-3 text-slate-700 dark:text-slate-300">{formatMoneyTotals(day.income_totals, lang)}</td>
                      </tr>
                    ))
                  ) : (
                    <tr>
                      <td colSpan={6} className="px-4 py-5 text-center text-slate-500 dark:text-slate-400">
                        {labels.noData}
                      </td>
                    </tr>
                  )}
                </tbody>
              </table>
            </div>
          ) : null}
        </section>

        <div className="grid gap-4">
          <BreakdownTable
            title={labels.clientsTable}
            rows={report?.clients || []}
            hourPercentages={activeSummary.client_percentages}
            incomePercentages={activeSummary.client_income_percentages}
            labels={labels}
            lang={lang}
            financialOnly
          />
          <BreakdownTable
            title={labels.projectsTable}
            rows={report?.projects || []}
            hourPercentages={activeSummary.project_percentages}
            incomePercentages={activeSummary.project_income_percentages}
            labels={labels}
            lang={lang}
            financialOnly
          />
          <BreakdownTable
            title={labels.tagsTable}
            rows={report?.tags || []}
            hourPercentages={activeSummary.tag_percentages}
            incomePercentages={activeSummary.tag_income_percentages}
            labels={labels}
            lang={lang}
            financialOnly
          />
        </div>
      </div>
    </Modal>
  );
}

function UserSummarySection({
  rows,
  onLoadUserSummaryReport,
  labels,
  lang,
  financialOnly,
}: {
  rows: UserReportSummary[];
  onLoadUserSummaryReport: (userId: string) => Promise<UserScopedTableReport>;
  labels: Record<string, string>;
  lang: "en" | "fa";
  financialOnly: boolean;
}) {
  const [selectedSummary, setSelectedSummary] = useState<UserReportSummary | null>(null);
  const [reportCache, setReportCache] = useState<Record<string, UserScopedTableReport>>({});
  const [selectedReport, setSelectedReport] = useState<UserScopedTableReport | null>(null);
  const [isLoadingDetails, setIsLoadingDetails] = useState(false);
  const [detailsError, setDetailsError] = useState<string | null>(null);

  if (!rows.length) return null;

  const openSummaryDetails = async (summary: UserReportSummary) => {
    setSelectedSummary(summary);
    setDetailsError(null);
    const cached = reportCache[summary.user.id];
    if (cached) {
      setSelectedReport(cached);
      setIsLoadingDetails(false);
      return;
    }
    setSelectedReport(null);
    setIsLoadingDetails(true);
    try {
      const nextReport = await onLoadUserSummaryReport(summary.user.id);
      setReportCache((current) => ({ ...current, [summary.user.id]: nextReport }));
      setSelectedReport(nextReport);
    } catch {
      setDetailsError(labels.loadDetailsError);
    } finally {
      setIsLoadingDetails(false);
    }
  };

  return (
    <>
      <div className="rounded-3xl border border-slate-200 bg-white p-4 shadow-sm dark:border-slate-800 dark:bg-slate-900 sm:p-5">
        <div className="mb-4 text-sm font-semibold text-slate-900 dark:text-white">{labels.userSummaryTitle}</div>
        <div className="overflow-x-auto">
          <table className="min-w-[720px] w-full text-sm">
            <thead>
              <tr className="border-b border-slate-200 text-slate-500 dark:border-slate-800 dark:text-slate-400">
                <th className="px-3 py-3 text-start font-medium">{labels.name}</th>
                <th className="px-3 py-3 text-start font-medium">{labels.mobile}</th>
                <th className="px-3 py-3 text-start font-medium">{labels.workingHours}</th>
                {!financialOnly ? <th className="px-3 py-3 text-start font-medium">{labels.nonWorkingHours}</th> : null}
                <th className="px-3 py-3 text-start font-medium">{labels.totalIncome}</th>
              </tr>
            </thead>
            <tbody>
              {rows.map((row) => (
                <tr
                  key={row.user.id}
                  className="cursor-pointer border-b border-slate-100 transition hover:bg-slate-50 last:border-b-0 dark:border-slate-800/80 dark:hover:bg-slate-800/40"
                  onClick={() => void openSummaryDetails(row)}
                >
                  <td className="px-3 py-3 font-medium text-slate-900 dark:text-slate-100">{row.user.name}</td>
                  <td className="px-3 py-3 text-slate-700 dark:text-slate-300">{localizeDigits(row.user.mobile, lang)}</td>
                  <td className="px-3 py-3 text-slate-700 dark:text-slate-300">{localizeDigits(row.billable_duration, lang)}</td>
                  {!financialOnly ? <td className="px-3 py-3 text-slate-700 dark:text-slate-300">{localizeDigits(row.non_billable_duration, lang)}</td> : null}
                  <td className="px-3 py-3 text-slate-700 dark:text-slate-300">{formatMoneyTotals(row.income_totals, lang)}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>
      <UserSummaryDetailsModal
        summary={selectedSummary}
        report={selectedReport}
        isLoading={isLoadingDetails}
        errorMessage={detailsError}
        labels={labels}
        lang={lang}
        onClose={() => {
          setSelectedSummary(null);
          setSelectedReport(null);
          setDetailsError(null);
          setIsLoadingDetails(false);
        }}
      />
    </>
  );
}

function SummaryCards({
  summary,
  labels,
  lang,
}: {
  summary: TableReportResponse["summary"];
  labels: Record<string, string>;
  lang: "en" | "fa";
}) {
  return (
    <div className="grid gap-3 sm:grid-cols-3">
      <div className="rounded-3xl border border-slate-200 bg-white p-4 shadow-sm dark:border-slate-800 dark:bg-slate-900">
        <div className="text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500 dark:text-slate-400">{labels.workingHours}</div>
        <div className="mt-2 text-xl font-bold text-slate-900 dark:text-white sm:text-2xl">{localizeDigits(summary.billable_duration, lang)}</div>
      </div>
      <div className="rounded-3xl border border-slate-200 bg-white p-4 shadow-sm dark:border-slate-800 dark:bg-slate-900">
        <div className="text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500 dark:text-slate-400">{labels.nonWorkingHours}</div>
        <div className="mt-2 text-xl font-bold text-slate-900 dark:text-white sm:text-2xl">{localizeDigits(summary.non_billable_duration, lang)}</div>
      </div>
      <div className="rounded-3xl border border-slate-200 bg-white p-4 shadow-sm dark:border-slate-800 dark:bg-slate-900">
        <div className="text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500 dark:text-slate-400">{labels.totalIncome}</div>
        <div className="mt-2 text-sm font-semibold leading-6 text-slate-900 dark:text-white sm:text-base">{formatMoneyTotals(summary.income_totals, lang)}</div>
      </div>
    </div>
  );
}

function DailyDetailsSection({
  data,
  dayDetails,
  openDay,
  onToggleDay,
  labels,
  lang,
}: {
  data: TableReportResponse;
  dayDetails: DayDetailsResponse | null;
  openDay: string | null;
  onToggleDay: (day: string) => void;
  labels: Record<string, string>;
  lang: "en" | "fa";
}) {
  const days = Array.isArray(data.days) ? data.days : [];
  const entries = Array.isArray(dayDetails?.entries) ? dayDetails.entries : [];
  const summary = data.summary;

  return (
    <div className="rounded-3xl border border-slate-200 bg-white p-4 shadow-sm dark:border-slate-800 dark:bg-slate-900 sm:p-5">
      <div className="mb-4 text-sm font-semibold text-slate-900 dark:text-white">{labels.details}</div>

      <div className="space-y-3 sm:hidden">
        {days.map((day) => {
          const isOpen = openDay === day.date;
          return (
            <div key={day.date} className="rounded-2xl border border-slate-200 bg-slate-50/80 p-3 dark:border-slate-800 dark:bg-slate-950/70">
              <div className="flex items-start justify-between gap-3">
                <div>
                  <div className="text-sm font-semibold text-slate-900 dark:text-white">{formatDisplayDate(day.date, lang)}</div>
                  <div className="mt-1 text-xs text-slate-500 dark:text-slate-400">
                    {labels.totalHours}: {localizeDigits(day.total_duration, lang)}
                  </div>
                </div>
                <button
                  type="button"
                  onClick={() => onToggleDay(day.date)}
                  className="inline-flex h-9 w-9 items-center justify-center rounded-xl border border-slate-200 bg-white text-slate-500 transition hover:bg-slate-100 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-300 dark:hover:bg-slate-800"
                >
                  {isOpen ? <ChevronUp className="h-4 w-4" /> : <ChevronDown className="h-4 w-4" />}
                </button>
              </div>

              <div className="mt-3 grid grid-cols-2 gap-3 text-xs text-slate-600 dark:text-slate-300">
                <div>
                  <div className="mb-1 text-[11px] uppercase tracking-[0.12em] text-slate-400 dark:text-slate-500">{labels.billableHours}</div>
                  <div className="font-medium">{localizeDigits(day.billable_duration, lang)}</div>
                </div>
                <div>
                  <div className="mb-1 text-[11px] uppercase tracking-[0.12em] text-slate-400 dark:text-slate-500">{labels.nonBillableHours}</div>
                  <div className="font-medium">{localizeDigits(day.non_billable_duration, lang)}</div>
                </div>
                <div>
                  <div className="mb-1 text-[11px] uppercase tracking-[0.12em] text-slate-400 dark:text-slate-500">{labels.hourlyRate}</div>
                  <div className="font-medium">{formatHourlyRate(day.latest_hourly_rate, lang)}</div>
                </div>
                <div className="col-span-2">
                  <div className="mb-1 text-[11px] uppercase tracking-[0.12em] text-slate-400 dark:text-slate-500">{labels.totalIncome}</div>
                  <div className="font-medium">{formatMoneyTotals(day.income_totals, lang)}</div>
                </div>
              </div>

              {isOpen && dayDetails?.day === day.date ? (
                <div className="mt-3 space-y-2 border-t border-slate-200 pt-3 dark:border-slate-800">
                  {entries.map((entry) => (
                    <div key={entry.id} className="rounded-xl border border-slate-200 bg-white p-3 dark:border-slate-700 dark:bg-slate-900">
                      <div className="text-sm font-medium text-slate-900 dark:text-slate-100">{entry.description || labels.noDescription}</div>
                      <div className="mt-1 text-xs text-slate-500 dark:text-slate-400">
                        {entry.project?.name || "-"} • {localizeDigits(entry.duration, lang)}
                      </div>
                      <div className="mt-2 text-xs text-slate-500 dark:text-slate-400">{formatDisplayDateTime(entry.start_time, lang)}</div>
                    </div>
                  ))}
                </div>
              ) : null}
            </div>
          );
        })}

        <div className="rounded-2xl border border-sky-200 bg-sky-50 p-3 dark:border-sky-500/20 dark:bg-sky-500/10">
          <div className="text-sm font-semibold text-slate-900 dark:text-white">{labels.total}</div>
          <div className="mt-3 grid grid-cols-2 gap-3 text-xs text-slate-700 dark:text-slate-300">
            <div>{labels.billableHours}: {localizeDigits(summary.billable_duration, lang)}</div>
            <div>{labels.nonBillableHours}: {localizeDigits(summary.non_billable_duration, lang)}</div>
            <div className="col-span-2">{labels.totalIncome}: {formatMoneyTotals(summary.income_totals, lang)}</div>
          </div>
        </div>
      </div>

      <div className="hidden overflow-x-auto sm:block">
        <table className="min-w-[860px] w-full text-sm">
          <thead>
            <tr className="border-b border-slate-200 text-slate-500 dark:border-slate-800 dark:text-slate-400">
              <th className="w-[18%] px-3 py-3 text-start font-medium">{labels.date}</th>
              <th className="w-[14%] px-3 py-3 text-start font-medium">{labels.billableHours}</th>
              <th className="w-[14%] px-3 py-3 text-start font-medium">{labels.nonBillableHours}</th>
              <th className="w-[18%] px-3 py-3 text-start font-medium">{labels.hourlyRate}</th>
              <th className="w-[26%] px-3 py-3 text-start font-medium">{labels.totalIncome}</th>
              <th className="w-[10%] px-3 py-3 text-start font-medium">{labels.details}</th>
            </tr>
          </thead>
          <tbody>
            {days.map((day) => {
              const isOpen = openDay === day.date;
              return (
                <Fragment key={day.date}>
                  <tr className="border-b border-slate-100 dark:border-slate-800/80">
                    <td className="px-3 py-3 font-medium text-slate-900 dark:text-slate-100">{formatDisplayDate(day.date, lang)}</td>
                    <td className="px-3 py-3 text-slate-700 dark:text-slate-300">{localizeDigits(day.billable_duration, lang)}</td>
                    <td className="px-3 py-3 text-slate-700 dark:text-slate-300">{localizeDigits(day.non_billable_duration, lang)}</td>
                    <td className="px-3 py-3 text-slate-700 dark:text-slate-300">{formatHourlyRate(day.latest_hourly_rate, lang)}</td>
                    <td className="px-3 py-3 text-slate-700 dark:text-slate-300">{formatMoneyTotals(day.income_totals, lang)}</td>
                    <td className="px-3 py-3">
                      <button
                        type="button"
                        onClick={() => onToggleDay(day.date)}
                        className="inline-flex h-9 w-9 items-center justify-center rounded-xl border border-slate-200 bg-white text-slate-500 transition hover:bg-slate-50 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-300 dark:hover:bg-slate-800"
                      >
                        {isOpen ? <ChevronUp className="h-4 w-4" /> : <ChevronDown className="h-4 w-4" />}
                      </button>
                    </td>
                  </tr>
                  {isOpen && dayDetails?.day === day.date ? (
                    <tr className="border-b border-slate-100 bg-slate-50/70 dark:border-slate-800/80 dark:bg-slate-950/70">
                      <td colSpan={6} className="px-3 py-4">
                        <div className="space-y-2">
                          {entries.map((entry) => (
                            <div key={entry.id} className="rounded-2xl border border-slate-200 bg-white px-4 py-3 dark:border-slate-700 dark:bg-slate-900">
                              <div className="flex flex-wrap items-center gap-2 text-sm">
                                <span className="font-medium text-slate-900 dark:text-slate-100">{entry.description || labels.noDescription}</span>
                                {entry.project ? <span className="text-sky-600 dark:text-sky-300">{entry.project.name}</span> : null}
                                <span className="text-slate-500 dark:text-slate-400">{localizeDigits(entry.duration, lang)}</span>
                                <span className="text-slate-500 dark:text-slate-400">{formatDisplayDateTime(entry.start_time, lang)}</span>
                              </div>
                            </div>
                          ))}
                        </div>
                      </td>
                    </tr>
                  ) : null}
                </Fragment>
              );
            })}
            <tr className="bg-sky-50/80 font-semibold dark:bg-sky-500/10">
              <td className="px-3 py-3">{labels.total}</td>
              <td className="px-3 py-3">{localizeDigits(summary.billable_duration, lang)}</td>
              <td className="px-3 py-3">{localizeDigits(summary.non_billable_duration, lang)}</td>
              <td className="px-3 py-3">-</td>
              <td className="px-3 py-3">{formatMoneyTotals(summary.income_totals, lang)}</td>
              <td className="px-3 py-3" />
            </tr>
          </tbody>
        </table>
      </div>
    </div>
  );
}

export function ReportsTablePanel({
  data,
  dayDetails,
  openDay,
  onToggleDay,
  onLoadUserSummaryReport,
  onExport,
  exportState,
  labels,
  isLoading,
}: {
  data: TableReportResponse | null;
  dayDetails: DayDetailsResponse | null;
  openDay: string | null;
  onToggleDay: (day: string) => void;
  onLoadUserSummaryReport: (userId: string) => Promise<UserScopedTableReport>;
  onExport: (type: "excel" | "pdf") => void;
  exportState: {
    excel: { pending: boolean; cooldownSeconds: number };
    pdf: { pending: boolean; cooldownSeconds: number };
  };
  labels: Record<string, string>;
  isLoading: boolean;
}) {
  const { lang } = useTranslation();

  if (isLoading) {
    return <ReportsTableSkeleton labels={labels} />;
  }

  if (!data) return null;

  const clients = Array.isArray(data.clients) ? data.clients : [];
  const projects = Array.isArray(data.projects) ? data.projects : [];
  const tags = Array.isArray(data.tags) ? data.tags : [];
  const userSummaries = Array.isArray(data.user_summaries) ? data.user_summaries : [];
  const isAllUsersScope = Boolean(data.scope?.is_workspace_scope && !data.scope?.user);

  return (
    <div className="space-y-4">
      <UserSummarySection
        rows={userSummaries}
        onLoadUserSummaryReport={onLoadUserSummaryReport}
        labels={labels}
        lang={lang}
        financialOnly={isAllUsersScope}
      />

      <div className="flex flex-col gap-2 sm:flex-row sm:justify-end">
        <button
          type="button"
          onClick={() => onExport("excel")}
          disabled={exportState.excel.pending || exportState.excel.cooldownSeconds > 0}
          className="inline-flex h-11 items-center justify-center gap-2 rounded-2xl border border-emerald-200 bg-emerald-50 px-4 text-sm font-medium text-emerald-700 transition hover:bg-emerald-100 disabled:cursor-not-allowed disabled:opacity-60 dark:border-emerald-500/30 dark:bg-emerald-500/10 dark:text-emerald-300"
        >
          <FileSpreadsheet className="h-4 w-4" />
          {exportState.excel.pending
            ? labels.exportExcel
            : exportState.excel.cooldownSeconds > 0
              ? `${labels.exportExcel} (${localizeDigits(String(exportState.excel.cooldownSeconds), lang)})`
              : labels.exportExcel}
        </button>
        <button
          type="button"
          onClick={() => onExport("pdf")}
          disabled={exportState.pdf.pending || exportState.pdf.cooldownSeconds > 0}
          className="inline-flex h-11 items-center justify-center gap-2 rounded-2xl border border-rose-200 bg-rose-50 px-4 text-sm font-medium text-rose-700 transition hover:bg-rose-100 disabled:cursor-not-allowed disabled:opacity-60 dark:border-rose-500/30 dark:bg-rose-500/10 dark:text-rose-300"
        >
          <FileText className="h-4 w-4" />
          {exportState.pdf.pending
            ? labels.exportPdf
            : exportState.pdf.cooldownSeconds > 0
              ? `${labels.exportPdf} (${localizeDigits(String(exportState.pdf.cooldownSeconds), lang)})`
              : labels.exportPdf}
        </button>
      </div>

      <SummaryCards summary={data.summary} labels={labels} lang={lang} />

      {!isAllUsersScope ? (
        <DailyDetailsSection
          data={data}
          dayDetails={dayDetails}
          openDay={openDay}
          onToggleDay={onToggleDay}
          labels={labels}
          lang={lang}
        />
      ) : null}

      <BreakdownTable
        title={labels.clientsTable}
        rows={clients}
        hourPercentages={data.client_percentages}
        incomePercentages={data.client_income_percentages}
        labels={labels}
        lang={lang}
        financialOnly={isAllUsersScope}
      />
      <BreakdownTable
        title={labels.projectsTable}
        rows={projects}
        hourPercentages={data.project_percentages}
        incomePercentages={data.project_income_percentages}
        labels={labels}
        lang={lang}
        financialOnly={isAllUsersScope}
      />
      <BreakdownTable
        title={labels.tagsTable}
        rows={tags}
        hourPercentages={data.tag_percentages}
        incomePercentages={data.tag_income_percentages}
        labels={labels}
        lang={lang}
        financialOnly={isAllUsersScope}
      />
    </div>
  );
}
