import { create } from 'zustand'
import { persist, createJSONStorage } from 'zustand/middleware'

export type BottomPanelTab = 'setup' | 'run' | 'terminal'
export type TerminalDock = 'right' | 'bottom'

const LEFT_SIDEBAR_DEFAULT = 240
const LEFT_SIDEBAR_MIN = 200
const LEFT_SIDEBAR_MAX = 400
const RIGHT_SIDEBAR_DEFAULT = 280
const SPLIT_FRACTION_DEFAULT = 0.54
const SPLIT_FRACTION_MIN = 0.15
const SPLIT_FRACTION_MAX = 0.85
const BOTTOM_DOCK_HEIGHT_DEFAULT = 250
const BOTTOM_DOCK_HEIGHT_MIN = 120
const BOTTOM_DOCK_HEIGHT_MAX = 600

// Module-level Set to track suppression keys — kept outside Zustand state
// because Set cannot be serialized by the persist middleware.
const _ghosttySuppressKeys = new Set<string>()

interface LayoutState {
  leftSidebarWidth: number
  leftSidebarCollapsed: boolean
  rightSidebarWidth: number
  rightSidebarCollapsed: boolean
  bottomPanelTab: BottomPanelTab
  terminalDock: TerminalDock
  bottomDockHeight: number
  ghosttyOverlaySuppressed: boolean
  splitFractionByEntity: Record<string, number>
  setLeftSidebarWidth: (width: number) => void
  toggleLeftSidebar: () => void
  setLeftSidebarCollapsed: (collapsed: boolean) => void
  setRightSidebarWidth: (width: number) => void
  toggleRightSidebar: () => void
  setRightSidebarCollapsed: (collapsed: boolean) => void
  setBottomPanelTab: (tab: BottomPanelTab) => void
  setTerminalDock: (dock: TerminalDock) => void
  setBottomDockHeight: (height: number) => void
  setGhosttyOverlaySuppressed: (suppressed: boolean) => void
  pushGhosttySuppression: (key: string) => void
  popGhosttySuppression: (key: string) => void
  setSplitFraction: (entityKey: string, fraction: number) => void
}

export const useLayoutStore = create<LayoutState>()(
  persist(
    (set) => ({
      leftSidebarWidth: LEFT_SIDEBAR_DEFAULT,
      leftSidebarCollapsed: false,
      rightSidebarWidth: RIGHT_SIDEBAR_DEFAULT,
      rightSidebarCollapsed: false,
      bottomPanelTab: 'terminal' as BottomPanelTab,
      terminalDock: 'right' as TerminalDock,
      bottomDockHeight: BOTTOM_DOCK_HEIGHT_DEFAULT,
      ghosttyOverlaySuppressed: false,
      splitFractionByEntity: {} as Record<string, number>,

      setLeftSidebarWidth: (width: number) => {
        const clampedWidth = Math.min(Math.max(width, LEFT_SIDEBAR_MIN), LEFT_SIDEBAR_MAX)
        set({ leftSidebarWidth: clampedWidth })
      },

      toggleLeftSidebar: () => {
        set((state) => ({ leftSidebarCollapsed: !state.leftSidebarCollapsed }))
      },

      setLeftSidebarCollapsed: (collapsed: boolean) => {
        set({ leftSidebarCollapsed: collapsed })
      },

      setRightSidebarWidth: (width: number) => {
        set({ rightSidebarWidth: Math.max(width, 200) })
      },

      toggleRightSidebar: () => {
        set((state) => ({ rightSidebarCollapsed: !state.rightSidebarCollapsed }))
      },

      setRightSidebarCollapsed: (collapsed: boolean) => {
        set({ rightSidebarCollapsed: collapsed })
      },

      setBottomPanelTab: (tab: BottomPanelTab) => {
        set({ bottomPanelTab: tab })
      },

      setTerminalDock: (dock: TerminalDock) => {
        set({ terminalDock: dock })
      },

      setBottomDockHeight: (height: number) => {
        const clamped = Math.min(Math.max(height, BOTTOM_DOCK_HEIGHT_MIN), BOTTOM_DOCK_HEIGHT_MAX)
        set({ bottomDockHeight: clamped })
      },

      setGhosttyOverlaySuppressed: (suppressed: boolean) => {
        if (suppressed) {
          _ghosttySuppressKeys.add('_compat')
        } else {
          _ghosttySuppressKeys.delete('_compat')
        }
        set({ ghosttyOverlaySuppressed: _ghosttySuppressKeys.size > 0 })
      },

      pushGhosttySuppression: (key: string) => {
        _ghosttySuppressKeys.add(key)
        set({ ghosttyOverlaySuppressed: true })
      },

      popGhosttySuppression: (key: string) => {
        _ghosttySuppressKeys.delete(key)
        set({ ghosttyOverlaySuppressed: _ghosttySuppressKeys.size > 0 })
      },

      setSplitFraction: (entityKey: string, fraction: number) => {
        const clamped = Math.min(Math.max(fraction, SPLIT_FRACTION_MIN), SPLIT_FRACTION_MAX)
        set((state) => ({
          splitFractionByEntity: { ...state.splitFractionByEntity, [entityKey]: clamped }
        }))
      }
    }),
    {
      name: 'hive-layout',
      storage: createJSONStorage(() => localStorage),
      partialize: (state) => ({
        leftSidebarWidth: state.leftSidebarWidth,
        leftSidebarCollapsed: state.leftSidebarCollapsed,
        rightSidebarWidth: state.rightSidebarWidth,
        rightSidebarCollapsed: state.rightSidebarCollapsed,
        splitFractionByEntity: state.splitFractionByEntity,
        terminalDock: state.terminalDock,
        bottomDockHeight: state.bottomDockHeight
      })
    }
  )
)

export const LAYOUT_CONSTRAINTS = {
  leftSidebar: {
    default: LEFT_SIDEBAR_DEFAULT,
    min: LEFT_SIDEBAR_MIN,
    max: LEFT_SIDEBAR_MAX
  },
  rightSidebar: {
    default: RIGHT_SIDEBAR_DEFAULT,
    min: 200
  },
  splitFraction: {
    default: SPLIT_FRACTION_DEFAULT,
    min: SPLIT_FRACTION_MIN,
    max: SPLIT_FRACTION_MAX
  },
  bottomDock: {
    default: BOTTOM_DOCK_HEIGHT_DEFAULT,
    min: BOTTOM_DOCK_HEIGHT_MIN,
    max: BOTTOM_DOCK_HEIGHT_MAX
  }
}
