import { useState, ReactNode, useMemo } from 'react';
import { createContext, useContextSelector } from 'use-context-selector';

interface UIContextProps {
    isMobileSidebarOpen: boolean;
    setIsMobileSidebarOpen: React.Dispatch<React.SetStateAction<boolean>>;
    isLoginModalOpen: boolean;
    setIsLoginModalOpen: React.Dispatch<React.SetStateAction<boolean>>;
    isRateLimitModalOpen: boolean;
    setIsRateLimitModalOpen: React.Dispatch<React.SetStateAction<boolean>>;
    isSettingsModalOpen: boolean;
    setIsSettingsModalOpen: React.Dispatch<React.SetStateAction<boolean>>;
    isConfirmDeleteModalOpen: boolean;
    setIsConfirmDeleteModalOpen: React.Dispatch<React.SetStateAction<boolean>>;
    confirmDeleteConversationName: string | null;
    setConfirmDeleteConversationName: React.Dispatch<React.SetStateAction<string | null>>;
    confirmDeleteConversationId: string | null;
    setConfirmDeleteConversationId: React.Dispatch<React.SetStateAction<string | null>>;
    // Propose Changes modal
    isProposeChangesModalOpen: boolean;
    setIsProposeChangesModalOpen: React.Dispatch<React.SetStateAction<boolean>>;
    proposeChangesRequest: any | null;
    setProposeChangesRequest: React.Dispatch<React.SetStateAction<any | null>>;
    openProposeChanges: (request: any) => Promise<{ approved: boolean; user_reason?: string }>;
    resolveProposeChanges: (decision: { approved: boolean; user_reason?: string }) => void;
    // Read approval modal
    isReadApprovalModalOpen: boolean;
    setIsReadApprovalModalOpen: React.Dispatch<React.SetStateAction<boolean>>;
    readApprovalRequest: any | null;
    setReadApprovalRequest: React.Dispatch<React.SetStateAction<any | null>>;
    openReadApproval: (payload: any) => Promise<{ approved: boolean; user_reason?: string }>;
    resolveReadApproval: (decision: { approved: boolean; user_reason?: string }) => void;
}

const defaultContextValue: UIContextProps = {
    isMobileSidebarOpen: false,
    setIsMobileSidebarOpen: () => {},
    isLoginModalOpen: false,
    setIsLoginModalOpen: () => {},
    isRateLimitModalOpen: false,
    setIsRateLimitModalOpen: () => {},
    isSettingsModalOpen: false,
    setIsSettingsModalOpen: () => {},
    isConfirmDeleteModalOpen: false,
    setIsConfirmDeleteModalOpen: () => {},
    confirmDeleteConversationName: null,
    setConfirmDeleteConversationName: () => {},
    confirmDeleteConversationId: null,
    setConfirmDeleteConversationId: () => {},
    isProposeChangesModalOpen: false,
    setIsProposeChangesModalOpen: () => {},
    proposeChangesRequest: null,
    setProposeChangesRequest: () => {},
    openProposeChanges: async () => ({ approved: false }),
    resolveProposeChanges: () => {},
    isReadApprovalModalOpen: false,
    setIsReadApprovalModalOpen: () => {},
    readApprovalRequest: null,
    setReadApprovalRequest: () => {},
    openReadApproval: async () => ({ approved: false }),
    resolveReadApproval: () => {},
};

const UIContext = createContext<UIContextProps>(defaultContextValue);

interface UIProviderProps {
  children: ReactNode;
}

