'use client';
import { createContext, useContext, useEffect, ReactNode, useMemo, useState, useRef } from 'react';
import { PortfolioConfig } from '@/types/portfolio';
import { setGlobalColors } from '@/lib/theme';
import { setGlobalTypography } from '@/src/lib/typography';
import { PortfolioRevisionService, useLastPortfolioRevision } from '@/src/services/PortfolioRevisionService';
import { useApiWithToast } from '@/src/hooks/useApiWithToast';

interface PortfolioConfigContextType {
  config: PortfolioConfig | null;
  updateConfig: (updates: Partial<PortfolioConfig>) => void;
  saveConfig: () => Promise<void>;
  immediateUpdateAndSave: (updates: Partial<PortfolioConfig>) => Promise<void>;
  isDirty: boolean;
  isLoading: boolean;
  error: Error | null;
}

const PortfolioConfigContext = createContext<PortfolioConfigContextType | undefined>(undefined);

export function PortfolioConfigProvider({ children, portfolioId }: { children: ReactNode; portfolioId: string }) {
  const [config, setConfig] = useState<PortfolioConfig | null>(null);
  const [originalConfig, setOriginalConfig] = useState<PortfolioConfig | null>(null);
  const { revision, isLoading, error, mutate } = useLastPortfolioRevision(portfolioId);
  const [isDirty, setIsDirty] = useState(false);
  const { handle } = useApiWithToast();
  const isInitialMount = useRef(true);

  useEffect(() => {
    if (revision && isInitialMount.current) {
      setConfig(revision.config);
      setOriginalConfig(revision.config);
      if (revision.config.colors) {
        setGlobalColors(revision.config.colors);
        localStorage.setItem('theme', 'light');
      }
      if (revision.config.typography) {
        setGlobalTypography(revision.config.typography);
      }
      isInitialMount.current = false;
    }
  }, [revision]);

  const updateConfig = (updates: Partial<PortfolioConfig>) => {
    setConfig((prev) => {
      if (!prev) return updates as PortfolioConfig;

      const newConfig = { ...prev };
      if (updates.elements) {
        newConfig.elements = updates.elements;
      }

      if (updates.colors) {
        newConfig.colors = updates.colors;
        setGlobalColors(updates.colors);
      }

      if (updates.typography) {
        newConfig.typography = updates.typography;
        setGlobalTypography(updates.typography);
      }

      if (JSON.stringify(newConfig) !== JSON.stringify(originalConfig)) {
        setIsDirty(true);
      } else {
        setIsDirty(false);
      }

      return newConfig;
    });
  };

  const saveConfig = async () => {
    if (!portfolioId || !config) return;

    await handle(PortfolioRevisionService.saveRevision(portfolioId, config), {
      mutate: () => mutate(),
    });
    setOriginalConfig(JSON.parse(JSON.stringify(config)));
    setIsDirty(false);
  };

  const immediateUpdateAndSave = async (updates: Partial<PortfolioConfig>) => {
    updateConfig(updates);
    await saveConfig();
  };

  const value = useMemo(
    () => ({
      config,
      updateConfig,
      saveConfig,
      immediateUpdateAndSave,
      isDirty,
      isLoading,
      error,
    }),
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [config, isDirty, isLoading, error]
  );

  return <PortfolioConfigContext.Provider value={value}>{children}</PortfolioConfigContext.Provider>;
}

export function usePortfolioConfig() {
  const context = useContext(PortfolioConfigContext);
  if (context === undefined) {
    throw new Error('usePortfolioConfig must be used within a PortfolioConfigProvider');
  }
  return context;
}
