import { create } from 'zustand';
import { useShallow } from 'zustand/react/shallow';
import { immer } from 'zustand/middleware/immer';
import { versionService } from '../services/versions';
import { Version, Workflow } from '../types/workflow';

interface VersionState {
  // Version list
  versions: Version[];
  isLoading: boolean;
  loadError: string | null;

  // Selected version for viewing
  selectedVersion: Version | null;

  // Restore operation
  isRestoring: boolean;
  restoreError: string | null;

  // Make live operation
  isMakingLive: boolean;
  makeLiveError: string | null;

  // Panel visibility
  isHistoryPanelOpen: boolean;
}

interface VersionActions {
  // Load versions for a workflow
  loadVersions: (workflowId: number) => Promise<void>;

  // Select a version for viewing
  selectVersion: (version: Version | null) => void;

  // Restore a version
  restoreVersion: (
    workflowId: number,
    versionId: number,
  ) => Promise<{ success: boolean; workflow?: Workflow }>;

  // Make a version live
  makeVersionLive: (
    workflowId: number,
    versionId: number,
  ) => Promise<{ success: boolean; version?: Version }>;

  // Panel controls
  openHistoryPanel: () => void;
  closeHistoryPanel: () => void;
  toggleHistoryPanel: () => void;

  // Reset
  reset: () => void;
}

type VersionStore = VersionState & VersionActions;

const initialState: VersionState = {
  versions: [],
  isLoading: false,
  loadError: null,
  selectedVersion: null,
  isRestoring: false,
  restoreError: null,
  isMakingLive: false,
  makeLiveError: null,
  isHistoryPanelOpen: false,
};

export const useVersionStore = create<VersionStore>()(
  immer((set, get) => ({
    ...initialState,

    loadVersions: async (workflowId: number) => {
      set((state) => {
        state.isLoading = true;
        state.loadError = null;
      });

      try {
        const versions = await versionService.getVersions(workflowId);
        set((state) => {
          state.versions = versions;
          state.isLoading = false;
        });
      } catch (err) {
        set((state) => {
          state.loadError = err instanceof Error ? err.message : 'Failed to load versions';
          state.isLoading = false;
        });
      }
    },

    selectVersion: (version) =>
      set((state) => {
        state.selectedVersion = version;
      }),

    restoreVersion: async (workflowId: number, versionId: number) => {
      const { isRestoring } = get();
      if (isRestoring) return { success: false };

      set((state) => {
        state.isRestoring = true;
        state.restoreError = null;
      });

      try {
        const response = await versionService.restoreVersion(workflowId, versionId);
        set((state) => {
          state.isRestoring = false;
          state.selectedVersion = null;
        });
        return { success: true, workflow: response.workflow };
      } catch (err) {
        set((state) => {
          state.restoreError = err instanceof Error ? err.message : 'Failed to restore version';
          state.isRestoring = false;
        });
        return { success: false };
      }
    },

    makeVersionLive: async (workflowId: number, versionId: number) => {
      const { isMakingLive } = get();
      if (isMakingLive) return { success: false };

      set((state) => {
        state.isMakingLive = true;
        state.makeLiveError = null;
      });

      try {
        const response = await versionService.makeVersionLive(workflowId, versionId);
        // Reload versions to update is_published flags
        await get().loadVersions(workflowId);
        set((state) => {
          state.isMakingLive = false;
        });
        return { success: true, version: response.version };
      } catch (err) {
        set((state) => {
          state.makeLiveError = err instanceof Error ? err.message : 'Failed to make version live';
          state.isMakingLive = false;
        });
        return { success: false };
      }
    },

    openHistoryPanel: () =>
      set((state) => {
        state.isHistoryPanelOpen = true;
      }),

    closeHistoryPanel: () =>
      set((state) => {
        state.isHistoryPanelOpen = false;
        state.selectedVersion = null;
      }),

    toggleHistoryPanel: () =>
      set((state) => {
        state.isHistoryPanelOpen = !state.isHistoryPanelOpen;
        if (!state.isHistoryPanelOpen) {
          state.selectedVersion = null;
        }
      }),

    reset: () => set(initialState),
  })),
);

// --- Granular selectors to prevent unnecessary re-renders ---

// State selectors (primitive values — stable by default)
export const useVersions = () => useVersionStore((s) => s.versions);
export const useIsLoadingVersions = () => useVersionStore((s) => s.isLoading);
export const useVersionLoadError = () => useVersionStore((s) => s.loadError);

// Grouped selectors (stable references via useShallow)
export const useVersionHistory = () =>
  useVersionStore(
    useShallow((s) => ({
      isHistoryPanelOpen: s.isHistoryPanelOpen,
      openHistoryPanel: s.openHistoryPanel,
      closeHistoryPanel: s.closeHistoryPanel,
    })),
  );

export const useVersionActions = () =>
  useVersionStore(
    useShallow((s) => ({
      loadVersions: s.loadVersions,
      restoreVersion: s.restoreVersion,
      makeVersionLive: s.makeVersionLive,
      isRestoring: s.isRestoring,
      isMakingLive: s.isMakingLive,
    })),
  );
