import { create } from 'zustand';
import { createJSONStorage, persist } from 'zustand/middleware';
import type { ResearchComposerState } from '../hooks/useResearchComposer';
import { createInitialResearchComposerState } from '../hooks/useResearchComposer';
import type {
  ResearchDensityMode,
  ResearchFilters,
  WorkspaceViewKind,
} from '../types/research';

export interface ResearchSelectionState {
  noteId: string | null;
  ghostId: string | null;
}

export interface CaptureModalState {
  isOpen: boolean;
  draft: ResearchComposerState;
  seedToken: string | null;
  contextLabel?: string;
}

export interface CreateWorkspaceModalState {
  isOpen: boolean;
  tickerDraft: string;
}

export interface ResearchActionStatus {
  pending: boolean;
  error: string | null;
}

export type ResearchMobilePane = 'none' | 'filters' | 'inspector';

export const defaultResearchFilters: ResearchFilters = {
  search: '',
  noteTypes: [],
  evidenceStatuses: [],
  showArchived: false,
  showGhosts: true,
};

const defaultSelection = (): ResearchSelectionState => ({
  noteId: null,
  ghostId: null,
});

const noopStorage = {
  getItem: () => null,
  setItem: () => undefined,
  removeItem: () => undefined,
};

const researchUiStorage = createJSONStorage(() => {
  if (typeof window === 'undefined') {
    return noopStorage;
  }
  return window.localStorage;
});

export interface ResearchUiStoreState {
  viewByWorkspaceId: Record<string, WorkspaceViewKind>;
  filtersByWorkspaceId: Record<string, ResearchFilters>;
  memoDraftByWorkspaceId: Record<string, string>;
  density: ResearchDensityMode;
  sidebarCollapsed: boolean;
  inspectorPinned: boolean;
  memoPreview: boolean;
  activeWorkspaceId: string | null;
  selectionByWorkspaceId: Record<string, ResearchSelectionState>;
  captureModal: CaptureModalState;
  createWorkspaceModal: CreateWorkspaceModalState;
  mobilePane: ResearchMobilePane;
  lastNavigationIntentToken: string | null;
  mutationStateByKey: Record<string, ResearchActionStatus>;
  initializeWorkspaceState: (workspaceId: string, defaultView: WorkspaceViewKind) => void;
  setActiveWorkspaceId: (workspaceId: string | null) => void;
  setWorkspaceView: (workspaceId: string, view: WorkspaceViewKind) => void;
  setWorkspaceFilters: (workspaceId: string, patch: Partial<ResearchFilters>) => void;
  resetWorkspaceFilters: (workspaceId: string) => void;
  setMemoDraft: (workspaceId: string, value: string) => void;
  setDensity: (density: ResearchDensityMode) => void;
  setSidebarCollapsed: (collapsed: boolean) => void;
  toggleSidebarCollapsed: () => void;
  setInspectorPinned: (pinned: boolean) => void;
  toggleInspectorPinned: () => void;
  setMemoPreview: (preview: boolean) => void;
  toggleMemoPreview: () => void;
  selectNote: (workspaceId: string, noteId: string) => void;
  selectGhost: (workspaceId: string, ghostId: string) => void;
  clearSelection: (workspaceId: string) => void;
  openCaptureModal: (args?: {
    draft?: Partial<ResearchComposerState>;
    seedToken?: string | null;
    contextLabel?: string;
  }) => void;
  closeCaptureModal: () => void;
  updateCaptureDraft: (patch: Partial<ResearchComposerState>) => void;
  openCreateWorkspaceModal: (tickerDraft?: string) => void;
  closeCreateWorkspaceModal: () => void;
  setCreateWorkspaceTickerDraft: (tickerDraft: string) => void;
  setMobilePane: (pane: ResearchMobilePane) => void;
  setLastNavigationIntentToken: (token: string | null) => void;
  setMutationPending: (key: string) => void;
  setMutationSucceeded: (key: string) => void;
  setMutationFailed: (key: string, error: string) => void;
  clearMutationState: (key: string) => void;
}

