"use client";

import React, {
  createContext,
  useContext,
  useReducer,
  useCallback,
  useEffect,
  ReactNode,
} from "react";

export interface Message {
  id: string;
  content: string;
  sender: "user" | "ai";
  timestamp: Date;
  type?: "text" | "error" | "system";
  isStreaming?: boolean;
}

export interface ModalState {
  isOpen: boolean;
  isMinimized: boolean;
  position: { x: number; y: number };
  size: { width: string; height: string };
  zIndex: number;
}

export interface ChatSession {
  id: string;
  messages: Message[];
  createdAt: Date;
  lastActivity: Date;
  title?: string;
}

export interface ModalStateContextType {
  // Modal state
  modalState: ModalState;
  openModal: () => void;
  closeModal: () => void;
  minimizeModal: () => void;
  maximizeModal: () => void;
  setModalPosition: (x: number, y: number) => void;
  setModalSize: (width: string, height: string) => void;
  bringToFront: () => void;

  // Chat state
  currentSession: ChatSession | null;
  sessions: ChatSession[];
  createSession: (title?: string) => string;
  switchSession: (sessionId: string) => void;
  deleteSession: (sessionId: string) => void;
  addMessage: (message: Omit<Message, "id" | "timestamp">) => void;
  clearCurrentSession: () => void;

  // Persistence
  saveToStorage: () => void;
  loadFromStorage: () => void;
  clearStorage: () => void;
}

type ModalAction =
  | { type: "OPEN_MODAL" }
  | { type: "CLOSE_MODAL" }
  | { type: "MINIMIZE_MODAL" }
  | { type: "MAXIMIZE_MODAL" }
  | { type: "SET_POSITION"; payload: { x: number; y: number } }
  | { type: "SET_SIZE"; payload: { width: string; height: string } }
  | { type: "BRING_TO_FRONT" }
  | { type: "CREATE_SESSION"; payload: { id: string; title?: string } }
  | { type: "SWITCH_SESSION"; payload: string }
  | { type: "DELETE_SESSION"; payload: string }
  | { type: "ADD_MESSAGE"; payload: Message }
  | { type: "CLEAR_CURRENT_SESSION" }
  | { type: "SET_SESSIONS"; payload: ChatSession[] }
  | { type: "UPDATE_SESSION_ACTIVITY"; payload: string };

interface ModalStateContextState {
  modalState: ModalState;
  currentSession: ChatSession | null;
  sessions: ChatSession[];
  nextZIndex: number;
}

const initialModalState: ModalState = {
  isOpen: false,
  isMinimized: false,
  position: { x: 0, y: 0 },
  size: { width: "800px", height: "600px" },
  zIndex: 1000,
};

const initialState: ModalStateContextState = {
  modalState: initialModalState,
  currentSession: null,
  sessions: [],
  nextZIndex: 1000,
};

const STORAGE_KEY = "desktop-chat-modal-state";
const SESSIONS_STORAGE_KEY = "desktop-chat-sessions";

