import React, { useState, useMemo } from 'react';
import { X, Download, Film, Image as ImageIcon, Wifi, WifiOff, Zap, ChevronDown } from 'lucide-react';
import { useExportQueue, RenderFormat, ExportConfig } from '../../context/ExportQueueContext';
import { useToast } from '../ui/ToastProvider';
import { ExportJobItem } from './ExportJobItem';
import type { DesignMD, TimelineElement, TimelineLayer } from '../../types';

interface ExportModalProps {
  isOpen: boolean;
  onClose: () => void;
  designMD: DesignMD;
  textOverlay: string;
  timelineElements: TimelineElement[];
  layers: TimelineLayer[];
  durationInFrames: number;
  brandVisibility?: { logo: boolean; frame: boolean; background: boolean };
  outputFormat?: 'video' | 'image';
  aspectRatio?: string;
  onAssetSaved?: (url: string) => void;
}

const FORMAT_OPTIONS: { value: RenderFormat; label: string; icon: typeof Film; desc: string }[] = [
  { value: 'mp4', label: 'MP4', icon: Film, desc: 'Compatible con todo' },
  { value: 'webm', label: 'WebM', icon: Film, desc: 'Web optimizado' },
  { value: 'gif', label: 'GIF', icon: Film, desc: 'Animación ligera' },
  { value: 'png', label: 'PNG', icon: ImageIcon, desc: 'Imagen sin fondo' },
  { value: 'jpeg', label: 'JPEG', icon: ImageIcon, desc: 'Imagen comprimida' },
];

const RESOLUTION_PRESETS = [
  { label: '1080×1080', w: 1080, h: 1080, desc: 'Instagram Post', ratio: '1:1' },
  { label: '720×720', w: 720, h: 720, desc: 'Preview rápido', ratio: '1:1' },
  { label: '1080×1920', w: 1080, h: 1920, desc: 'Story / Reel', ratio: '9:16' },
  { label: '720×1280', w: 720, h: 1280, desc: 'Preview rápido', ratio: '9:16' },
  { label: '1920×1080', w: 1920, h: 1080, desc: 'YouTube / TV', ratio: '16:9' },
  { label: '1280×720', w: 1280, h: 720, desc: 'HD 720p', ratio: '16:9' },
  { label: '1080×1350', w: 1080, h: 1350, desc: 'Feed 4:5', ratio: '4:5' },
  { label: '720×900', w: 720, h: 900, desc: 'Preview 4:5', ratio: '4:5' },
  { label: '1440×1080', w: 1440, h: 1080, desc: 'Pantalla 4:3', ratio: '4:3' },
  { label: '960×720', w: 960, h: 720, desc: 'Preview 4:3', ratio: '4:3' },
];

/**
 * Export modal — format selection, resolution presets, and live job queue.
 */
