"use client";

import {
  type EstimateExportArtifactPayload,
  EstimateExportFormat,
} from "@capakraken/shared";
import type {
  EstimateExportView,
  EstimateVersionView,
  EstimateWorkspaceView,
} from "~/components/estimates/EstimateWorkspace.types.js";
import { InfoTooltip } from "~/components/ui/InfoTooltip.js";
import { formatDateLong, formatMoney } from "~/lib/format.js";

const EXPORT_FORMATS: EstimateExportFormat[] = [
  EstimateExportFormat.XLSX,
  EstimateExportFormat.CSV,
  EstimateExportFormat.JSON,
  EstimateExportFormat.SAP,
  EstimateExportFormat.MMP,
];

function formatBytes(value: number | null | undefined) {
  const bytes = value ?? 0;
  if (bytes < 1024) {
    return `${bytes} B`;
  }
  if (bytes < 1024 * 1024) {
    return `${(bytes / 1024).toFixed(1)} KB`;
  }
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
}

function isEstimateExportArtifactPayload(
  payload: EstimateExportView["payload"],
): payload is EstimateExportArtifactPayload {
  return (
    typeof payload === "object" &&
    payload !== null &&
    typeof payload.content === "string" &&
    typeof payload.mimeType === "string" &&
    typeof payload.encoding === "string" &&
    typeof payload.fileExtension === "string" &&
    typeof payload.generatedAt === "string" &&
    typeof payload.byteLength === "number" &&
    typeof payload.summary === "object" &&
    payload.summary !== null
  );
}

function decodeBase64(value: string) {
  const binary = atob(value);
  const bytes = new Uint8Array(binary.length);

  for (let index = 0; index < binary.length; index += 1) {
    bytes[index] = binary.charCodeAt(index);
  }

  return bytes;
}

function downloadEstimateExport(estimateExport: EstimateExportView) {
  const payload = estimateExport.payload;
  if (!isEstimateExportArtifactPayload(payload)) {
    return;
  }

  const blob =
    payload.encoding === "base64"
      ? new Blob([decodeBase64(payload.content)], { type: payload.mimeType })
      : new Blob([payload.content], { type: payload.mimeType });
  const url = URL.createObjectURL(blob);
  const link = document.createElement("a");
  link.href = url;
  link.download = estimateExport.fileName;
  document.body.append(link);
  link.click();
  link.remove();
  URL.revokeObjectURL(url);
}

export interface ExportsTabProps {
  estimate: EstimateWorkspaceView;
  canEdit: boolean;
  onCreateExport: (versionId: string, format: EstimateExportFormat) => void;
  isCreatingExport: boolean;
}

