'use client';

import { useState, useEffect, useCallback, useRef } from 'react';
import { Sparkles, Copy, Check, X, Lock, Unlock, Play, RefreshCw, Loader2 } from 'lucide-react';
import { Button } from '@/components/ui/Button';
import { Textarea } from '@/components/ui/Input';
import type { Personaje, CharacterAsset, CharacterAssetsData } from '@/types/project';

interface CharacterAssetsPanelProps {
  personaje: Personaje;
  slug: string;
  onClose: () => void;
}

const API_BASE = (slug: string, id: string) =>
  `/api/projects/${slug}/personajes/${id}/assets`;

export function CharacterAssetsPanel({ personaje, slug, onClose }: CharacterAssetsPanelProps) {
  const [data, setData] = useState<CharacterAssetsData>({ assets: [], baseLocked: false });
  const [loading, setLoading] = useState<string | null>(null);
  const [fetching, setFetching] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [copiedId, setCopiedId] = useState<string | null>(null);
  const [basePromptEdit, setBasePromptEdit] = useState('');
  const [imgVersion, setImgVersion] = useState(0);
  const abortRef = useRef(false);

  const url = API_BASE(slug, personaje.id);

  const fetchData = useCallback(async () => {
    setFetching(true);
    try {
      const res = await fetch(url);
      if (res.ok) {
        const d = await res.json();
        setData(d);
        setImgVersion(v => v + 1);
        const base = d.assets?.find((a: CharacterAsset) => a.isBase);
        if (base) setBasePromptEdit(base.prompt || '');
      }
    } catch (e) {
      console.error('Error fetching assets:', e);
    } finally {
      setFetching(false);
    }
  }, [url]);

  useEffect(() => { fetchData(); }, [fetchData]);

  // Cleanup: abort batch generation on unmount
  useEffect(() => {
    return () => { abortRef.current = true; };
  }, []);

  const postAction = async (action: string, extra?: Record<string, any>): Promise<CharacterAssetsData | null> => {
    const loadingKey = extra?.assetId || action;
    setLoading(loadingKey);
    setError(null);
    try {
      const res = await fetch(url, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ action, ...extra }),
      });
      const d = await res.json();
      if (!res.ok) { setError(d.error || `Error ${res.status}`); return null; }
      setData(d);
      setImgVersion(v => v + 1);
      const base = d.assets?.find((a: CharacterAsset) => a.isBase);
      if (base) setBasePromptEdit(base.prompt || '');
      return d;
    } catch (e: any) {
      setError(e.message || 'Error de conexión');
      return null;
    } finally {
      setLoading(null);
    }
  };

  const generateAllVariations = async () => {
    const pending = data.assets.filter(a => !a.isBase && a.status !== 'generated');
    if (pending.length === 0) return;
    abortRef.current = false;

    for (const asset of pending) {
      if (abortRef.current) break;
      const result = await postAction('generate-variation', { assetId: asset.id });
      if (!result) break;
    }
  };

  const copyPrompt = (asset: CharacterAsset) => {
    navigator.clipboard.writeText(asset.prompt);
    setCopiedId(asset.id);
    setTimeout(() => setCopiedId(null), 2000);
  };

  const { assets, baseLocked } = data;
  const baseAsset = assets.find(a => a.isBase);
  const otherAssets = assets.filter(a => !a.isBase);
  const tposeOthers = otherAssets.filter(a => a.type === 'tpose');
  const emotionAssets = otherAssets.filter(a => a.type === 'emotion');
  const generatedCount = assets.filter(a => a.status === 'generated').length;

  // Determine current workflow step
  const step = assets.length === 0 ? 0
    : !baseAsset?.imageUrl ? 1
    : !baseLocked ? 2
    : 3;

  return (
    <div className="fixed inset-0 bg-black/40 backdrop-blur-sm flex items-center justify-center z-50 p-4">
      <div className="bg-white rounded-lg shadow-xl shadow-black/10 max-w-4xl w-full max-h-[90vh] overflow-hidden">
        {/* Header */}
        <div className="flex items-center justify-between px-5 py-4 border-b border-stone-100">
          <div className="flex items-center gap-3">
            <h2 className="text-base font-semibold text-stone-900">{personaje.nombre}</h2>
            <span className="text-[11px] font-medium text-stone-400 uppercase tracking-wider">Character Assets</span>
            {assets.length > 0 && (
              <span className="text-[10px] text-stone-400">{generatedCount}/{assets.length} generados</span>
            )}
          </div>
          <button onClick={onClose} className="p-1 text-stone-400 hover:text-stone-600 transition-colors">
            <X className="w-4 h-4" />
          </button>
        </div>

        {/* Stepper */}
        {assets.length > 0 && (
          <div className="px-5 py-2 bg-stone-50/50 border-b border-stone-100 flex items-center gap-6 text-[11px]">
            {['Prompts', 'Imagen base', 'Fijar base', 'Variaciones'].map((label, i) => (
              <div key={label} className={`flex items-center gap-1.5 ${
                i === step ? 'text-indigo-600 font-semibold' : i < step ? 'text-emerald-600' : 'text-stone-300'
              }`}>
                <span className={`w-4 h-4 rounded-full text-[10px] flex items-center justify-center font-bold ${
                  i < step ? 'bg-emerald-100 text-emerald-600' : i === step ? 'bg-indigo-100 text-indigo-600' : 'bg-stone-100 text-stone-400'
                }`}>{i < step ? '✓' : i + 1}</span>
                {label}
              </div>
            ))}
          </div>
        )}

        {/* Error */}
        {error && (
          <div className="mx-5 mt-3 text-xs text-red-600 bg-red-50 px-3 py-2 rounded">{error}</div>
        )}

        <div className="p-5 overflow-y-auto max-h-[calc(90vh-160px)]">
          {fetching ? (
            <div className="flex items-center justify-center py-12">
              <div className="animate-spin w-5 h-5 border-2 border-indigo-600 border-t-transparent rounded-full" />
            </div>

          /* Step 0: No prompts yet */
          ) : step === 0 ? (
            <div className="text-center py-12">
              <p className="text-stone-500 text-sm mb-1">Sin prompts de assets.</p>
              <p className="text-stone-400 text-xs mb-5">
                Genera prompts para T-pose y emociones usando IA.
              </p>
              <Button onClick={() => postAction('generate-prompts')} loading={loading === 'generate-prompts'}>
                <Sparkles className="w-4 h-4" />
                Generar prompts de assets
              </Button>
            </div>

          /* Steps 1-3: Has prompts */
          ) : (
            <div className="space-y-6">

              {/* BASE IMAGE SECTION */}
              <div className={`border rounded-lg p-4 ${
                baseLocked ? 'border-emerald-200 bg-emerald-50/30' : 'border-indigo-200 bg-indigo-50/30'
              }`}>
                <div className="flex items-center gap-2 mb-3">
                  {baseLocked ? <Lock className="w-3.5 h-3.5 text-emerald-500" /> : <Unlock className="w-3.5 h-3.5 text-indigo-500" />}
                  <span className="text-xs font-semibold text-stone-700">Imagen Base (Referencia Canónica)</span>
                  {baseLocked && <span className="text-[10px] text-emerald-600 font-medium">Fijada</span>}
                </div>

                <div className="flex gap-4">
                  {/* Base image preview */}
                  <div className="w-48 flex-shrink-0">
                    {baseAsset?.imageUrl ? (
                      <div className="aspect-square bg-white rounded-lg border border-stone-200 overflow-hidden relative group/base">
                        <img src={`${baseAsset.imageUrl}?v=${imgVersion}`} alt="Base" className="w-full h-full object-cover" />
                        {loading === 'generate-base-image' && (
                          <div className="absolute inset-0 flex items-center justify-center bg-black/40">
                            <Loader2 className="w-5 h-5 text-white animate-spin" />
                          </div>
                        )}
                      </div>
                    ) : loading === 'generate-base-image' ? (
                      <div className="aspect-square bg-white rounded-lg border border-stone-200 flex items-center justify-center">
                        <Loader2 className="w-5 h-5 text-indigo-400 animate-spin" />
                      </div>
                    ) : (
                      <div className="aspect-square bg-white rounded-lg border border-stone-200 flex items-center justify-center">
                        <span className="text-xs text-stone-300">Sin imagen</span>
                      </div>
                    )}
                  </div>

                  {/* Controls */}
                  <div className="flex-1 space-y-3">
                    {!baseLocked && (
                      <>
                        <div>
                          <label className="text-[11px] font-medium text-stone-500 mb-1 block">Prompt (editable)</label>
                          <Textarea
                            value={basePromptEdit}
                            onChange={(e) => setBasePromptEdit(e.target.value)}
                            rows={4}
                            className="text-xs"
                          />
                        </div>
                        <div className="flex gap-2">
                          <Button
                            size="sm"
                            onClick={() => postAction('generate-base-image', { prompt: basePromptEdit })}
                            loading={loading === 'generate-base-image'}
                          >
                            {baseAsset?.imageUrl ? <RefreshCw className="w-3.5 h-3.5" /> : <Sparkles className="w-3.5 h-3.5" />}
                            {baseAsset?.imageUrl ? 'Regenerar' : 'Generar imagen base'}
                          </Button>
                          {baseAsset?.imageUrl && baseAsset.status === 'generated' && (
                            <Button
                              size="sm"
                              variant="secondary"
                              onClick={() => postAction('lock-base')}
                              loading={loading === 'lock-base'}
                            >
                              <Lock className="w-3.5 h-3.5" />
                              Fijar como referencia
                            </Button>
                          )}
                        </div>
                      </>
                    )}
                    {baseLocked && (
                      <p className="text-xs text-stone-500">
                        Imagen fijada como referencia. Las variaciones se generarán a partir de esta imagen.
                      </p>
                    )}
                  </div>
                </div>
              </div>

              {/* VARIATIONS SECTION */}
              {baseLocked && (
                <>
                  <div className="flex items-center justify-between">
                    <span className="text-xs font-semibold text-stone-700">Variaciones</span>
                    <Button
                      size="sm"
                      onClick={generateAllVariations}
                      loading={!!loading}
                      disabled={otherAssets.every(a => a.status === 'generated')}
                    >
                      <Play className="w-3.5 h-3.5" />
                      Generar todas las variaciones
                    </Button>
                  </div>

                  {/* Other T-Poses */}
                  {tposeOthers.length > 0 && (
                    <div>
                      <span className="text-[11px] font-medium text-stone-400 uppercase tracking-wider block mb-2">T-Pose</span>
                      <div className="grid grid-cols-4 gap-3">
                        {tposeOthers.map(asset => (
                          <AssetCard
                            key={asset.id}
                            asset={asset}
                            imgVersion={imgVersion}
                            copiedId={copiedId}
                            onCopy={copyPrompt}
                            onGenerate={() => postAction('generate-variation', { assetId: asset.id })}
                            generating={loading === asset.id}
                            canGenerate={baseLocked && !loading}
                          />
                        ))}
                      </div>
                    </div>
                  )}

                  {/* Emotions */}
                  {emotionAssets.length > 0 && (
                    <div>
                      <span className="text-[11px] font-medium text-stone-400 uppercase tracking-wider block mb-2">Emociones</span>
                      <div className="grid grid-cols-4 gap-3">
                        {emotionAssets.map(asset => (
                          <AssetCard
                            key={asset.id}
                            asset={asset}
                            imgVersion={imgVersion}
                            copiedId={copiedId}
                            onCopy={copyPrompt}
                            onGenerate={() => postAction('generate-variation', { assetId: asset.id })}
                            generating={loading === asset.id}
                            canGenerate={baseLocked && !loading}
                          />
                        ))}
                      </div>
                    </div>
                  )}
                </>
              )}

              {/* Pre-lock: show all assets as prompt list */}
              {!baseLocked && assets.length > 1 && (
                <div>
                  <span className="text-[11px] font-medium text-stone-400 uppercase tracking-wider block mb-2">
                    Prompts pendientes ({otherAssets.length} variaciones)
                  </span>
                  <div className="grid grid-cols-4 gap-3">
                    {otherAssets.map(asset => (
                      <AssetCard
                        key={asset.id}
                        asset={asset}
                        imgVersion={imgVersion}
                        copiedId={copiedId}
                        onCopy={copyPrompt}
                        canGenerate={false}
                      />
                    ))}
                  </div>
                </div>
              )}

              {/* Regenerate prompts */}
              <div className="pt-3 border-t border-stone-100 flex justify-end">
                <Button
                  variant="ghost"
                  size="sm"
                  onClick={() => postAction('generate-prompts')}
                  loading={loading === 'generate-prompts'}
                >
                  <RefreshCw className="w-3 h-3" />
                  Regenerar todos los prompts
                </Button>
              </div>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

function AssetCard({
  asset,
  imgVersion,
  copiedId,
  onCopy,
  onGenerate,
  generating,
  canGenerate,
}: {
  asset: CharacterAsset;
  imgVersion: number;
  copiedId: string | null;
  onCopy: (asset: CharacterAsset) => void;
  onGenerate?: () => void;
  generating?: boolean;
  canGenerate?: boolean;
}) {
  const isCopied = copiedId === asset.id;

  const statusColors: Record<string, string> = {
    pending: 'bg-stone-300',
    prompt_ready: 'bg-amber-400',
    generating: 'bg-blue-400 animate-pulse',
    generated: 'bg-emerald-400',
  };

  return (
    <div className="border border-stone-200 rounded-lg p-2.5 group">
      <div className="flex items-center justify-between mb-1.5">
        <div className="flex items-center gap-1.5">
          <div className={`w-1.5 h-1.5 rounded-full ${statusColors[asset.status] || 'bg-stone-300'}`} />
          <span className="text-[11px] font-medium text-stone-700">{asset.label}</span>
        </div>
      </div>

      {asset.imageUrl ? (
        <div className="aspect-square bg-stone-50 rounded border border-stone-100 mb-1.5 overflow-hidden relative group/img">
          <img src={`${asset.imageUrl}?v=${imgVersion}`} alt={asset.label} className="w-full h-full object-cover" />
          {generating ? (
            <div className="absolute inset-0 flex items-center justify-center bg-black/40">
              <Loader2 className="w-4 h-4 text-white animate-spin" />
            </div>
          ) : canGenerate && onGenerate ? (
            <button
              onClick={onGenerate}
              className="absolute inset-0 flex items-center justify-center bg-black/40 opacity-0 group-hover/img:opacity-100 transition-opacity"
            >
              <RefreshCw className="w-4 h-4 text-white" />
            </button>
          ) : null}
        </div>
      ) : generating ? (
        <div className="aspect-square bg-stone-50 rounded border border-stone-100 mb-1.5 flex items-center justify-center">
          <Loader2 className="w-4 h-4 text-indigo-400 animate-spin" />
        </div>
      ) : (
        <div className="aspect-square bg-stone-50 rounded border border-stone-100 mb-1.5 flex flex-col items-center justify-center gap-1">
          {canGenerate && onGenerate ? (
            <button
              onClick={onGenerate}
              className="text-[10px] text-indigo-500 hover:text-indigo-700 font-medium"
            >
              Generar
            </button>
          ) : (
            <span className="text-[10px] text-stone-300">Pendiente</span>
          )}
        </div>
      )}

      {asset.prompt && (
        <div className="flex gap-1">
          <p className="text-[9px] text-stone-400 leading-tight flex-1 line-clamp-2">{asset.prompt}</p>
          <button
            onClick={() => onCopy(asset)}
            className="flex-shrink-0 p-0.5 text-stone-300 hover:text-indigo-500 transition-colors"
            title="Copiar prompt"
          >
            {isCopied ? <Check className="w-2.5 h-2.5 text-emerald-500" /> : <Copy className="w-2.5 h-2.5" />}
          </button>
        </div>
      )}
    </div>
  );
}
