import { Fragment } from "react";
import { clsx } from "clsx";
import type { ReportExplainability } from "./reportBuilderExplainability.js";

interface ReportGroupSummary {
  key: string;
  label: string;
  rowCount: number;
  startIndex: number;
}

type ReportResultsPanelProps = {
  rows: Record<string, unknown>[];
  totalCount: number;
  outputColumns: string[];
  groups: ReportGroupSummary[];
  explainability: ReportExplainability | undefined;
  groupBy: string;
  sortBy: string;
  sortDir: "asc" | "desc";
  isLoading: boolean;
  page: number;
  pageSize: number;
  columnLabelMap: Map<string, string>;
  exportPending: boolean;
  onSort: (column: string) => void;
  onExport: () => void;
  onPageChange: (page: number) => void;
  summarizeMissing: (columns: string[], labelMap: Map<string, string>, limit?: number) => string;
};

function formatCellValue(value: unknown): string {
  if (value === null || value === undefined) return "--";
  if (typeof value === "boolean") return value ? "Yes" : "No";
  if (typeof value === "string") {
    if (/^\d{4}-\d{2}-\d{2}T/.test(value)) {
      return new Date(value).toLocaleDateString("de-DE", {
        year: "numeric",
        month: "2-digit",
        day: "2-digit",
      });
    }
    return value;
  }
  if (typeof value === "number") {
    return value.toLocaleString("de-DE");
  }
  return String(value);
}

