import React, { useState, useCallback, useMemo } from 'react';
import { DesignMD, TimelineElement, TimelineLayer, CompanyProfile, Project, ContentPiece, ContentPillar, ExpressTemplate } from './types';
import { TopHeader } from './components/TopHeader';
import { BrandArchitecture } from './components/BrandArchitecture';
import { Dashboard } from './components/Dashboard';
import { ProductionForm } from './components/dashboard/ProductionForm';
import { StudioEditor } from './components/studio/StudioEditor';
import { ExpressEditor } from './components/express/ExpressEditor';
import { StudioTopBar } from './components/studio/StudioTopBar';
import { EditorProvider } from './context/EditorContext';
import { DEFAULT_DESIGN_MD, PREDEFINED_COMPANIES, DEFAULT_PILLARS } from './data/defaults';
import { useCustomTooltips } from './hooks/useCustomTooltips';
import { useToast } from './components/ui/ToastProvider';
import { usePersistence, loadCompanies, useTemplatePersistence, loadTemplates } from './hooks/usePersistence';
import { ContentGridView } from './components/content-grid/ContentGridView';
import { TemplateBuilder } from './components/express/builder/TemplateBuilder';
import { EXPRESS_TEMPLATES } from './config/expressTemplates';
import { compileExpressToTimeline } from './utils/expressCompiler';
import { FullscreenToggle } from './components/ui/FullscreenToggle';
import { GlobalExportWidget } from './components/export/GlobalExportWidget';
import { detectMediaDimensionsAndAspect } from './utils/mediaDimensions';

type Step = 'dashboard' | 'brand' | 'studio' | 'express' | 'content-grid' | 'template-builder' | 'production-form';

// ── Content persistence ──
const CONTENT_STORAGE_KEY = 'remix-content-data';
function loadContentData(): Record<string, { pieces: ContentPiece[]; pillars: ContentPillar[] }> | null {
  try {
    const raw = localStorage.getItem(CONTENT_STORAGE_KEY);
    return raw ? JSON.parse(raw) : null;
  } catch { return null; }
}
function saveContentData(data: Record<string, { pieces: ContentPiece[]; pillars: ContentPillar[] }>): void {
  try { localStorage.setItem(CONTENT_STORAGE_KEY, JSON.stringify(data)); } catch {}
}