function modalStateReducer(
  state: ModalStateContextState,
  action: ModalAction
): ModalStateContextState {
  switch (action.type) {
    case "OPEN_MODAL":
      return {
        ...state,
        modalState: {
          ...state.modalState,
          isOpen: true,
          zIndex: state.nextZIndex,
        },
        nextZIndex: state.nextZIndex + 1,
      };

    case "CLOSE_MODAL":
      return {
        ...state,
        modalState: {
          ...state.modalState,
          isOpen: false,
          isMinimized: false,
        },
      };

    case "MINIMIZE_MODAL":
      return {
        ...state,
        modalState: {
          ...state.modalState,
          isMinimized: true,
        },
      };

    case "MAXIMIZE_MODAL":
      return {
        ...state,
        modalState: {
          ...state.modalState,
          isMinimized: false,
        },
      };

    case "SET_POSITION":
      return {
        ...state,
        modalState: {
          ...state.modalState,
          position: action.payload,
        },
      };

    case "SET_SIZE":
      return {
        ...state,
        modalState: {
          ...state.modalState,
          size: action.payload,
        },
      };

    case "BRING_TO_FRONT":
      return {
        ...state,
        modalState: {
          ...state.modalState,
          zIndex: state.nextZIndex,
        },
        nextZIndex: state.nextZIndex + 1,
      };

    case "CREATE_SESSION": {
      const newSession: ChatSession = {
        id: action.payload.id,
        title: action.payload.title || `Chat ${state.sessions.length + 1}`,
        messages: [],
        createdAt: new Date(),
        lastActivity: new Date(),
      };

      return {
        ...state,
        sessions: [...state.sessions, newSession],
        currentSession: newSession,
      };
    }

    case "SWITCH_SESSION": {
      const session = state.sessions.find((s) => s.id === action.payload);
      return {
        ...state,
        currentSession: session || null,
      };
    }

    case "DELETE_SESSION": {
      const filteredSessions = state.sessions.filter(
        (s) => s.id !== action.payload
      );
      const wasCurrentSession = state.currentSession?.id === action.payload;

      return {
        ...state,
        sessions: filteredSessions,
        currentSession: wasCurrentSession
          ? filteredSessions[0] || null
          : state.currentSession,
      };
    }

    case "ADD_MESSAGE": {
      if (!state.currentSession) return state;

      const updatedSessions = state.sessions.map((session) =>
        session.id === state.currentSession!.id
          ? {
              ...session,
              messages: [...session.messages, action.payload],
              lastActivity: new Date(),
            }
          : session
      );

      const updatedCurrentSession = {
        ...state.currentSession,
        messages: [...state.currentSession.messages, action.payload],
        lastActivity: new Date(),
      };

      return {
        ...state,
        sessions: updatedSessions,
        currentSession: updatedCurrentSession,
      };
    }

    case "CLEAR_CURRENT_SESSION": {
      if (!state.currentSession) return state;

      const updatedSessions = state.sessions.map((session) =>
        session.id === state.currentSession!.id
          ? {
              ...session,
              messages: [],
              lastActivity: new Date(),
            }
          : session
      );

      const updatedCurrentSession = {
        ...state.currentSession,
        messages: [],
        lastActivity: new Date(),
      };

      return {
        ...state,
        sessions: updatedSessions,
        currentSession: updatedCurrentSession,
      };
    }

    case "SET_SESSIONS":
      return {
        ...state,
        sessions: action.payload,
        currentSession: action.payload[0] || null,
      };

    case "UPDATE_SESSION_ACTIVITY": {
      const updatedSessions = state.sessions.map((session) =>
        session.id === action.payload
          ? { ...session, lastActivity: new Date() }
          : session
      );

      const updatedCurrentSession =
        state.currentSession?.id === action.payload
          ? { ...state.currentSession, lastActivity: new Date() }
          : state.currentSession;

      return {
        ...state,
        sessions: updatedSessions,
        currentSession: updatedCurrentSession,
      };
    }

    default:
      return state;
  }
}

const ModalStateContext = createContext<ModalStateContextType | undefined>(
  undefined
);

export function useModalState(): ModalStateContextType {
  const context = useContext(ModalStateContext);
  if (!context) {
    throw new Error("useModalState must be used within a ModalStateProvider");
  }
  return context;
}

interface ModalStateProviderProps {
  children: ReactNode;
  persistToStorage?: boolean;
  maxSessions?: number;
  sessionTimeout?: number; // in milliseconds
}

