"use client";

import { useState } from "react";
import {
  Copy, Download, Heart, ChevronLeft, ChevronRight,
  FileText, Code2, Film, ScrollText, Check, BookmarkPlus, X, Loader2
} from "lucide-react";
import { toast } from "sonner";
import { cn } from "@/lib/utils";
import { copyToClipboard, downloadText, downloadJson } from "@/lib/utils";
import type { GeneratorOutput as GeneratorOutputType } from "@/lib/schemas/universal-prompt.schema";
import type { Platform } from "@/types";
import { PLATFORM_CONFIGS } from "@/types";

interface Props {
  output: GeneratorOutputType;
  platform: Platform;
  historyId: string | null;
}

type TabId = "text" | "json" | "shot_list" | "script";

const TABS: { id: TabId; label: string; icon: React.ReactNode }[] = [
  { id: "text", label: "Text", icon: <FileText className="w-3.5 h-3.5" /> },
  { id: "json", label: "JSON", icon: <Code2 className="w-3.5 h-3.5" /> },
  { id: "shot_list", label: "Shot List", icon: <Film className="w-3.5 h-3.5" /> },
  { id: "script", label: "Script", icon: <ScrollText className="w-3.5 h-3.5" /> },
];

// ─── Save as Template Modal ───────────────────────────────────────────────────
function SaveTemplateModal({
  output,
  platform,
  onClose,
}: {
  output: GeneratorOutputType;
  platform: Platform;
  onClose: () => void;
}) {
  const [name, setName] = useState("");
  const [description, setDescription] = useState("");
  const [isPublic, setIsPublic] = useState(false);
  const [saving, setSaving] = useState(false);

  // Build input_data from first variation's jsonOutput + metadata
  const inputData = output.variations[0]?.jsonOutput ?? {};

  async function handleSave() {
    if (!name.trim()) {
      toast.error("Nama template wajib diisi");
      return;
    }
    setSaving(true);
    try {
      const res = await fetch("/api/templates", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          platform,
          name: name.trim(),
          description: description.trim() || null,
          input_data: inputData,
          is_public: isPublic,
          tags: [platform],
        }),
      });
      const data = await res.json();
      if (!res.ok) {
        toast.error(data.error ?? "Gagal menyimpan template");
        return;
      }
      toast.success("Template berhasil disimpan! 🎉");
      onClose();
    } finally {
      setSaving(false);
    }
  }

  return (
    <div
      className="fixed inset-0 bg-background/80 backdrop-blur-sm z-50 flex items-center justify-center p-4"
      onClick={(e) => { if (e.target === e.currentTarget) onClose(); }}
    >
      <div
        role="dialog"
        aria-modal="true"
        aria-labelledby="save-template-title"
        className="bg-card border border-border rounded-2xl p-6 w-full max-w-md"
        onKeyDown={(e) => { if (e.key === "Escape") onClose(); }}
      >
        <div className="flex items-center justify-between mb-4">
          <h2 id="save-template-title" className="font-bold text-lg">Simpan sebagai Template</h2>
          <button
            onClick={onClose}
            aria-label="Tutup modal"
            className="w-8 h-8 rounded-lg flex items-center justify-center hover:bg-accent text-muted-foreground"
          >
            <X className="w-4 h-4" />
          </button>
        </div>

        <div className="space-y-4">
          <div>
            <label htmlFor="template-name" className="text-sm font-medium mb-1.5 block">
              Nama Template <span className="text-red-400" aria-hidden="true">*</span>
            </label>
            <input
              id="template-name"
              value={name}
              onChange={(e) => setName(e.target.value)}
              placeholder="Contoh: Cinematic Portrait 4K"
              className="w-full px-3 py-2.5 rounded-lg bg-accent border border-border focus:border-primary focus:outline-none text-sm"
            />
          </div>

          <div>
            <label htmlFor="template-desc" className="text-sm font-medium mb-1.5 block">Deskripsi (opsional)</label>
            <textarea
              id="template-desc"
              value={description}
              onChange={(e) => setDescription(e.target.value)}
              placeholder="Jelaskan kapan template ini berguna..."
              rows={2}
              className="w-full px-3 py-2.5 rounded-lg bg-accent border border-border focus:border-primary focus:outline-none text-sm resize-none"
            />
          </div>

          <div className="flex items-center gap-2.5">
            <button
              type="button"
              id="toggle-public"
              role="switch"
              aria-checked={isPublic}
              onClick={() => setIsPublic(!isPublic)}
              onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); setIsPublic(!isPublic); } }}
              className={cn(
                "w-10 h-5 rounded-full transition-colors relative focus:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-1 flex-shrink-0",
                isPublic ? "bg-primary" : "bg-accent"
              )}
            >
              <div className={cn(
                "w-4 h-4 bg-white rounded-full absolute top-0.5 transition-all shadow-sm",
                isPublic ? "left-5" : "left-0.5"
              )} />
            </button>
            <label htmlFor="toggle-public" className="text-sm text-muted-foreground cursor-pointer">
              Bagikan ke komunitas (publik)
            </label>
          </div>
        </div>

        <div className="flex gap-3 mt-6">
          <button
            onClick={onClose}
            className="flex-1 py-2.5 rounded-xl border border-border text-sm hover:bg-accent transition-colors"
          >
            Batal
          </button>
          <button
            onClick={handleSave}
            disabled={saving || !name.trim()}
            className="flex-1 py-2.5 rounded-xl bg-primary text-primary-foreground text-sm font-medium hover:opacity-90 transition-opacity disabled:opacity-60 flex items-center justify-center gap-2"
          >
            {saving ? (
              <><Loader2 className="w-4 h-4 animate-spin" aria-hidden="true" /> Menyimpan...</>
            ) : (
              <><BookmarkPlus className="w-4 h-4" aria-hidden="true" /> Simpan</>
            )}
          </button>
        </div>
      </div>
    </div>
  );
}

