"use client";

import { useCallback, useState } from "react";
import { useTranslation } from "react-i18next";
import { useAsyncEffect } from "@/hooks/use-async-effect";
import { useTranslationRef } from "@/hooks/use-translation-ref";
import { toast } from "sonner";
import { Download, RefreshCw } from "lucide-react";

import { downloadAdminReportJob, getAdminReportJobs } from "@/api/admin-report-jobs";
import { AdminRowActionsMenu } from "@/components/admin/admin-row-actions-menu";
import { AdminTableNoResourceRow } from "@/components/admin/admin-no-resource-state";
import { AdminStatusBadge } from "@/components/admin/admin-status-badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { AdminTableLoadingRow } from "@/components/admin/admin-loading-state";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { useAdminDateTimeFormatter } from "@/hooks/use-admin-datetime-formatter";
import { LotteryApiBizError } from "@/types/api/errors";
import type { AdminReportJobRow } from "@/types/api/admin-report-jobs";

function downloadBlob(blob: Blob, filename: string): void {
  const url = URL.createObjectURL(blob);
  const anchor = document.createElement("a");
  anchor.href = url;
  anchor.download = filename;
  document.body.appendChild(anchor);
  anchor.click();
  anchor.remove();
  URL.revokeObjectURL(url);
}

type ReportJobsPanelProps = {
  canExport: boolean;
  refreshToken?: number;
  reportType?: string;
};

export function ReportJobsPanel({ canExport, refreshToken = 0, reportType }: ReportJobsPanelProps) {
  const { t } = useTranslation(["reports", "common"]);
  const tRef = useTranslationRef(["reports", "common"]);
  const formatTs = useAdminDateTimeFormatter();
  const [jobs, setJobs] = useState<AdminReportJobRow[]>([]);
  const [loading, setLoading] = useState(true);
  const [downloadingId, setDownloadingId] = useState<number | null>(null);

  const loadJobs = useCallback(async () => {
    setLoading(true);
    try {
      const data = await getAdminReportJobs({ page: 1, per_page: 10, report_type: reportType || undefined });
      setJobs(data.items);
    } catch (e) {
      toast.error(e instanceof LotteryApiBizError ? e.message : tRef.current("tasks.loadFailed"));
      setJobs([]);
    } finally {
      setLoading(false);
    }
  }, [reportType, tRef]);

  useAsyncEffect(() => {
    void loadJobs();
  }, [refreshToken]);

  async function handleDownload(job: AdminReportJobRow): Promise<void> {
    if (!canExport || job.status !== "completed") {
      return;
    }
    setDownloadingId(job.id);
    try {
      const { blob, filename } = await downloadAdminReportJob(job.id);
      const fallback = `${job.job_no}.${job.export_format}`;
      downloadBlob(blob, filename ?? fallback);
      toast.success(t("tasks.downloadSuccess", { jobNo: job.job_no }));
    } catch (e) {
      toast.error(e instanceof LotteryApiBizError ? e.message : t("tasks.downloadFailed"));
    } finally {
      setDownloadingId(null);
    }
  }

  function reportTypeLabel(reportType: string): string {
    const key = `jobTypes.${reportType}`;
    const label = t(key);
    return label === key ? reportType : label;
  }

  return (
    <Card className="admin-list-card">
      <CardHeader className="admin-list-header flex flex-row items-center justify-between gap-3 pb-4">
        <CardTitle className="admin-list-title">{t("recentTasks")}</CardTitle>
        <Button type="button" variant="outline" size="sm" disabled={loading} onClick={() => void loadJobs()}>
          <RefreshCw data-icon="inline-start" className={loading ? "animate-spin" : undefined} />
          {t("tasks.refresh")}
        </Button>
      </CardHeader>
      <CardContent className="pt-2">
        <p className="mb-3 text-xs text-muted-foreground">
          {reportType ? t("tasks.currentReportHint") : t("exportHint")}
        </p>
        <Table>
          <TableHeader>
            <TableRow>
              <TableHead>{t("tasks.columns.jobNo")}</TableHead>
              <TableHead>{t("tasks.columns.report")}</TableHead>
              <TableHead>{t("tasks.columns.format")}</TableHead>
              <TableHead>{t("tasks.columns.status")}</TableHead>
              <TableHead>{t("tasks.columns.createdAt")}</TableHead>
              <TableHead className="sticky right-0 z-20 bg-muted w-14 text-center shadow-[-1px_0_0_rgba(203,213,225,0.7)]">{t("tasks.columns.actions")}</TableHead>
            </TableRow>
          </TableHeader>
          <TableBody>
            {loading ? (
              <AdminTableLoadingRow colSpan={6} />
            ) : jobs.length === 0 ? (
              <AdminTableNoResourceRow colSpan={6} />
            ) : (
              jobs.map((job) => (
                <TableRow key={job.id}>
                  <TableCell className="font-mono text-xs">{job.job_no}</TableCell>
                  <TableCell className="text-sm">{reportTypeLabel(job.report_type)}</TableCell>
                  <TableCell className="uppercase">{job.export_format}</TableCell>
                  <TableCell>
                    <AdminStatusBadge status={job.status}>
                      {t(`tasks.status.${job.status}`, { defaultValue: job.status })}
                    </AdminStatusBadge>
                  </TableCell>
                  <TableCell className="text-xs text-muted-foreground">
                    {formatTs(job.created_at ?? job.finished_at)}
                  </TableCell>
                  <TableCell className="sticky right-0 z-10 bg-card text-center shadow-[-1px_0_0_rgba(203,213,225,0.7)]">
                    <AdminRowActionsMenu
                      busy={downloadingId === job.id}
                      actions={[
                        {
                          key: "download",
                          label: t("tasks.download"),
                          icon: Download,
                          disabled: !canExport || job.status !== "completed",
                          onClick: () => void handleDownload(job),
                        },
                      ]}
                    />
                  </TableCell>
                </TableRow>
              ))
            )}
          </TableBody>
        </Table>
      </CardContent>
    </Card>
  );
}
