import { create } from 'zustand'
import { devtools } from 'zustand/middleware'
import { NAMESPACE_COLORS } from '../data/mockResources'

export interface Krate {
  id: string
  type: string
  title: string
  x: number
  y: number
  width: number
  height: number
  color: string
  minimized: boolean
  windowLayout: WindowLayout
  windows: Map<string, KrateWindow>
}

export interface WindowLayout {
  cols: number
  rows: number
  cells: Map<string, { col: number; row: number; colSpan: number; rowSpan: number }>
}

export interface KrateWindow {
  id: string
  type: string
  title: string
  state: unknown
}

export interface WindowInfo {
  type: string
  title: string
}

export interface KrateStore {
  krates: Map<string, Krate>
  selectedKrateId: string | null
  addKrate: (krate: Krate) => void
  removeKrate: (id: string) => void
  selectKrate: (id: string | null) => void
  updateKrate: (id: string, updates: Partial<Krate>) => void
  createKrate: (title: string, type: string, namespace?: string, color?: string, windows?: WindowInfo[]) => void
}

const INITIAL_STATE: KrateStore = {
  krates: new Map(),
  selectedKrateId: null,
  addKrate: () => {},
  removeKrate: () => {},
  selectKrate: () => {},
  updateKrate: () => {},
  createKrate: () => {},
}

export const useKrateStore = create<KrateStore>()(
  devtools((set, get) => ({
    ...INITIAL_STATE,
    addKrate: (krate: Krate) =>
      set((state) => ({ krates: new Map(state.krates).set(krate.id, krate) })),
    removeKrate: (id: string) =>
      set((state) => {
        const newKrates = new Map(state.krates)
        newKrates.delete(id)
        return { krates: newKrates }
      }),
    selectKrate: (id: string | null) => set({ selectedKrateId: id }),
    updateKrate: (id: string, updates: Partial<Krate>) =>
      set((state) => {
        const existing = state.krates.get(id)
        if (!existing) return state
        return {
          krates: new Map(state.krates).set(id, { ...existing, ...updates }),
        }
      }),
    createKrate: (title: string, type: string, namespace?: string, color?: string, windows?: WindowInfo[]) => {
      const { krates } = get()
      
      const krateColor = color || (namespace ? NAMESPACE_COLORS[namespace] || '#6fb1ff' : '#6fb1ff')
      
      const findNonOverlappingPosition = (width: number, height: number, Krates: Map<string, Krate>): { x: number; y: number } => {
        const COLLISION_TOLERANCE = 20
        
        const getAABB = (krate: Krate) => ({
          x1: krate.x - COLLISION_TOLERANCE,
          y1: krate.y - COLLISION_TOLERANCE,
          x2: krate.x + krate.width + COLLISION_TOLERANCE,
          y2: krate.y + krate.height + COLLISION_TOLERANCE,
        })
        
        const rectsOverlap = (r1: any, r2: any) => {
          return r1.x1 < r2.x2 && r1.x2 > r2.x1 && r1.y1 < r2.y2 && r1.y2 > r2.y1
        }
        
        const checkOverlap = (x: number, y: number, Krates: Map<string, Krate>): boolean => {
          const newRect = {
            x1: x - COLLISION_TOLERANCE,
            y1: y - COLLISION_TOLERANCE,
            x2: x + width + COLLISION_TOLERANCE,
            y2: y + height + COLLISION_TOLERANCE,
          }
          
          for (const krate of Krates.values()) {
            const existingRect = getAABB(krate)
            if (rectsOverlap(newRect, existingRect)) {
              return true
            }
          }
          return false
        }
        
        let x = 100
        let y = 100
        let attempts = 0
        const maxAttempts = 100
        
        while (attempts < maxAttempts) {
          if (!checkOverlap(x, y, Krates)) {
            return { x, y }
          }
          
          x += width / 2
          if (x > 8000) {
            x = 100
            y += height / 2
          }
          attempts++
        }
        
        return { x, y }
      }
      
      const { x, y } = findNonOverlappingPosition(800, 600, krates)
      
      const defaultWindows: Map<string, KrateWindow> = new Map()
      
      const windowsToCreate = windows || (type === 'namespace' ? [{ type: 'collection', title: 'Status' }] : [{ type: 'logs', title: 'Logs' }, { type: 'describe', title: 'Describe' }])
      
      windowsToCreate.forEach((win, index) => {
        defaultWindows.set(`${title}-${index}`, {
          id: `${title}-${index}`,
          type: win.type,
          title: win.title,
          state: {},
        })
      })
      
      const newKrate: Krate = {
        id: `krate-${Date.now()}`,
        type,
        title,
        x,
        y,
        width: 800,
        height: 600,
        color: krateColor,
        minimized: false,
        windowLayout: {
          cols: 2,
          rows: 2,
          cells: new Map(),
        },
        windows: defaultWindows,
      }
      
      set((state) => ({
        krates: new Map(state.krates).set(newKrate.id, newKrate),
      }))
    },
  }))
)
