import { useState } from "react";
import { Loader2 } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Textarea } from "@/components/ui/textarea";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Progress } from "@/components/ui/progress";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { useContentJob } from "@/hooks/useContentJob";
import { getContentJobAsset } from "@/api/contentJobs";
import type { IconSetBundle } from "@/types/content-bundles";
import { IconResultGrid } from "./IconResultGrid";
import { IconDownloadBar } from "./IconDownloadBar";

const STYLE_OPTIONS = [
  { value: "outline", label: "Outline" },
  { value: "filled", label: "Filled" },
  { value: "rounded", label: "Rounded" },
];

const COUNT_OPTIONS = [
  { value: "1", label: "1" },
  { value: "4", label: "4" },
  { value: "8", label: "8" },
  { value: "16", label: "16" },
];

interface IconGeneratePanelProps {
  companyId: string;
}

export function IconGeneratePanel({ companyId }: IconGeneratePanelProps) {
  const [description, setDescription] = useState("");
  const [style, setStyle] = useState("outline");
  const [count, setCount] = useState("4");
  const [bundle, setBundle] = useState<IconSetBundle | null>(null);
  const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set());
  const job = useContentJob(companyId);

  const isGenerating = job.status === "queued" || job.status === "running";
  const isIdle = job.status === "idle";

  async function handleSubmit() {
    if (!description.trim() || isGenerating) return;
    setBundle(null);
    setSelectedIds(new Set());
    await job.submit("icon-set", { description, style, count: parseInt(count, 10) });
  }

  // Fetch asset when job completes
  if (job.status === "done" && job.resultAssetId && !bundle) {
    void getContentJobAsset(companyId, job.resultAssetId).then(async (assetUrl) => {
      const res = await fetch(assetUrl);
      const text = await res.text();
      try {
        const parsed = JSON.parse(text) as IconSetBundle;
        setBundle(parsed);
      } catch {
        // ignore parse error
      }
    });
  }

  function handleToggleIcon(name: string) {
    setSelectedIds((prev) => {
      const next = new Set(prev);
      if (next.has(name)) {
        next.delete(name);
      } else {
        next.add(name);
      }
      return next;
    });
  }

  function handleDownload(format: string) {
    if (!bundle) return;
    const selected = bundle.icons.filter((icon) => selectedIds.has(icon.name));
    for (const icon of selected) {
      let blobData: Blob;
      let filename: string;

      if (format === "svg") {
        blobData = new Blob([icon.svgSource], { type: "image/svg+xml" });
        filename = `${icon.name}.svg`;
      } else {
        const sizeMap: Record<string, string> = { "png-16": "16", "png-32": "32", "png-64": "64" };
        const size = sizeMap[format] ?? "32";
        const pngData = icon.pngs[size];
        if (!pngData) continue;
        const byteString = atob(pngData);
        const ab = new ArrayBuffer(byteString.length);
        const ia = new Uint8Array(ab);
        for (let i = 0; i < byteString.length; i++) {
          ia[i] = byteString.charCodeAt(i);
        }
        blobData = new Blob([ab], { type: "image/png" });
        filename = `${icon.name}-${size}.png`;
      }

      const url = URL.createObjectURL(blobData);
      const a = document.createElement("a");
      a.href = url;
      a.download = filename;
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      URL.revokeObjectURL(url);
    }
  }

  function handleClearSelection() {
    setSelectedIds(new Set());
  }

  return (
    <Card className="w-full">
      <CardHeader>
        <CardTitle className="text-xl font-semibold">Generate Icons</CardTitle>
      </CardHeader>
      <CardContent className="flex flex-col gap-4">
        <div className="flex flex-col gap-2">
          <label htmlFor="icon-description" className="text-sm font-medium">
            Describe your icons
          </label>
          <Textarea
            id="icon-description"
            rows={3}
            placeholder="Describe what you need..."
            value={description}
            onChange={(e) => setDescription(e.target.value)}
            disabled={isGenerating}
          />
        </div>

        <div className="flex gap-3">
          <div className="flex flex-col gap-2 flex-1">
            <label htmlFor="icon-style" className="text-sm font-medium">
              Style
            </label>
            <Select value={style} onValueChange={setStyle} disabled={isGenerating}>
              <SelectTrigger id="icon-style" className="w-full">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                {STYLE_OPTIONS.map((opt) => (
                  <SelectItem key={opt.value} value={opt.value}>
                    {opt.label}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>

          <div className="flex flex-col gap-2 flex-1">
            <label htmlFor="icon-count" className="text-sm font-medium">
              Count
            </label>
            <Select value={count} onValueChange={setCount} disabled={isGenerating}>
              <SelectTrigger id="icon-count" className="w-full">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                {COUNT_OPTIONS.map((opt) => (
                  <SelectItem key={opt.value} value={opt.value}>
                    {opt.label}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
        </div>

        <Button
          type="button"
          onClick={() => void handleSubmit()}
          disabled={isGenerating || !description.trim()}
          className="w-full"
        >
          {isGenerating ? (
            <>
              <Loader2 className="mr-2 size-4 animate-spin" aria-hidden="true" />
              Generating...
            </>
          ) : (
            "Generate Icons"
          )}
        </Button>

        {isGenerating && (
          <Progress
            value={job.progress}
            role="progressbar"
            aria-valuenow={job.progress}
            aria-valuemin={0}
            aria-valuemax={100}
            aria-label="Icon generation progress"
          />
        )}

        {job.status === "failed" && job.errorMessage && (
          <p className="text-sm text-destructive">
            Render failed — {job.errorMessage}. Try again.
          </p>
        )}

        {bundle && bundle.icons.length > 0 ? (
          <>
            <IconResultGrid
              icons={bundle.icons}
              selectedIds={selectedIds}
              onToggle={handleToggleIcon}
            />
            <IconDownloadBar
              selectedCount={selectedIds.size}
              onDownload={handleDownload}
              onClear={handleClearSelection}
            />
          </>
        ) : isIdle ? (
          <div className="flex flex-col items-center gap-2 py-8 text-center">
            <p className="text-xl font-semibold">No icons yet</p>
            <p className="text-sm text-muted-foreground">
              Describe what you need and we'll generate a cohesive set.
            </p>
          </div>
        ) : null}
      </CardContent>
    </Card>
  );
}