// ─── Main Component ──────────────────────────────────────────────────────────
export default function GeneratorOutput({ output, platform, historyId }: Props) {
  const [activeTab, setActiveTab] = useState<TabId>("text");
  const [variationIndex, setVariationIndex] = useState(0);
  const [isFavorite, setIsFavorite] = useState(false);
  const [copied, setCopied] = useState(false);
  const [showSaveTemplate, setShowSaveTemplate] = useState(false);

  const config = PLATFORM_CONFIGS[platform];
  const variation = output.variations[variationIndex];
  const totalVariations = output.variations.length;

  async function handleCopy() {
    const content = getTabContent();
    if (!content) return;
    await copyToClipboard(typeof content === "string" ? content : JSON.stringify(content, null, 2));
    setCopied(true);
    toast.success("Disalin ke clipboard!");
    setTimeout(() => setCopied(false), 2000);
  }

  function handleDownloadTxt() {
    const content = getTabContent();
    if (!content) return;
    const text = typeof content === "string" ? content : JSON.stringify(content, null, 2);
    downloadText(text, `promptmotion-${platform}-${Date.now()}.txt`);
    toast.success("File TXT didownload");
  }

  function handleDownloadJson() {
    const jsonContent = variation?.jsonOutput;
    if (!jsonContent) return;
    downloadJson(jsonContent, `promptmotion-${platform}-${Date.now()}.json`);
    toast.success("File JSON didownload");
  }

  async function handleFavorite() {
    if (!historyId) {
      toast.error("Simpan history terlebih dahulu");
      return;
    }
    try {
      const res = await fetch("/api/history", {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ id: historyId, is_favorite: !isFavorite }),
      });
      if (res.ok) {
        setIsFavorite(!isFavorite);
        toast.success(isFavorite ? "Dihapus dari favorit" : "Ditambahkan ke favorit ❤️");
      }
    } catch {
      toast.error("Gagal update favorit");
    }
  }

  function getTabContent(): string | Record<string, unknown> | null {
    if (!variation) return null;
    switch (activeTab) {
      case "text": return variation.textPrompt ?? null;
      case "json": return variation.jsonOutput ?? null;
      case "shot_list": return variation.shotList
        ? variation.shotList.map((s) =>
            `Shot ${s.shotNumber}: ${s.shotType}\n` +
            `Camera: ${s.cameraAngle}, ${s.cameraMovement}\n` +
            `Subject: ${s.subject} - ${s.action}\n` +
            `Duration: ${s.duration}\n` +
            (s.notes ? `Notes: ${s.notes}\n` : "")
          ).join("\n---\n")
        : null;
      case "script": return variation.script ?? null;
    }
  }

  const tabContent = getTabContent();

  return (
    <>
      <div className="glass-card rounded-2xl overflow-hidden">
        {/* Header */}
        <div className="p-4 border-b border-border/50 flex items-center justify-between">
          <div className="flex items-center gap-2">
            <span className="text-xl">{config.icon}</span>
            <div>
              <p className="text-sm font-medium">{config.name}</p>
              <p className="text-xs text-muted-foreground">
                {output.metadata.model} • {new Date(output.metadata.generatedAt).toLocaleTimeString("id-ID")}
              </p>
            </div>
          </div>

          {/* Action buttons */}
          <div className="flex items-center gap-1">
            <button
              onClick={handleFavorite}
              aria-label={isFavorite ? "Hapus dari favorit" : "Tambah ke favorit"}
              aria-pressed={isFavorite}
              className={cn(
                "w-8 h-8 rounded-lg flex items-center justify-center transition-colors",
                isFavorite ? "text-pink-400 bg-pink-500/20" : "text-muted-foreground hover:text-foreground hover:bg-accent"
              )}
            >
              <Heart className={cn("w-4 h-4", isFavorite && "fill-current")} aria-hidden="true" />
            </button>
            <button
              onClick={() => setShowSaveTemplate(true)}
              aria-label="Simpan sebagai Template"
              className="w-8 h-8 rounded-lg flex items-center justify-center text-muted-foreground hover:text-foreground hover:bg-accent transition-colors"
            >
              <BookmarkPlus className="w-4 h-4" aria-hidden="true" />
            </button>
            <button
              onClick={handleCopy}
              aria-label={copied ? "Tersalin!" : "Salin ke clipboard"}
              className="w-8 h-8 rounded-lg flex items-center justify-center text-muted-foreground hover:text-foreground hover:bg-accent transition-colors"
            >
              {copied ? <Check className="w-4 h-4 text-green-400" aria-hidden="true" /> : <Copy className="w-4 h-4" aria-hidden="true" />}
            </button>
            <button
              onClick={handleDownloadTxt}
              aria-label="Download TXT"
              className="w-8 h-8 rounded-lg flex items-center justify-center text-muted-foreground hover:text-foreground hover:bg-accent transition-colors"
            >
              <Download className="w-4 h-4" aria-hidden="true" />
            </button>
            <button
              onClick={handleDownloadJson}
              aria-label="Download JSON"
              className="px-2.5 h-8 rounded-lg flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground hover:bg-accent transition-colors"
            >
              <Code2 className="w-3.5 h-3.5" aria-hidden="true" /> JSON
            </button>
          </div>
        </div>

        {/* Variation navigation */}
        {totalVariations > 1 && (
          <div className="px-4 py-2 border-b border-border/50 flex items-center justify-between">
            <span className="text-xs text-muted-foreground">
              Variasi {variationIndex + 1} dari {totalVariations}
            </span>
            <div className="flex gap-1">
              <button
                onClick={() => setVariationIndex(Math.max(0, variationIndex - 1))}
                disabled={variationIndex === 0}
                className="w-7 h-7 rounded flex items-center justify-center hover:bg-accent disabled:opacity-40 transition-colors"
              >
                <ChevronLeft className="w-4 h-4" />
              </button>
              <div className="flex gap-1 items-center">
                {output.variations.map((_, i) => (
                  <button
                    key={i}
                    onClick={() => setVariationIndex(i)}
                    className={cn(
                      "w-1.5 h-1.5 rounded-full transition-colors",
                      i === variationIndex ? "bg-primary" : "bg-accent hover:bg-muted-foreground"
                    )}
                  />
                ))}
              </div>
              <button
                onClick={() => setVariationIndex(Math.min(totalVariations - 1, variationIndex + 1))}
                disabled={variationIndex === totalVariations - 1}
                className="w-7 h-7 rounded flex items-center justify-center hover:bg-accent disabled:opacity-40 transition-colors"
              >
                <ChevronRight className="w-4 h-4" />
              </button>
            </div>
          </div>
        )}

        {/* Tabs */}
        <div className="flex border-b border-border/50">
          {TABS.map((tab) => (
            <button
              key={tab.id}
              onClick={() => setActiveTab(tab.id)}
              className={cn(
                "flex-1 flex items-center justify-center gap-1.5 py-2.5 text-xs font-medium transition-colors",
                activeTab === tab.id
                  ? "text-primary border-b-2 border-primary bg-primary/5"
                  : "text-muted-foreground hover:text-foreground hover:bg-accent/50"
              )}
            >
              {tab.icon}
              {tab.label}
            </button>
          ))}
        </div>

        {/* Content */}
        <div className="p-4 max-h-[500px] overflow-y-auto scrollbar-thin">
          {activeTab === "text" && (
            <div>
              <div className="bg-accent/50 rounded-xl p-4 mb-4">
                <p className="text-sm leading-relaxed whitespace-pre-wrap">
                  {variation?.textPrompt ?? "—"}
                </p>
              </div>
              {variation?.negativePrompt && (
                <div>
                  <p className="text-xs font-medium text-muted-foreground mb-2">Negative Prompt</p>
                  <div className="bg-red-500/10 border border-red-500/20 rounded-xl p-3">
                    <p className="text-xs text-red-300 leading-relaxed">
                      {variation.negativePrompt}
                    </p>
                  </div>
                </div>
              )}
            </div>
          )}

          {activeTab === "json" && (
            <div className="bg-black/40 rounded-xl p-4 overflow-x-auto border border-white/5">
              <pre className="text-xs text-green-300 font-mono leading-relaxed whitespace-pre-wrap break-words">
                {JSON.stringify(variation?.jsonOutput ?? {}, null, 2)}
              </pre>
            </div>
          )}

          {activeTab === "shot_list" && (
            <div className="space-y-3">
              {variation?.shotList && variation.shotList.length > 0 ? (
                variation.shotList.map((shot, i) => (
                  <div key={i} className="bg-accent/50 rounded-xl p-3">
                    <div className="flex items-center gap-2 mb-2">
                      <span className="w-7 h-7 rounded-full bg-primary/20 text-primary text-xs font-bold flex items-center justify-center">
                        {shot.shotNumber}
                      </span>
                      <span className="font-medium text-sm">{shot.shotType}</span>
                      <span className="text-xs text-muted-foreground ml-auto">{shot.duration}</span>
                    </div>
                    <div className="grid grid-cols-2 gap-1 text-xs text-muted-foreground">
                      <span>📷 {shot.cameraAngle}</span>
                      <span>🎬 {shot.cameraMovement}</span>
                      <span>👤 {shot.subject}</span>
                      <span>🎭 {shot.action}</span>
                    </div>
                    {shot.notes && (
                      <p className="mt-2 text-xs text-muted-foreground italic">{shot.notes}</p>
                    )}
                  </div>
                ))
              ) : (
                <div className="text-center py-8 text-muted-foreground text-sm">
                  Shot list tidak tersedia untuk output ini.
                  <br />
                  <span className="text-xs">Coba gunakan Advanced Mode.</span>
                </div>
              )}
            </div>
          )}

          {activeTab === "script" && (
            <div className="bg-accent/50 rounded-xl p-4">
              <p className="text-sm leading-relaxed whitespace-pre-wrap">
                {variation?.script ?? (
                  <span className="text-muted-foreground">
                    Script tidak tersedia. Coba gunakan Advanced Mode.
                  </span>
                )}
              </p>
            </div>
          )}
        </div>
      </div>

      {/* Save Template Modal */}
      {showSaveTemplate && (
        <SaveTemplateModal
          output={output}
          platform={platform}
          onClose={() => setShowSaveTemplate(false)}
        />
      )}
    </>
  );
}