export const ExportModal: React.FC<ExportModalProps> = ({
  isOpen,
  onClose,
  designMD,
  textOverlay,
  timelineElements,
  layers,
  durationInFrames,
  brandVisibility,
  outputFormat,
  aspectRatio,
  onAssetSaved,
}) => {
  const { jobs, activeJobs, hasActiveJobs, isConnected, startExport, cancelJob, downloadJob } = useExportQueue();

  const { showToast } = useToast();
  const [format, setFormat] = useState<RenderFormat>('mp4');
  const [fps, setFps] = useState(30);
  const [isExporting, setIsExporting] = useState(false);
  const [showAdvanced, setShowAdvanced] = useState(false);
  const [quality, setQuality] = useState<'draft' | 'standard' | 'high' | 'ultra'>('high');

  const isStill = format === 'png' || format === 'jpeg';

  // Filter resolution presets to match the template's aspect ratio
  const filteredPresets = useMemo(() => {
    if (!aspectRatio) return RESOLUTION_PRESETS;
    const matching = RESOLUTION_PRESETS.filter(p => p.ratio === aspectRatio);
    if (matching.length > 0) return matching;

    // Parse custom W:H
    const parts = aspectRatio.split(':');
    if (parts.length === 2) {
      const w = parseInt(parts[0], 10);
      const h = parseInt(parts[1], 10);
      if (!isNaN(w) && !isNaN(h)) {
        return [{
          label: `${w}x${h}`,
          w: w,
          h: h,
          desc: 'Resolución Original',
          ratio: aspectRatio
        }];
      }
    }
    return RESOLUTION_PRESETS;
  }, [aspectRatio]);

  const [resIdx, setResIdx] = useState(0);
  const selectedRes = filteredPresets[resIdx] || filteredPresets[0];

  // The app's internal timeline is always calculated at a base of 30 fps
  const BASE_FPS = 30;
  const durationSeconds = durationInFrames / BASE_FPS;
  const actualFrames = isStill ? 1 : Math.round(durationSeconds * fps);
  
  // Scale timeline elements to match selected FPS
  const scaledTimelineElements = useMemo(() => {
    const fpsScale = fps / BASE_FPS;
    if (fpsScale === 1) return timelineElements;
    
    return timelineElements.map(el => {
      const scaledEl = {
        ...el,
        startFrame: Math.round(el.startFrame * fpsScale),
        endFrame: Math.round(el.endFrame * fpsScale),
      };
      
      if (scaledEl.transitionIn) {
        scaledEl.transitionIn = {
          ...scaledEl.transitionIn,
          duration: Math.round(scaledEl.transitionIn.duration * fpsScale)
        };
      }
      return scaledEl;
    });
  }, [timelineElements, fps]);

  // Estimated file size
  const estimatedSize = useMemo(() => {
    if (isStill) return '~0.5 MB';
    const pixels = selectedRes.w * selectedRes.h;
    const bitrateMap: Record<string, number> = { mp4: 5, webm: 3, gif: 15 };
    const bitrate = bitrateMap[format] ?? 5; // MB per minute per megapixel
    const mp = pixels / 1_000_000;
    const sizeMB = (durationSeconds / 60) * bitrate * mp;
    return sizeMB < 1 ? `~${Math.round(sizeMB * 1024)} KB` : `~${sizeMB.toFixed(1)} MB`;
  }, [format, selectedRes, durationSeconds, fps, isStill]);

  // Auto-select image format in image mode
  const filteredFormats = useMemo(() => {
    if (outputFormat === 'image') {
      return FORMAT_OPTIONS.filter(f => f.value === 'png' || f.value === 'jpeg');
    }
    return FORMAT_OPTIONS;
  }, [outputFormat]);

  // Ensure selected format is valid for the current mode
  React.useEffect(() => {
    if (!filteredFormats.find(f => f.value === format)) {
      setFormat(filteredFormats[0].value);
    }
  }, [filteredFormats, format]);

  const handleExport = async () => {
    setIsExporting(true);
    try {
      const config: ExportConfig = {
        format,
        width: selectedRes.w,
        height: selectedRes.h,
        fps,
        durationInFrames: actualFrames,
        designMD,
        textOverlay,
        timelineElements: scaledTimelineElements,
        layers,
        brandVisibility,
        outputFormat,
      };
      
      const job = await startExport(config, {
        onSuccess: onAssetSaved ? (url) => {
          onAssetSaved(url);
        } : undefined
      });
      
      if (job) {
        showToast('Renderizado en segundo plano iniciado', 'info');
        onClose(); // Close modal immediately so user can keep interacting
      }
    } finally {
      setIsExporting(false);
    }
  };

  if (!isOpen) return null;

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm">
      <div className="bg-neutral-950 border border-neutral-800 rounded-2xl shadow-2xl shadow-black/80 w-[480px] max-h-[85vh] flex flex-col overflow-hidden">
        {/* Header */}
        <div className="flex items-center justify-between px-5 py-4 border-b border-neutral-800/50">
          <div className="flex items-center gap-3">
            <div className="p-2 rounded-lg bg-gradient-to-br from-violet-500/20 to-fuchsia-500/20 border border-violet-500/20">
              <Download size={18} className="text-violet-400" />
            </div>
            <div>
              <h2 className="text-sm font-bold text-white">{onAssetSaved ? 'Guardar Activo de Marca' : 'Exportar'}</h2>
              <p className="text-[10px] text-neutral-500">{onAssetSaved ? 'Renderizar y aplicar cambios' : 'Renderizar y descargar'}</p>
            </div>
          </div>
          <div className="flex items-center gap-2">
            <div className="flex items-center gap-1.5" title={isConnected ? 'Conectado al servidor' : 'Sin conexión'}>
              {isConnected
                ? <Wifi size={12} className="text-emerald-400" />
                : <WifiOff size={12} className="text-red-400" />
              }
              <span className={`text-[9px] ${isConnected ? 'text-emerald-400' : 'text-red-400'}`}>
                {isConnected ? 'Live' : 'Offline'}
              </span>
            </div>
            <button onClick={onClose} title="Cerrar" className="p-1.5 rounded-lg hover:bg-neutral-800 transition-colors text-neutral-400 hover:text-white">
              <X size={16} />
            </button>
          </div>
        </div>

        {/* Body */}
        <div className="flex-1 overflow-y-auto custom-scrollbar p-5 space-y-5">
          {/* Format Selection */}
          <div>
            <label className="block text-[10px] font-medium text-neutral-500 uppercase tracking-wider mb-2">Formato</label>
            <div className="grid grid-cols-2 gap-2">
              {filteredFormats.map(opt => {
                const Icon = opt.icon;
                return (
                  <button
                    key={opt.value}
                    onClick={() => setFormat(opt.value)}
                    title={opt.desc}
                    className={`p-3 rounded-xl border transition-all flex items-center gap-2.5 ${
                      format === opt.value
                        ? 'bg-violet-600/15 border-violet-500/50 text-violet-300 shadow-lg shadow-violet-500/5'
                        : 'bg-neutral-900/50 border-neutral-800 text-neutral-400 hover:border-neutral-700 hover:text-neutral-300'
                    }`}
                  >
                    <Icon size={16} />
                    <div className="text-left">
                      <div className="text-xs font-semibold">{opt.label}</div>
                      <div className="text-[9px] text-neutral-500">{opt.desc}</div>
                    </div>
                  </button>
                );
              })}
            </div>
          </div>

          {/* Resolution */}
          <div>
            <label className="block text-[10px] font-medium text-neutral-500 uppercase tracking-wider mb-2">Resolución</label>
            <div className="flex flex-wrap gap-1.5">
              {filteredPresets.map((preset, idx) => (
                <button
                  key={preset.label}
                  onClick={() => setResIdx(idx)}
                  title={preset.desc}
                  className={`px-3 py-1.5 rounded-lg border text-[10px] font-medium transition-all ${
                    resIdx === idx
                      ? 'bg-violet-600/15 border-violet-500/50 text-violet-300'
                      : 'bg-neutral-900/50 border-neutral-800 text-neutral-500 hover:border-neutral-700'
                  }`}
                >
                  {preset.label}
                </button>
              ))}
            </div>
            <p className="text-[9px] text-neutral-600 mt-1">{selectedRes.desc}</p>
          </div>

          {/* Advanced Settings */}
          {!isStill && (
            <div>
              <button
                onClick={() => setShowAdvanced(!showAdvanced)}
                className="flex items-center gap-1 text-[10px] text-neutral-500 hover:text-neutral-300 transition-colors"
              >
                <ChevronDown size={10} className={`transition-transform ${showAdvanced ? 'rotate-180' : ''}`} />
                Configuración avanzada
              </button>
              {showAdvanced && (
                <div className="mt-2 bg-neutral-900/50 border border-neutral-800/50 rounded-lg p-3 space-y-3">
                  <div>
                    <label className="block text-[10px] text-neutral-500 mb-1">FPS</label>
                    <div className="flex gap-1.5">
                      {[24, 30, 60].map(f => (
                        <button
                          key={f}
                          onClick={() => setFps(f)}
                          className={`px-3 py-1 rounded-md text-[10px] font-medium border transition-all ${
                            fps === f
                              ? 'bg-violet-600/15 border-violet-500/50 text-violet-300'
                              : 'bg-neutral-900 border-neutral-800 text-neutral-500 hover:border-neutral-700'
                          }`}
                        >
                          {f} fps
                        </button>
                      ))}
                    </div>
                  </div>
                  <div className="flex items-center justify-between text-[10px]">
                    <span className="text-neutral-500">Duración</span>
                    <span className="text-neutral-400 font-mono">{durationSeconds.toFixed(1)}s ({actualFrames} frames)</span>
                  </div>
                  {/* Quality Tier */}
                  <div>
                    <label className="block text-[10px] text-neutral-500 mb-1">Calidad</label>
                    <div className="grid grid-cols-4 gap-1">
                      {[
                        { value: 'draft' as const, label: 'Draft', color: 'text-neutral-400' },
                        { value: 'standard' as const, label: 'Std', color: 'text-sky-400' },
                        { value: 'high' as const, label: 'High', color: 'text-violet-400' },
                        { value: 'ultra' as const, label: 'Ultra', color: 'text-amber-400' },
                      ].map(q => (
                        <button
                          key={q.value}
                          onClick={() => {
                            setQuality(q.value);
                            // Auto-adjust resolution: high/ultra → first (largest), draft/standard → last (smallest)
                            const lastIdx = filteredPresets.length - 1;
                            const resMap: Record<string, number> = { draft: lastIdx, standard: lastIdx, high: 0, ultra: 0 };
                            setResIdx(resMap[q.value] ?? 0);
                            const fpsMap: Record<string, number> = { draft: 24, standard: 30, high: 30, ultra: 60 };
                            setFps(fpsMap[q.value] ?? 30);
                          }}
                          title={q.label}
                          className={`py-1 rounded-md text-[9px] font-semibold border transition-all ${
                            quality === q.value
                              ? 'bg-violet-600/15 border-violet-500/50 text-violet-300'
                              : `bg-neutral-900 border-neutral-800 ${q.color} hover:border-neutral-700`
                          }`}
                        >
                          {q.label}
                        </button>
                      ))}
                    </div>
                  </div>
                </div>
              )}
            </div>
          )}

          {/* Export Button */}
          <button
            onClick={handleExport}
            disabled={isExporting || !isConnected}
            title="Iniciar exportación"
            className={`w-full py-3 rounded-xl font-semibold text-sm flex items-center justify-center gap-2 transition-all ${
              isExporting || !isConnected
                ? 'bg-neutral-800 text-neutral-500 cursor-not-allowed'
                : 'bg-gradient-to-r from-violet-600 to-fuchsia-600 text-white hover:from-violet-500 hover:to-fuchsia-500 shadow-lg shadow-violet-500/20 hover:shadow-violet-500/30'
            }`}
          >
            <Zap size={16} />
            {isExporting ? 'Iniciando...' : (onAssetSaved ? 'Renderizar y Guardar' : `Exportar ${isStill ? 'Imagen' : 'Video'}`)}
            <span className="text-[9px] opacity-60 font-mono">({estimatedSize})</span>
          </button>

          {/* Job Queue */}
          {jobs.length > 0 && (
            <div>
              <div className="flex items-center justify-between mb-2">
                <label className="text-[10px] font-medium text-neutral-500 uppercase tracking-wider">
                  Cola de Exportación
                </label>
                {hasActiveJobs && (
                  <span className="text-[9px] text-violet-400 animate-pulse">
                    {activeJobs.length} activ{activeJobs.length > 1 ? 'os' : 'o'}
                  </span>
                )}
              </div>
              <div className="space-y-2 max-h-[250px] overflow-y-auto custom-scrollbar">
                {jobs.map(job => (
                  <ExportJobItem
                    key={job.id}
                    job={job}
                    onCancel={cancelJob}
                    onDownload={downloadJob}
                  />
                ))}
              </div>
            </div>
          )}
        </div>
      </div>
    </div>
  );
};
