/**
 * 디자인 시스템 Context
 * 
 * atoms, molecules, organisms, templates, widgets 데이터를 localStorage에 저장하고 관리
 */

import { createContext, useContext, useState, useEffect, ReactNode } from "react";

export interface ComponentItem {
  id: string;
  name: string;
  path: string;
  category: string;
  description: string;
  variants?: string[];
  structure?: string;
  preview: string | ReactNode;
  code: string;
  createdAt: string;
  updatedAt: string;
}

interface DesignSystemContextType {
  atoms: ComponentItem[];
  molecules: ComponentItem[];
  organisms: ComponentItem[];
  templates: ComponentItem[];
  widgets: ComponentItem[];
  
  addComponent: (type: "atoms" | "molecules" | "organisms" | "templates" | "widgets", component: Omit<ComponentItem, "id" | "createdAt" | "updatedAt">) => void;
  updateComponent: (type: "atoms" | "molecules" | "organisms" | "templates" | "widgets", id: string, updates: Partial<ComponentItem>) => void;
  deleteComponent: (type: "atoms" | "molecules" | "organisms" | "templates" | "widgets", id: string) => void;
  
  resetToDefaults: () => void;
}

const DesignSystemContext = createContext<DesignSystemContextType | undefined>(undefined);

export function DesignSystemProvider({ children }: { children: ReactNode }) {
  // localStorage 키
  const STORAGE_KEYS = {
    atoms: "designSystem_atoms",
    molecules: "designSystem_molecules",
    organisms: "designSystem_organisms",
    templates: "designSystem_templates",
    widgets: "designSystem_widgets",
  };

  // 기본 데이터 (하드코딩된 초기 데이터)
  const DEFAULT_ATOMS: ComponentItem[] = [];
  const DEFAULT_MOLECULES: ComponentItem[] = [];
  const DEFAULT_ORGANISMS: ComponentItem[] = [];
  const DEFAULT_TEMPLATES: ComponentItem[] = [];
  const DEFAULT_WIDGETS: ComponentItem[] = [];

  // localStorage에서 데이터 로드
  const loadFromStorage = (key: string, defaultData: ComponentItem[]) => {
    try {
      const stored = localStorage.getItem(key);
      if (stored) {
        return JSON.parse(stored);
      }
    } catch (error) {
      console.error(`Failed to load ${key} from localStorage:`, error);
    }
    return defaultData;
  };

  // 상태 초기화
  const [atoms, setAtoms] = useState<ComponentItem[]>(() => loadFromStorage(STORAGE_KEYS.atoms, DEFAULT_ATOMS));
  const [molecules, setMolecules] = useState<ComponentItem[]>(() => loadFromStorage(STORAGE_KEYS.molecules, DEFAULT_MOLECULES));
  const [organisms, setOrganisms] = useState<ComponentItem[]>(() => loadFromStorage(STORAGE_KEYS.organisms, DEFAULT_ORGANISMS));
  const [templates, setTemplates] = useState<ComponentItem[]>(() => loadFromStorage(STORAGE_KEYS.templates, DEFAULT_TEMPLATES));
  const [widgets, setWidgets] = useState<ComponentItem[]>(() => loadFromStorage(STORAGE_KEYS.widgets, DEFAULT_WIDGETS));

  // localStorage에 저장
  useEffect(() => {
    localStorage.setItem(STORAGE_KEYS.atoms, JSON.stringify(atoms));
  }, [atoms]);

  useEffect(() => {
    localStorage.setItem(STORAGE_KEYS.molecules, JSON.stringify(molecules));
  }, [molecules]);

  useEffect(() => {
    localStorage.setItem(STORAGE_KEYS.organisms, JSON.stringify(organisms));
  }, [organisms]);

  useEffect(() => {
    localStorage.setItem(STORAGE_KEYS.templates, JSON.stringify(templates));
  }, [templates]);

  useEffect(() => {
    localStorage.setItem(STORAGE_KEYS.widgets, JSON.stringify(widgets));
  }, [widgets]);

  // 컴포넌트 추가
  const addComponent = (
    type: "atoms" | "molecules" | "organisms" | "templates" | "widgets",
    component: Omit<ComponentItem, "id" | "createdAt" | "updatedAt">
  ) => {
    const newComponent: ComponentItem = {
      ...component,
      id: `${type}-${Date.now()}`,
      createdAt: new Date().toISOString(),
      updatedAt: new Date().toISOString(),
    };

    switch (type) {
      case "atoms":
        setAtoms((prev) => [...prev, newComponent]);
        break;
      case "molecules":
        setMolecules((prev) => [...prev, newComponent]);
        break;
      case "organisms":
        setOrganisms((prev) => [...prev, newComponent]);
        break;
      case "templates":
        setTemplates((prev) => [...prev, newComponent]);
        break;
      case "widgets":
        setWidgets((prev) => [...prev, newComponent]);
        break;
    }
  };

  // 컴포넌트 수정
  const updateComponent = (
    type: "atoms" | "molecules" | "organisms" | "templates" | "widgets",
    id: string,
    updates: Partial<ComponentItem>
  ) => {
    const updater = (prev: ComponentItem[]) =>
      prev.map((item) =>
        item.id === id
          ? { ...item, ...updates, updatedAt: new Date().toISOString() }
          : item
      );

    switch (type) {
      case "atoms":
        setAtoms(updater);
        break;
      case "molecules":
        setMolecules(updater);
        break;
      case "organisms":
        setOrganisms(updater);
        break;
      case "templates":
        setTemplates(updater);
        break;
      case "widgets":
        setWidgets(updater);
        break;
    }
  };

  // 컴포넌트 삭제
  const deleteComponent = (
    type: "atoms" | "molecules" | "organisms" | "templates" | "widgets",
    id: string
  ) => {
    const deleter = (prev: ComponentItem[]) => prev.filter((item) => item.id !== id);

    switch (type) {
      case "atoms":
        setAtoms(deleter);
        break;
      case "molecules":
        setMolecules(deleter);
        break;
      case "organisms":
        setOrganisms(deleter);
        break;
      case "templates":
        setTemplates(deleter);
        break;
      case "widgets":
        setWidgets(deleter);
        break;
    }
  };

  // 기본값으로 리셋
  const resetToDefaults = () => {
    setAtoms(DEFAULT_ATOMS);
    setMolecules(DEFAULT_MOLECULES);
    setOrganisms(DEFAULT_ORGANISMS);
    setTemplates(DEFAULT_TEMPLATES);
    setWidgets(DEFAULT_WIDGETS);
  };

  return (
    <DesignSystemContext.Provider
      value={{
        atoms,
        molecules,
        organisms,
        templates,
        widgets,
        addComponent,
        updateComponent,
        deleteComponent,
        resetToDefaults,
      }}
    >
      {children}
    </DesignSystemContext.Provider>
  );
}

export function useDesignSystem() {
  const context = useContext(DesignSystemContext);
  if (context === undefined) {
    throw new Error("useDesignSystem must be used within a DesignSystemProvider");
  }
  return context;
}