export function ReportResultsPanel({
  rows,
  totalCount,
  outputColumns,
  groups,
  explainability,
  groupBy,
  sortBy,
  sortDir,
  isLoading,
  page,
  pageSize,
  columnLabelMap,
  exportPending,
  onSort,
  onExport,
  onPageChange,
  summarizeMissing,
}: ReportResultsPanelProps) {
  const totalPages = Math.ceil(totalCount / pageSize);
  const groupStartByIndex = new Map(groups.map((group) => [group.startIndex, group] as const));

  return (
    <div className="rounded-2xl border border-gray-200 bg-white shadow-sm dark:border-slate-800 dark:bg-slate-950">
      {/* Results Header */}
      <div className="flex items-center justify-between border-b border-gray-200 px-6 py-4 dark:border-slate-800">
        <div className="space-y-1">
          <div className="flex items-center gap-3">
            <h2 className="text-lg font-semibold text-gray-900 dark:text-gray-50">Results</h2>
            {!isLoading && (
              <span className="rounded-full bg-gray-100 px-2.5 py-0.5 text-xs font-medium text-gray-600 dark:bg-slate-800 dark:text-gray-400">
                {totalCount.toLocaleString()} row{totalCount !== 1 ? "s" : ""}
              </span>
            )}
          </div>
          <p className="text-xs text-gray-500 dark:text-gray-400">
            {explainability?.entity === "resource_month"
              ? "Exports include the report sheet plus an Explainability sheet with location, holiday, absence and SAH basis."
              : "CSV exports include the selected basis columns and computed CapaKraken metrics exactly as shown here."}
          </p>
          {groupBy && rows.length > 0 ? (
            <p className="text-xs text-gray-500 dark:text-gray-400">
              Grouped by {columnLabelMap.get(groupBy) ?? groupBy} with page-local section headers.
            </p>
          ) : null}
        </div>
        <button
          type="button"
          onClick={onExport}
          disabled={exportPending || totalCount === 0}
          className="inline-flex items-center gap-1.5 rounded-lg border border-gray-300 bg-white px-3 py-1.5 text-sm font-medium text-gray-700 shadow-sm transition-colors hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-700 dark:bg-slate-900 dark:text-gray-300 dark:hover:bg-slate-800"
        >
          <svg className="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path
              strokeLinecap="round"
              strokeLinejoin="round"
              strokeWidth={2}
              d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
            />
          </svg>
          {exportPending
            ? "Exporting..."
            : explainability?.entity === "resource_month"
              ? "Export XLSX"
              : "Export CSV"}
        </button>
      </div>

      {explainability?.entity === "resource_month" ? (
        <div className="border-b border-emerald-100 bg-emerald-50/70 px-6 py-4 text-sm dark:border-emerald-950/60 dark:bg-emerald-950/20">
          <div className="flex flex-wrap gap-2">
            <span className="rounded-full bg-white px-2.5 py-1 text-[11px] font-medium text-emerald-900 dark:bg-slate-950 dark:text-emerald-100">
              Month: {explainability.periodMonth ?? "current"}
            </span>
            <span className="rounded-full bg-white px-2.5 py-1 text-[11px] font-medium text-emerald-900 dark:bg-slate-950 dark:text-emerald-100">
              Location:{" "}
              {(explainability.locationContextColumns.length > 0
                ? explainability.locationContextColumns
                : ["none"]
              )
                .map((column) => columnLabelMap.get(column) ?? column)
                .join(", ")}
            </span>
            <span className="rounded-full bg-white px-2.5 py-1 text-[11px] font-medium text-emerald-900 dark:bg-slate-950 dark:text-emerald-100">
              Holidays:{" "}
              {(explainability.holidayMetricColumns.length > 0
                ? explainability.holidayMetricColumns
                : ["none"]
              )
                .map((column) => columnLabelMap.get(column) ?? column)
                .join(", ")}
            </span>
            <span className="rounded-full bg-white px-2.5 py-1 text-[11px] font-medium text-emerald-900 dark:bg-slate-950 dark:text-emerald-100">
              Absences:{" "}
              {(explainability.absenceMetricColumns.length > 0
                ? explainability.absenceMetricColumns
                : ["none"]
              )
                .map((column) => columnLabelMap.get(column) ?? column)
                .join(", ")}
            </span>
            <span className="rounded-full bg-white px-2.5 py-1 text-[11px] font-medium text-emerald-900 dark:bg-slate-950 dark:text-emerald-100">
              Capacity:{" "}
              {(explainability.capacityMetricColumns.length > 0
                ? explainability.capacityMetricColumns
                : ["none"]
              )
                .map((column) => columnLabelMap.get(column) ?? column)
                .join(", ")}
            </span>
          </div>
          <p className="mt-3 text-xs text-emerald-900/80 dark:text-emerald-200/80">
            {explainability.notes.join(" ")}
          </p>
          {explainability.missingRecommendedColumns.length > 0 ? (
            <p className="mt-2 text-xs text-amber-700 dark:text-amber-300">
              Missing recommended audit columns:{" "}
              {summarizeMissing(explainability.missingRecommendedColumns, columnLabelMap)}
            </p>
          ) : null}
        </div>
      ) : null}

      {/* Table */}
      <div className="overflow-x-auto">
        {isLoading ? (
          <div className="flex items-center justify-center py-16">
            <div className="h-8 w-8 animate-spin rounded-full border-2 border-brand-600 border-t-transparent" />
          </div>
        ) : rows.length === 0 ? (
          <div className="py-16 text-center text-sm text-gray-400 dark:text-gray-500">
            No data found. Try adjusting your filters.
          </div>
        ) : (
          <table className="w-full text-sm">
            <thead>
              <tr className="border-b border-gray-200 bg-gray-50/80 dark:border-slate-800 dark:bg-slate-900/50">
                {outputColumns.map((col) => {
                  const isSortable = !col.includes(".");
                  const isSorted = sortBy === col;
                  return (
                    <th
                      key={col}
                      onClick={isSortable ? () => onSort(col) : undefined}
                      className={clsx(
                        "whitespace-nowrap px-4 py-3 text-left text-xs font-semibold uppercase tracking-wider text-gray-500 dark:text-gray-400",
                        isSortable &&
                          "cursor-pointer select-none hover:text-gray-700 dark:hover:text-gray-200",
                      )}
                    >
                      <span className="inline-flex items-center gap-1">
                        {columnLabelMap.get(col) ?? col}
                        {isSorted && (
                          <svg
                            className={clsx("h-3 w-3", sortDir === "desc" && "rotate-180")}
                            fill="none"
                            stroke="currentColor"
                            viewBox="0 0 24 24"
                          >
                            <path
                              strokeLinecap="round"
                              strokeLinejoin="round"
                              strokeWidth={2}
                              d="M5 15l7-7 7 7"
                            />
                          </svg>
                        )}
                      </span>
                    </th>
                  );
                })}
              </tr>
            </thead>
            <tbody className="divide-y divide-gray-100 dark:divide-slate-800/60">
              {rows.map((row, idx) => {
                const group = groupStartByIndex.get(idx);

                return (
                  <Fragment key={`grouped-row:${String(row.id ?? idx)}:${idx}`}>
                    {group ? (
                      <tr
                        key={`${group.key}:${idx}`}
                        className="bg-brand-50/70 dark:bg-brand-950/20"
                      >
                        <td
                          colSpan={outputColumns.length}
                          className="px-4 py-2 text-xs font-semibold uppercase tracking-[0.14em] text-brand-700 dark:text-brand-200"
                        >
                          {columnLabelMap.get(groupBy) ?? groupBy}: {group.label} · {group.rowCount}{" "}
                          row{group.rowCount === 1 ? "" : "s"}
                        </td>
                      </tr>
                    ) : null}
                    <tr
                      key={(row.id as string) ?? idx}
                      className="transition-colors hover:bg-gray-50/60 dark:hover:bg-slate-900/40"
                    >
                      {outputColumns.map((col) => (
                        <td
                          key={col}
                          className="whitespace-nowrap px-4 py-2.5 text-gray-700 dark:text-gray-300"
                        >
                          {formatCellValue(row[col])}
                        </td>
                      ))}
                    </tr>
                  </Fragment>
                );
              })}
            </tbody>
          </table>
        )}
      </div>

      {/* Pagination */}
      {totalPages > 1 && (
        <div className="flex items-center justify-between border-t border-gray-200 px-6 py-3 dark:border-slate-800">
          <span className="text-sm text-gray-500 dark:text-gray-400">
            Page {page + 1} of {totalPages}
          </span>
          <div className="flex gap-2">
            <button
              type="button"
              onClick={() => onPageChange(Math.max(0, page - 1))}
              disabled={page === 0}
              className="rounded-lg border border-gray-300 px-3 py-1.5 text-sm font-medium text-gray-700 transition-colors hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-700 dark:text-gray-300 dark:hover:bg-slate-800"
            >
              Previous
            </button>
            <button
              type="button"
              onClick={() => onPageChange(Math.min(totalPages - 1, page + 1))}
              disabled={page >= totalPages - 1}
              className="rounded-lg border border-gray-300 px-3 py-1.5 text-sm font-medium text-gray-700 transition-colors hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-50 dark:border-slate-700 dark:text-gray-300 dark:hover:bg-slate-800"
            >
              Next
            </button>
          </div>
        </div>
      )}
    </div>
  );
}