export default function App() {
  const { showToast } = useToast();
  const [companies, setCompanies] = useState<CompanyProfile[]>(() => {
    return loadCompanies() ?? PREDEFINED_COMPANIES;
  });
  const [currentCompanyId, setCurrentCompanyId] = useState<string | null>(null);
  const [currentProjectId, setCurrentProjectId] = useState<string | null>(null);
  const [currentStep, setCurrentStep] = useState<Step>('dashboard');
  const [designMD, setDesignMD] = useState<DesignMD>(DEFAULT_DESIGN_MD);
  const [outputFormat, setOutputFormat] = useState<'video' | 'image'>('video');
  const [editingBrandAsset, setEditingBrandAsset] = useState<{ type: keyof DesignMD; url: string } | null>(null);

  // Global templates (decoupled from brands) — persisted
  const [globalTemplates, setGlobalTemplates] = useState<ExpressTemplate[]>(() => {
    return loadTemplates() ?? [];
  });
  const [templateBuilderFormat, setTemplateBuilderFormat] = useState<'video' | 'image'>('image');
  const [templateBuilderAspect, setTemplateBuilderAspect] = useState<ExpressTemplate['aspectRatio']>('9:16');
  const [editingGlobalTemplate, setEditingGlobalTemplate] = useState<ExpressTemplate | null>(null);

  // Production form state
  const [productionTemplate, setProductionTemplate] = useState<ExpressTemplate | null>(null);
  const [productionBrand, setProductionBrand] = useState<CompanyProfile | null>(null);

  // Merge preset + custom templates for the dashboard
  const allTemplates = useMemo(() => [
    ...EXPRESS_TEMPLATES,
    ...globalTemplates,
  ], [globalTemplates]);

  const handleSaveGlobalTemplate = useCallback((template: ExpressTemplate) => {
    setGlobalTemplates(prev => {
      const existing = prev.findIndex(t => t.id === template.id);
      if (existing >= 0) {
        const next = [...prev];
        next[existing] = template;
        return next;
      }
      return [...prev, template];
    });
    setEditingGlobalTemplate(null);
    setCurrentStep('dashboard');
  }, []);

  // Content grid state (per company)
  const [contentData, setContentData] = useState<Record<string, { pieces: ContentPiece[]; pillars: ContentPillar[] }>>(() => {
    return loadContentData() ?? {};
  });

  const getContentForCompany = useCallback((companyId: string) => {
    return contentData[companyId] ?? { pieces: [], pillars: [...DEFAULT_PILLARS] };
  }, [contentData]);

  const updateContentPieces = useCallback((companyId: string, pieces: ContentPiece[]) => {
    setContentData(prev => {
      const next = { ...prev, [companyId]: { ...prev[companyId] ?? { pillars: [...DEFAULT_PILLARS] }, pieces } };
      saveContentData(next);
      return next;
    });
  }, []);

  const updateContentPillars = useCallback((companyId: string, pillars: ContentPillar[]) => {
    setContentData(prev => {
      const next = { ...prev, [companyId]: { ...prev[companyId] ?? { pieces: [] }, pillars } };
      saveContentData(next);
      return next;
    });
  }, []);

  // Studio initial data (passed to EditorProvider when entering studio)
  const [studioInitialElements, setStudioInitialElements] = useState<TimelineElement[]>([]);
  const [studioInitialLayers, setStudioInitialLayers] = useState<TimelineLayer[]>([
    { id: 'layer-1', name: 'Capa Gráfica 1', type: 'visual' }
  ]);
  // Key to force remount EditorProvider when switching projects
  const [editorKey, setEditorKey] = useState(0);

  useCustomTooltips();
  usePersistence(companies);
  useTemplatePersistence(globalTemplates);

  const handleDesignChange = (key: keyof DesignMD, value: string | number | string[] | boolean) => {
    setDesignMD((prev) => {
      const newDesign = { ...prev, [key]: value };
      if (currentCompanyId) {
        setCompanies(prev2 => prev2.map(c => c.id === currentCompanyId ? { ...c, design: newDesign } : c));
      }
      return newDesign;
    });
  };

  const enterStudio = (design: DesignMD, format: 'video' | 'image', elements: TimelineElement[], layers: TimelineLayer[], companyId?: string, projectId?: string | null) => {
    if (companyId) setCurrentCompanyId(companyId);
    if (projectId !== undefined) setCurrentProjectId(projectId);
    setDesignMD(design);
    setOutputFormat(format);
    setStudioInitialElements(elements);
    setStudioInitialLayers(layers);
    setEditorKey(prev => prev + 1);
    setCurrentStep('studio');
  };

  const handleEditAsset = useCallback(async (assetInfo: { type: keyof DesignMD; url: string }) => {
    try {
      const isVideo = assetInfo.type === 'introVideoUrl' || assetInfo.type === 'outroVideoUrl';
      const dimensions = await detectMediaDimensionsAndAspect(assetInfo.url, isVideo ? 'video' : 'image');
      
      const layerId = 'layer-1';
      const element: TimelineElement = dimensions.format === 'video' ? {
        id: `brand-asset-${Date.now()}`,
        layerId,
        type: 'video',
        content: assetInfo.url,
        startFrame: 0,
        endFrame: 150, 
        x: 50, y: 50,
        width: 100, height: 100,
        objectFit: 'cover',
        opacity: 100,
        isBrandElement: false,
        isLocked: true,
      } : {
        id: `brand-asset-${Date.now()}`,
        layerId,
        type: 'image',
        content: assetInfo.url,
        startFrame: 0,
        endFrame: 150,
        x: 50, y: 50,
        width: 100, height: 100, 
        objectFit: 'cover',
        opacity: 100,
        isBrandElement: false,
        isLocked: true,
      };

      setEditingBrandAsset(assetInfo);
      setTemplateBuilderAspect(dimensions.aspect as ExpressTemplate['aspectRatio']);
      enterStudio(designMD, dimensions.format, [element], [{ id: layerId, name: 'Fondo del Activo', type: 'background' }], currentCompanyId || undefined, null);
    } catch (err) {
      console.error('Failed to detect dimensions:', err);
      alert('Error al leer las dimensiones del archivo original.');
    }
  }, [designMD, currentCompanyId]);

  const handleAssetSaved = useCallback((url: string) => {
    if (editingBrandAsset) {
      handleDesignChange(editingBrandAsset.type, url);
      setEditingBrandAsset(null);
      setCurrentStep('brand');
      showToast('Activo de marca guardado y aplicado correctamente', 'success');
    }
  }, [editingBrandAsset, showToast]);

  const handleStartExpressBlank = useCallback(() => {
    setCurrentCompanyId(null);
    setDesignMD(DEFAULT_DESIGN_MD);
    setOutputFormat('video');
    setCurrentStep('express');
  }, []);

  const handleStartProBlank = useCallback(() => {
    const initialElements: TimelineElement[] = [{
      id: `el-content-${Date.now()}`,
      layerId: 'layer-1',
      type: 'text',
      content: 'Inserta tu contenido aquí',
      startFrame: 0,
      endFrame: 180,
      x: 50, y: 50,
      fontSize: 48,
      color: '#FFFFFF',
      fontFamily: DEFAULT_DESIGN_MD.baseFont,
    }];
    const initialLayers: TimelineLayer[] = [{ id: 'layer-1', name: 'Capa Gráfica 1', type: 'visual' }];
    enterStudio(DEFAULT_DESIGN_MD, 'video', initialElements, initialLayers, undefined, null);
  }, []);

  const handleGenerate = useCallback((template: ExpressTemplate, brand: CompanyProfile) => {
    setProductionTemplate(template);
    setProductionBrand(brand);
    setCurrentStep('production-form');
  }, []);

  const handleEditTemplate = useCallback((template: ExpressTemplate) => {
    setEditingGlobalTemplate(template);
    setTemplateBuilderFormat(template.format);
    setCurrentStep('template-builder');
  }, []);

  const handleDuplicateTemplate = useCallback((template: ExpressTemplate) => {
    const copy: ExpressTemplate = {
      ...template,
      id: `tpl-${Date.now()}`,
      name: `${template.name} (Copia)`,
      isCustom: true,
      createdAt: new Date().toISOString(),
      scenes: template.scenes.map(s => ({ ...s, id: `scene-${Date.now()}-${Math.random().toString(36).slice(2, 6)}` })),
    };
    setGlobalTemplates(prev => [...prev, copy]);
  }, []);

  const handleDeleteTemplate = useCallback((id: string) => {
    setGlobalTemplates(prev => prev.filter(t => t.id !== id));
  }, []);

  const handleProducePro = useCallback((fieldData: Record<string, string>) => {
    if (!productionTemplate || !productionBrand) return;
    const compiled = compileExpressToTimeline(productionTemplate, fieldData, productionBrand.design, productionBrand);
    enterStudio(productionBrand.design, productionTemplate.format, compiled.elements, compiled.layers, productionBrand.id, null);
  }, [productionTemplate, productionBrand]);

  return (
    <div className="flex flex-col h-screen bg-neutral-950 text-neutral-100 font-sans overflow-hidden">
      {currentStep !== 'studio' && (
        <TopHeader 
          currentStep={currentStep} 
          setCurrentStep={(step) => {
            setCurrentStep(step);
          }} 
          outputFormat={outputFormat}
          onStartExpressBlank={handleStartExpressBlank}
          onStartProBlank={handleStartProBlank}
        />
      )}

      <div className="flex-1 flex overflow-hidden relative bg-neutral-950">
        
        {currentStep === 'dashboard' && (
          <Dashboard
            companies={companies}
            templates={allTemplates}
            onCreateBrand={(name, industry) => {
              const newAppId = Date.now().toString();
              const newBrand: CompanyProfile = {
                id: newAppId,
                name,
                industry,
                design: { ...DEFAULT_DESIGN_MD },
                projects: []
              };
              setCompanies(prev => [...prev, newBrand]);
              setCurrentCompanyId(newAppId);
              setDesignMD(newBrand.design);
              setCurrentStep('brand');
            }}
            onDeleteBrand={(id) => {
              setCompanies(prev => prev.filter(c => c.id !== id));
            }}
            onDuplicateBrand={(id) => {
              const original = companies.find(c => c.id === id);
              if (!original) return;
              const newId = Date.now().toString();
              const duplicate: CompanyProfile = {
                ...original,
                id: newId,
                name: `${original.name} (Copia)`,
                projects: [],
                design: { ...original.design, brandStickers: [...(original.design.brandStickers || [])] },
                socialLinks: original.socialLinks ? { ...original.socialLinks } : undefined,
              };
              setCompanies(prev => [...prev, duplicate]);
            }}
            onEditBrand={(design) => {
              const comp = companies.find(c => c.design === design);
              if (comp) setCurrentCompanyId(comp.id);
              setDesignMD(design);
              setCurrentStep('brand');
            }}
            onOpenContentGrid={(companyId) => {
              setCurrentCompanyId(companyId);
              setCurrentStep('content-grid');
            }}
            onCreateTemplate={(format, aspect) => {
              setTemplateBuilderFormat(format);
              setTemplateBuilderAspect(aspect);
              setEditingGlobalTemplate(null);
              setCurrentStep('template-builder');
            }}
            onEditTemplate={handleEditTemplate}
            onDuplicateTemplate={handleDuplicateTemplate}
            onDeleteTemplate={handleDeleteTemplate}
            onGenerate={handleGenerate}
          />
        )}

        {currentStep === 'production-form' && productionTemplate && productionBrand && (
          <ProductionForm
            template={productionTemplate}
            brand={productionBrand}
            onBack={() => setCurrentStep('dashboard')}
            onProducePro={handleProducePro}
          />
        )}

        {currentStep === 'brand' && (
          <BrandArchitecture 
            company={companies.find(c => c.id === currentCompanyId)!}
            handleCompanyChange={(company) => {
              setCompanies(prev => prev.map(c => c.id === company.id ? company : c));
            }}
            designMD={designMD} 
            handleDesignChange={handleDesignChange} 
            onContinue={() => setCurrentStep('dashboard')}
            onEditAsset={(type, url) => handleEditAsset({ type, url })}
          />
        )}

        {currentStep === 'content-grid' && currentCompanyId && (
          <ContentGridView
            company={companies.find(c => c.id === currentCompanyId)!}
            pieces={getContentForCompany(currentCompanyId).pieces}
            pillars={getContentForCompany(currentCompanyId).pillars}
            onPiecesChange={(pieces) => updateContentPieces(currentCompanyId, pieces)}
            onPillarsChange={(pillars) => updateContentPillars(currentCompanyId, pillars)}
            onOpenProject={(projectId) => {
              const comp = companies.find(c => c.id === currentCompanyId);
              if (comp) {
                const proj = comp.projects.find(p => p.id === projectId);
                if (proj) {
                  const layers = proj.layers.length > 0 ? proj.layers : [{ id: 'layer-1', name: 'Capa Gráfica 1', type: 'visual' as const }];
                  enterStudio(comp.design, proj.format, proj.elements, layers, comp.id, projectId);
                }
              }
            }}
          />
        )}

        {currentStep === 'express' && (
          <ExpressEditor
            designMD={designMD}
            company={companies.find(c => c.id === currentCompanyId)}
            onBack={() => setCurrentStep('dashboard')}
            onUpgradeToPro={(elements, layers) => {
              const comp = companies.find(c => c.id === currentCompanyId);
              enterStudio(designMD, outputFormat, elements, layers, comp?.id, null);
            }}
            onExport={(elements, layers, format) => {
              const comp = companies.find(c => c.id === currentCompanyId);
              enterStudio(designMD, format, elements, layers, comp?.id, null);
            }}
          />
        )}

        {currentStep === 'studio' && (
          <EditorProvider
            key={editorKey}
            initialDesignMD={designMD}
            initialElements={studioInitialElements}
            initialLayers={studioInitialLayers}
            initialFormat={outputFormat}
            initialAspect={templateBuilderAspect}
            brandContent={currentCompanyId ? (getContentForCompany(currentCompanyId).pieces || []) : []}
            editingBrandAsset={editingBrandAsset}
          >
            <div className="flex-1 flex flex-col overflow-hidden">
              <StudioTopBar setCurrentStep={setCurrentStep} />
              <StudioEditor onAssetSaved={handleAssetSaved} />
            </div>
          </EditorProvider>
        )}

        {currentStep === 'template-builder' && (
          <TemplateBuilder
            availableBrands={companies}
            onSave={handleSaveGlobalTemplate}
            onBack={() => setCurrentStep('dashboard')}
            editingTemplate={editingGlobalTemplate}
            initialFormat={templateBuilderFormat}
            initialAspect={templateBuilderAspect}
          />
        )}
      </div>
      <GlobalExportWidget />
      <FullscreenToggle />
    </div>
  );
}
