import { gitArchive, gitRefTarget } from "@/client";
import type { ArchiveResponse } from "@/client";
import { Button } from "@/components/ui/button";
import { useMutation, useQuery } from "@tanstack/react-query";
import {
  Archive,
  Download,
  Loader2,
} from "lucide-react";
import { useParams } from "react-router-dom";
import { toast } from "sonner";
import { useRepo } from "@/contexts";
import {getApiErrorMessage} from '@/lib/api-error';

export function RepoSettingsArchive() {
  const repo = useRepo();
  const { namespace, repoName } = useParams<{ namespace: string; repoName: string }>();
  const ns = namespace!;
  const rn = repoName!;
  const defaultBranch = repo?.default_branch ?? "main";

  const { data: refData } = useQuery({
    queryKey: ["ref-target", ns, rn, defaultBranch],
    queryFn: async () => {
      const resp = await gitRefTarget({
        path: { namespace: ns, repo: rn, name: `refs/heads/${defaultBranch}` },
      });
      return resp.data?.data ?? null;
    },
    enabled: !!ns && !!rn && !!defaultBranch,
    staleTime: 60 * 1000,
  });

  const headOid = refData?.oid ?? "";

  const downloadMutation = useMutation({
    mutationFn: async (format: string) => {
      if (!headOid) throw new Error("No commit OID available");
      const resp = await gitArchive({
        path: { namespace: ns, repo: rn },
        query: { commit_oid: headOid, format },
      });
      return { format, data: resp.data?.data as ArchiveResponse };
    },
    onSuccess: ({ format, data }) => {
      if (!data?.data) return;
      const blob = new Blob(
        [Uint8Array.from(atob(data.data), (c) => c.charCodeAt(0))],
        { type: "application/octet-stream" }
      );
      const url = URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      a.download = `${repoName}-${defaultBranch}.${format}`;
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      URL.revokeObjectURL(url);
      toast.success(`Downloaded ${repoName}.${format}`);
    },
    onError: (err: unknown) => {
      toast.error(getApiErrorMessage(err, "Download failed"));
    },
  });

  const formats = [
    { label: "zip", desc: "ZIP archive" },
    { label: "tar.gz", desc: "Gzip compressed tar" },
    { label: "tar.bz2", desc: "Bzip2 compressed tar" },
    { label: "tar", desc: "Uncompressed tar" },
  ];

  return (
    <div className="border rounded-lg bg-card">
      <div className="p-4 border-b">
        <h2 className="text-sm font-semibold">Download Archive</h2>
        <p className="text-xs text-muted-foreground mt-0.5">
          Download a snapshot of {defaultBranch} in various archive formats
        </p>
      </div>
      <div className="p-4">
        <div className="grid grid-cols-2 gap-3">
          {formats.map((f) => (
            <div key={f.label} className="border rounded-md p-3 flex items-center gap-3">
              <Archive className="h-6 w-6 text-muted-foreground flex-shrink-0" />
              <div className="flex-1 min-w-0">
                <p className="font-medium text-sm">.{f.label}</p>
                <p className="text-xs text-muted-foreground">{f.desc}</p>
              </div>
              <Button
                size="sm"
                variant="outline"
                onClick={() => downloadMutation.mutate(f.label)}
                disabled={downloadMutation.isPending || !headOid}
              >
                {downloadMutation.isPending && downloadMutation.variables === f.label ? (
                  <Loader2 className="h-3.5 w-3.5 mr-1 animate-spin" />
                ) : (
                  <Download className="h-3.5 w-3.5 mr-1" />
                )}
                Download
              </Button>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}