export const useResearchUiStore = create<ResearchUiStoreState>()(
  persist(
    (set, get) => ({
      viewByWorkspaceId: {},
      filtersByWorkspaceId: {},
      memoDraftByWorkspaceId: {},
      density: 'comfortable',
      sidebarCollapsed: false,
      inspectorPinned: true,
      memoPreview: true,
      activeWorkspaceId: null,
      selectionByWorkspaceId: {},
      captureModal: {
        isOpen: false,
        draft: createInitialResearchComposerState(),
        seedToken: null,
      },
      createWorkspaceModal: {
        isOpen: false,
        tickerDraft: '',
      },
      mobilePane: 'none',
      lastNavigationIntentToken: null,
      mutationStateByKey: {},
      initializeWorkspaceState: (workspaceId, defaultView) => {
        set((state) => ({
          viewByWorkspaceId: state.viewByWorkspaceId[workspaceId]
            ? state.viewByWorkspaceId
            : { ...state.viewByWorkspaceId, [workspaceId]: defaultView },
          filtersByWorkspaceId: state.filtersByWorkspaceId[workspaceId]
            ? state.filtersByWorkspaceId
            : {
                ...state.filtersByWorkspaceId,
                [workspaceId]: { ...defaultResearchFilters },
              },
          memoDraftByWorkspaceId: state.memoDraftByWorkspaceId[workspaceId]
            ? state.memoDraftByWorkspaceId
            : { ...state.memoDraftByWorkspaceId, [workspaceId]: '' },
          selectionByWorkspaceId: state.selectionByWorkspaceId[workspaceId]
            ? state.selectionByWorkspaceId
            : {
                ...state.selectionByWorkspaceId,
                [workspaceId]: defaultSelection(),
              },
        }));
      },
      setActiveWorkspaceId: (workspaceId) => set({ activeWorkspaceId: workspaceId }),
      setWorkspaceView: (workspaceId, view) =>
        set((state) => ({
          viewByWorkspaceId: {
            ...state.viewByWorkspaceId,
            [workspaceId]: view,
          },
        })),
      setWorkspaceFilters: (workspaceId, patch) =>
        set((state) => ({
          filtersByWorkspaceId: {
            ...state.filtersByWorkspaceId,
            [workspaceId]: {
              ...(state.filtersByWorkspaceId[workspaceId] ?? defaultResearchFilters),
              ...patch,
            },
          },
        })),
      resetWorkspaceFilters: (workspaceId) =>
        set((state) => ({
          filtersByWorkspaceId: {
            ...state.filtersByWorkspaceId,
            [workspaceId]: { ...defaultResearchFilters },
          },
        })),
      setMemoDraft: (workspaceId, value) =>
        set((state) => ({
          memoDraftByWorkspaceId: {
            ...state.memoDraftByWorkspaceId,
            [workspaceId]: value,
          },
        })),
      setDensity: (density) => set({ density }),
      setSidebarCollapsed: (sidebarCollapsed) => set({ sidebarCollapsed }),
      toggleSidebarCollapsed: () =>
        set((state) => ({ sidebarCollapsed: !state.sidebarCollapsed })),
      setInspectorPinned: (inspectorPinned) => set({ inspectorPinned }),
      toggleInspectorPinned: () =>
        set((state) => ({ inspectorPinned: !state.inspectorPinned })),
      setMemoPreview: (memoPreview) => set({ memoPreview }),
      toggleMemoPreview: () => set((state) => ({ memoPreview: !state.memoPreview })),
      selectNote: (workspaceId, noteId) =>
        set((state) => ({
          selectionByWorkspaceId: {
            ...state.selectionByWorkspaceId,
            [workspaceId]: { noteId, ghostId: null },
          },
        })),
      selectGhost: (workspaceId, ghostId) =>
        set((state) => ({
          selectionByWorkspaceId: {
            ...state.selectionByWorkspaceId,
            [workspaceId]: { noteId: null, ghostId },
          },
        })),
      clearSelection: (workspaceId) =>
        set((state) => ({
          selectionByWorkspaceId: {
            ...state.selectionByWorkspaceId,
            [workspaceId]: defaultSelection(),
          },
        })),
      openCaptureModal: (args = {}) => {
        const activeWorkspaceId = get().activeWorkspaceId;
        const baseDraft = createInitialResearchComposerState(activeWorkspaceId);
        const draft = {
          ...baseDraft,
          ...args.draft,
          workspaceId:
            args.draft?.workspaceId ?? baseDraft.workspaceId ?? '',
        };
        set({
          captureModal: {
            isOpen: true,
            draft,
            seedToken: args.seedToken ?? null,
            contextLabel: args.contextLabel,
          },
        });
      },
      closeCaptureModal: () => {
        const activeWorkspaceId = get().activeWorkspaceId;
        set({
          captureModal: {
            isOpen: false,
            draft: createInitialResearchComposerState(activeWorkspaceId),
            seedToken: null,
            contextLabel: undefined,
          },
        });
      },
      updateCaptureDraft: (patch) =>
        set((state) => ({
          captureModal: {
            ...state.captureModal,
            draft: {
              ...state.captureModal.draft,
              ...patch,
              fileIds:
                patch.workspaceId !== undefined &&
                patch.workspaceId !== state.captureModal.draft.workspaceId
                  ? []
                  : patch.fileIds ?? state.captureModal.draft.fileIds,
            },
          },
        })),
      openCreateWorkspaceModal: (tickerDraft = '') =>
        set({
          createWorkspaceModal: {
            isOpen: true,
            tickerDraft,
          },
        }),
      closeCreateWorkspaceModal: () =>
        set({
          createWorkspaceModal: {
            isOpen: false,
            tickerDraft: '',
          },
        }),
      setCreateWorkspaceTickerDraft: (tickerDraft) =>
        set((state) => ({
          createWorkspaceModal: {
            ...state.createWorkspaceModal,
            tickerDraft,
          },
        })),
      setMobilePane: (mobilePane) => set({ mobilePane }),
      setLastNavigationIntentToken: (lastNavigationIntentToken) =>
        set({ lastNavigationIntentToken }),
      setMutationPending: (key) =>
        set((state) => ({
          mutationStateByKey: {
            ...state.mutationStateByKey,
            [key]: {
              pending: true,
              error: null,
            },
          },
        })),
      setMutationSucceeded: (key) =>
        set((state) => ({
          mutationStateByKey: {
            ...state.mutationStateByKey,
            [key]: {
              pending: false,
              error: null,
            },
          },
        })),
      setMutationFailed: (key, error) =>
        set((state) => ({
          mutationStateByKey: {
            ...state.mutationStateByKey,
            [key]: {
              pending: false,
              error,
            },
          },
        })),
      clearMutationState: (key) =>
        set((state) => {
          if (!(key in state.mutationStateByKey)) {
            return state;
          }

          const nextMutationStateByKey = { ...state.mutationStateByKey };
          delete nextMutationStateByKey[key];
          return {
            mutationStateByKey: nextMutationStateByKey,
          };
        }),
    }),
    {
      name: 'mosaiciq.research.ui',
      storage: researchUiStorage,
      partialize: (state) => ({
        viewByWorkspaceId: state.viewByWorkspaceId,
        filtersByWorkspaceId: state.filtersByWorkspaceId,
        memoDraftByWorkspaceId: state.memoDraftByWorkspaceId,
        density: state.density,
        sidebarCollapsed: state.sidebarCollapsed,
        inspectorPinned: state.inspectorPinned,
        memoPreview: state.memoPreview,
      }),
    },
  ),
);

export const getWorkspaceSelection = (
  workspaceId: string | null,
  selectionByWorkspaceId: Record<string, ResearchSelectionState>,
) => {
  if (!workspaceId) {
    return defaultSelection();
  }

  return selectionByWorkspaceId[workspaceId] ?? defaultSelection();
};

export const getMutationStatus = (
  mutationStateByKey: Record<string, ResearchActionStatus>,
  key: string,
): ResearchActionStatus => mutationStateByKey[key] ?? { pending: false, error: null };