export const UIProvider = ({ children }: UIProviderProps): JSX.Element => {
    const [isMobileSidebarOpen, setIsMobileSidebarOpen] = useState(false);
    const [isLoginModalOpen, setIsLoginModalOpen] = useState(false);
    const [isRateLimitModalOpen, setIsRateLimitModalOpen] = useState(false);
    const [isSettingsModalOpen, setIsSettingsModalOpen] = useState(false);
    const [isConfirmDeleteModalOpen, setIsConfirmDeleteModalOpen] = useState(false);
    const [confirmDeleteConversationName, setConfirmDeleteConversationName] = useState<string | null>(null);
    const [confirmDeleteConversationId, setConfirmDeleteConversationId] = useState<string | null>(null);
    const [isProposeChangesModalOpen, setIsProposeChangesModalOpen] = useState(false);
    const [proposeChangesRequest, setProposeChangesRequest] = useState<any | null>(null);
    const [resolver, setResolver] = useState<((value: { approved: boolean; user_reason?: string }) => void) | null>(null);
    const [isReadApprovalModalOpen, setIsReadApprovalModalOpen] = useState(false);
    const [readApprovalRequest, setReadApprovalRequest] = useState<any | null>(null);
    const [readResolver, setReadResolver] = useState<((value: { approved: boolean; user_reason?: string }) => void) | null>(null);

    const openProposeChanges = (request: any) => {
        setProposeChangesRequest(request);
        setIsProposeChangesModalOpen(true);
        return new Promise<{ approved: boolean; user_reason?: string }>((resolve) => {
            setResolver(() => resolve);
        });
    };

    const resolveProposeChanges = (decision: { approved: boolean; user_reason?: string }) => {
        if (resolver) {
            resolver(decision);
            setResolver(null);
        }
        setIsProposeChangesModalOpen(false);
        setProposeChangesRequest(null);
    };

    const openReadApproval = (payload: any) => {
        setReadApprovalRequest(payload);
        setIsReadApprovalModalOpen(true);
        return new Promise<{ approved: boolean; user_reason?: string }>((resolve) => {
            setReadResolver(() => resolve);
        });
    };

    const resolveReadApproval = (decision: { approved: boolean; user_reason?: string }) => {
        if (readResolver) {
            readResolver(decision);
            setReadResolver(null);
        }
        setIsReadApprovalModalOpen(false);
        setReadApprovalRequest(null);
    };

    const contextValue = useMemo(() => ({
        isMobileSidebarOpen,
        setIsMobileSidebarOpen,
        isLoginModalOpen,
        setIsLoginModalOpen,
        isRateLimitModalOpen,
        setIsRateLimitModalOpen,
        isSettingsModalOpen,
        setIsSettingsModalOpen,
        isConfirmDeleteModalOpen,
        setIsConfirmDeleteModalOpen,
        confirmDeleteConversationName,
        setConfirmDeleteConversationName,
        confirmDeleteConversationId,
        setConfirmDeleteConversationId,
        isProposeChangesModalOpen,
        setIsProposeChangesModalOpen,
        proposeChangesRequest,
        setProposeChangesRequest,
        openProposeChanges,
        resolveProposeChanges,
        isReadApprovalModalOpen,
        setIsReadApprovalModalOpen,
        readApprovalRequest,
        setReadApprovalRequest,
        openReadApproval,
        resolveReadApproval,
    }), [
        isMobileSidebarOpen,
        isLoginModalOpen,
        isRateLimitModalOpen,
        isSettingsModalOpen,
        isConfirmDeleteModalOpen,
        confirmDeleteConversationName,
        confirmDeleteConversationId,
        isProposeChangesModalOpen,
        proposeChangesRequest,
        isReadApprovalModalOpen,
        readApprovalRequest,
        resolver,
        readResolver,
    ]);

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

// Selector Hook
export const useUISelector = <T,>(selector: (state: UIContextProps) => T): T => {
  return useContextSelector(UIContext, selector);
};

export const useIsMobileSidebarOpen = () => {
  return useUISelector(state => state.isMobileSidebarOpen);
};

export const useIsLoginModalOpen = () => {
  return useUISelector(state => state.isLoginModalOpen);
};

export const useIsRateLimitModalOpen = () => {
  return useUISelector(state => state.isRateLimitModalOpen);
};

export const useIsSettingsModalOpen = () => {
  return useUISelector(state => state.isSettingsModalOpen);
};

export const useIsConfirmDeleteModalOpen = () => {
  return useUISelector(state => state.isConfirmDeleteModalOpen);
};

export const useConfirmDeleteConversationName = () => {
  return useUISelector(state => state.confirmDeleteConversationName);
};

export const useConfirmDeleteConversationId = () => {
  return useUISelector(state => state.confirmDeleteConversationId);
};

// Individual Selector Hooks for Setter Functions
export const useSetIsMobileSidebarOpen = () => {
  return useUISelector(state => state.setIsMobileSidebarOpen);
};

export const useSetIsLoginModalOpen = () => {
  return useUISelector(state => state.setIsLoginModalOpen);
};

export const useSetIsRateLimitModalOpen = () => {
  return useUISelector(state => state.setIsRateLimitModalOpen);
};

export const useSetIsSettingsModalOpen = () => {
  return useUISelector(state => state.setIsSettingsModalOpen);
};

export const useSetIsConfirmDeleteModalOpen = () => {
  return useUISelector(state => state.setIsConfirmDeleteModalOpen);
};

export const useSetConfirmDeleteConversationName = () => {
  return useUISelector(state => state.setConfirmDeleteConversationName);
};

export const useSetConfirmDeleteConversationId = () => {
  return useUISelector(state => state.setConfirmDeleteConversationId);
};

export const useIsProposeChangesModalOpen = () => {
  return useUISelector(state => state.isProposeChangesModalOpen);
};

export const useSetIsProposeChangesModalOpen = () => {
  return useUISelector(state => state.setIsProposeChangesModalOpen);
};

export const useProposeChangesRequest = () => {
  return useUISelector(state => state.proposeChangesRequest);
};

export const useSetProposeChangesRequest = () => {
  return useUISelector(state => state.setProposeChangesRequest);
};

export const useOpenProposeChanges = () => {
  return useUISelector(state => state.openProposeChanges);
};

export const useIsReadApprovalModalOpen = () => {
  return useUISelector(state => state.isReadApprovalModalOpen);
};

export const useSetIsReadApprovalModalOpen = () => {
  return useUISelector(state => state.setIsReadApprovalModalOpen);
};

export const useReadApprovalRequest = () => {
  return useUISelector(state => state.readApprovalRequest);
};

export const useSetReadApprovalRequest = () => {
  return useUISelector(state => state.setReadApprovalRequest);
};

export const useOpenReadApproval = () => {
  return useUISelector(state => state.openReadApproval);
};