export function ModalStateProvider({
  children,
  persistToStorage = true,
  maxSessions = 10,
  sessionTimeout = 24 * 60 * 60 * 1000, // 24 hours
}: ModalStateProviderProps) {
  const [state, dispatch] = useReducer(modalStateReducer, initialState);

  // Generate unique session ID
  const generateSessionId = useCallback(() => {
    return `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
  }, []);

  // Generate unique message ID
  const generateMessageId = useCallback(() => {
    return `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
  }, []);

  // Modal actions
  const openModal = useCallback(() => {
    dispatch({ type: "OPEN_MODAL" });
  }, []);

  const closeModal = useCallback(() => {
    dispatch({ type: "CLOSE_MODAL" });
  }, []);

  const minimizeModal = useCallback(() => {
    dispatch({ type: "MINIMIZE_MODAL" });
  }, []);

  const maximizeModal = useCallback(() => {
    dispatch({ type: "MAXIMIZE_MODAL" });
  }, []);

  const setModalPosition = useCallback((x: number, y: number) => {
    dispatch({ type: "SET_POSITION", payload: { x, y } });
  }, []);

  const setModalSize = useCallback((width: string, height: string) => {
    dispatch({ type: "SET_SIZE", payload: { width, height } });
  }, []);

  const bringToFront = useCallback(() => {
    dispatch({ type: "BRING_TO_FRONT" });
  }, []);

  // Chat session actions
  const createSession = useCallback(
    (title?: string): string => {
      const sessionId = generateSessionId();
      dispatch({ type: "CREATE_SESSION", payload: { id: sessionId, title } });
      return sessionId;
    },
    [generateSessionId]
  );

  const switchSession = useCallback((sessionId: string) => {
    dispatch({ type: "SWITCH_SESSION", payload: sessionId });
    dispatch({ type: "UPDATE_SESSION_ACTIVITY", payload: sessionId });
  }, []);

  const deleteSession = useCallback((sessionId: string) => {
    dispatch({ type: "DELETE_SESSION", payload: sessionId });
  }, []);

  const addMessage = useCallback(
    (messageData: Omit<Message, "id" | "timestamp">) => {
      const message: Message = {
        ...messageData,
        id: generateMessageId(),
        timestamp: new Date(),
      };
      dispatch({ type: "ADD_MESSAGE", payload: message });
    },
    [generateMessageId]
  );

  const clearCurrentSession = useCallback(() => {
    dispatch({ type: "CLEAR_CURRENT_SESSION" });
  }, []);

  // Storage functions
  const saveToStorage = useCallback(() => {
    if (!persistToStorage || typeof window === "undefined") return;

    try {
      // Save modal state
      const modalStateToSave = {
        position: state.modalState.position,
        size: state.modalState.size,
        isMinimized: state.modalState.isMinimized,
      };
      localStorage.setItem(STORAGE_KEY, JSON.stringify(modalStateToSave));

      // Save sessions (with date serialization)
      const sessionsToSave = state.sessions.map((session) => ({
        ...session,
        createdAt: session.createdAt.toISOString(),
        lastActivity: session.lastActivity.toISOString(),
        messages: session.messages.map((msg) => ({
          ...msg,
          timestamp: msg.timestamp.toISOString(),
        })),
      }));
      localStorage.setItem(
        SESSIONS_STORAGE_KEY,
        JSON.stringify(sessionsToSave)
      );
    } catch (error) {
      console.warn("Failed to save modal state to storage:", error);
    }
  }, [state, persistToStorage]);

  const loadFromStorage = useCallback(() => {
    if (!persistToStorage || typeof window === "undefined") return;

    try {
      // Load modal state
      const savedModalState = localStorage.getItem(STORAGE_KEY);
      if (savedModalState) {
        const parsed = JSON.parse(savedModalState);
        if (parsed.position) {
          dispatch({ type: "SET_POSITION", payload: parsed.position });
        }
        if (parsed.size) {
          dispatch({ type: "SET_SIZE", payload: parsed.size });
        }
        if (parsed.isMinimized) {
          dispatch({ type: "MINIMIZE_MODAL" });
        }
      }

      // Load sessions
      const savedSessions = localStorage.getItem(SESSIONS_STORAGE_KEY);
      if (savedSessions) {
        const parsed = JSON.parse(savedSessions);
        const now = new Date();

        // Filter out expired sessions and restore dates
        const validSessions: ChatSession[] = parsed
          .map((session: any) => ({
            ...session,
            createdAt: new Date(session.createdAt),
            lastActivity: new Date(session.lastActivity),
            messages: session.messages.map((msg: any) => ({
              ...msg,
              timestamp: new Date(msg.timestamp),
            })),
          }))
          .filter((session: ChatSession) => {
            const timeSinceActivity =
              now.getTime() - session.lastActivity.getTime();
            return timeSinceActivity < sessionTimeout;
          })
          .slice(-maxSessions); // Keep only the most recent sessions

        if (validSessions.length > 0) {
          dispatch({ type: "SET_SESSIONS", payload: validSessions });
        }
      }
    } catch (error) {
      console.warn("Failed to load modal state from storage:", error);
    }
  }, [persistToStorage, sessionTimeout, maxSessions]);

  const clearStorage = useCallback(() => {
    if (typeof window === "undefined") return;

    try {
      localStorage.removeItem(STORAGE_KEY);
      localStorage.removeItem(SESSIONS_STORAGE_KEY);
    } catch (error) {
      console.warn("Failed to clear modal state storage:", error);
    }
  }, []);

  // Auto-save to storage when state changes
  useEffect(() => {
    if (persistToStorage) {
      const timeoutId = setTimeout(saveToStorage, 500); // Debounce saves
      return () => clearTimeout(timeoutId);
    }
  }, [state, saveToStorage, persistToStorage]);

  // Load from storage on mount
  useEffect(() => {
    loadFromStorage();
  }, [loadFromStorage]);

  // Create initial session if none exists
  useEffect(() => {
    if (state.sessions.length === 0 && !state.currentSession) {
      createSession("Welcome Chat");
    }
  }, [state.sessions.length, state.currentSession, createSession]);

  // Cleanup expired sessions periodically
  useEffect(() => {
    const cleanupInterval = setInterval(() => {
      const now = new Date();
      const validSessions = state.sessions.filter((session) => {
        const timeSinceActivity =
          now.getTime() - session.lastActivity.getTime();
        return timeSinceActivity < sessionTimeout;
      });

      if (validSessions.length !== state.sessions.length) {
        dispatch({ type: "SET_SESSIONS", payload: validSessions });
      }
    }, 60000); // Check every minute

    return () => clearInterval(cleanupInterval);
  }, [state.sessions, sessionTimeout]);

  const contextValue: ModalStateContextType = {
    modalState: state.modalState,
    openModal,
    closeModal,
    minimizeModal,
    maximizeModal,
    setModalPosition,
    setModalSize,
    bringToFront,
    currentSession: state.currentSession,
    sessions: state.sessions,
    createSession,
    switchSession,
    deleteSession,
    addMessage,
    clearCurrentSession,
    saveToStorage,
    loadFromStorage,
    clearStorage,
  };

  return (
    <ModalStateContext.Provider value={contextValue}>
      {children}
    </ModalStateContext.Provider>
  );
}

export default ModalStateProvider;