export function ExportsTab({
  estimate,
  canEdit,
  onCreateExport,
  isCreatingExport,
}: ExportsTabProps) {
  const versions = estimate.versions as EstimateVersionView[];
  const latestVersion = versions[0] ?? null;
  const exports = latestVersion?.exports ?? [];

  return (
    <div className="space-y-4">
      <div className="rounded-3xl border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 p-5 shadow-sm">
        <div className="flex flex-wrap items-start justify-between gap-4">
          <div>
            <h2 className="text-sm font-semibold uppercase tracking-wide text-gray-600 dark:text-gray-400">Export delivery <InfoTooltip content="Generate downloadable files from the current estimate version. Each format includes demand lines, scope, and financial summaries." /></h2>
            <p className="mt-2 text-sm text-gray-500 dark:text-gray-400">
              Generate format-specific artifacts from the current version and download them directly from the stored serializer payload.
            </p>
          </div>
          {latestVersion && canEdit && (
            <div className="flex flex-wrap gap-2">
              {EXPORT_FORMATS.map((format) => (
                <button
                  key={format}
                  type="button"
                  onClick={() => onCreateExport(latestVersion.id, format)}
                  disabled={isCreatingExport}
                  className="rounded-2xl border border-brand-200 bg-white dark:bg-gray-800 px-3 py-2 text-sm font-semibold text-brand-700 transition hover:border-brand-300 hover:bg-brand-50 disabled:cursor-not-allowed disabled:opacity-60"
                >
                  {isCreatingExport ? "Generating..." : `Create ${format}`}
                </button>
              ))}
            </div>
          )}
        </div>
      </div>

      <div className="rounded-3xl border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 shadow-sm">
        <div className="border-b border-gray-100 dark:border-gray-700/50 px-6 py-4">
          <h2 className="text-sm font-semibold uppercase tracking-wide text-gray-600 dark:text-gray-400">Generated exports <InfoTooltip content="Previously generated export artifacts. XLSX/CSV contain tabular data; JSON is machine-readable; SAP/MMP are ERP integration formats." /></h2>
        </div>
        {exports.length === 0 ? (
          <div className="px-6 py-8">
            <p className="text-sm text-gray-400">No exports have been generated for the current version yet.</p>
          </div>
        ) : (
          <div className="divide-y divide-gray-100 dark:divide-gray-700/50">
            {exports.map((estimateExport) => {
              const payload = isEstimateExportArtifactPayload(estimateExport.payload)
                ? estimateExport.payload
                : null;

              return (
                <div key={estimateExport.id} className="px-6 py-5">
                  <div className="flex flex-wrap items-start justify-between gap-4">
                    <div className="min-w-0 flex-1">
                      <div className="flex flex-wrap items-center gap-2">
                        <p className="text-sm font-medium text-gray-900 dark:text-gray-100">{estimateExport.fileName}</p>
                        <span className="rounded-full bg-gray-100 dark:bg-gray-800 px-2.5 py-1 text-[11px] font-semibold uppercase tracking-wide text-gray-600 dark:text-gray-400">
                          {estimateExport.format}
                        </span>
                        {payload?.sheetNames?.length ? (
                          <span className="rounded-full bg-sky-50 dark:bg-sky-900/30 px-2.5 py-1 text-[11px] font-semibold text-sky-700 dark:text-sky-300">
                            {payload.sheetNames.length} sheets
                          </span>
                        ) : null}
                      </div>
                      <div className="mt-2 flex flex-wrap gap-x-4 gap-y-1 text-xs text-gray-500 dark:text-gray-400">
                        <span>{formatDateLong(estimateExport.createdAt)}</span>
                        {payload ? <span>{formatBytes(payload.byteLength)}</span> : null}
                        {payload?.rowCount != null ? <span>{payload.rowCount} rows</span> : null}
                        {payload?.lineCount != null ? <span>{payload.lineCount} lines</span> : null}
                      </div>
                      {payload ? (
                        <div className="mt-3 grid gap-2 text-xs text-gray-600 dark:text-gray-400 md:grid-cols-2 xl:grid-cols-4">
                          <div className="rounded-2xl bg-gray-50 dark:bg-gray-900 px-3 py-2">
                            <p className="uppercase tracking-wide text-gray-400">Hours</p>
                            <p className="mt-1 font-semibold text-gray-900 dark:text-gray-100">
                              {payload.summary.totalHours.toFixed(1)}
                            </p>
                          </div>
                          <div className="rounded-2xl bg-gray-50 dark:bg-gray-900 px-3 py-2">
                            <p className="uppercase tracking-wide text-gray-400">Cost</p>
                            <p className="mt-1 font-semibold text-gray-900 dark:text-gray-100">
                              {formatMoney(
                                payload.summary.totalCostCents,
                                payload.summary.baseCurrency,
                              )}
                            </p>
                          </div>
                          <div className="rounded-2xl bg-gray-50 dark:bg-gray-900 px-3 py-2">
                            <p className="uppercase tracking-wide text-gray-400">Price</p>
                            <p className="mt-1 font-semibold text-gray-900 dark:text-gray-100">
                              {formatMoney(
                                payload.summary.totalPriceCents,
                                payload.summary.baseCurrency,
                              )}
                            </p>
                          </div>
                          <div className="rounded-2xl bg-gray-50 dark:bg-gray-900 px-3 py-2">
                            <p className="uppercase tracking-wide text-gray-400">Margin</p>
                            <p className="mt-1 font-semibold text-gray-900 dark:text-gray-100">
                              {payload.summary.marginPercent.toFixed(0)}%
                            </p>
                          </div>
                        </div>
                      ) : (
                        <p className="mt-3 text-xs text-amber-700 dark:text-amber-300">
                          Legacy export record detected. Regenerate it to get downloadable serializer output.
                        </p>
                      )}
                    </div>

                    {payload ? (
                      <button
                        type="button"
                        onClick={() => downloadEstimateExport(estimateExport)}
                        className="rounded-2xl border border-brand-200 bg-white dark:bg-gray-800 px-3 py-2 text-sm font-semibold text-brand-700 transition hover:border-brand-300 hover:bg-brand-50"
                      >
                        Download
                      </button>
                    ) : null}
                  </div>

                  {payload?.previewText ? (
                    <pre className="mt-4 overflow-x-auto rounded-2xl bg-gray-950/95 p-4 text-xs text-gray-100">
                      {payload.previewText}
                    </pre>
                  ) : null}
                </div>
              );
            })}
          </div>
        )}
      </div>
    </div>
  );
}
