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

// Building information interface
export interface BuildingInfo {
  id?: string
  cost: number
  levelRequirement: number
  title: string
  description: string
  production: {
    points?: number
    techParts?: number
  }
}

interface GameState {
  // Resources
  points: number
  
  // Buildings
  mouseFarms: number
  keyboardFactories: number
  monitorDisplays: number
  officeSpace: number
  serverRooms: number
  dataCenters: number
  dataCities: number
  dataCountries: number
  dataContinents: number
  dataWorlds: number
  dataMoons: number
  dataSolarSystems: number
  dataGalaxies: number
  dataUniverses: number
  dataGods: number
  
  // Building Levels
  mouseFarmsLevel: number
  keyboardFactoriesLevel: number
  monitorDisplaysLevel: number
  officeSpaceLevel: number
  serverRoomsLevel: number
  dataCentersLevel: number
  dataCitiesLevel: number
  dataCountriesLevel: number
  dataContinentsLevel: number
  dataWorldsLevel: number
  dataMoonsLevel: number
  dataSolarSystemsLevel: number
  dataGalaxiesLevel: number
  dataUniversesLevel: number
  dataGodsLevel: number
  
  // Upgrades
  autoClickers: number
  clickPower: number
  clickPowerUpgrades: number
  
  // Production rates
  pointsPerSecond: number

  // Player level
  playerLevel: number
  
  // Actions
  click: () => void
  buyBuilding: (buildingType: BuildingType) => void
  buyUpgrade: (upgradeType: UpgradeType) => void
  resetGame: () => void
  tick: () => void
  upgradeBuilding: (buildingType: BuildingType) => void
  getClickPowerUpgradeCost: () => number

  // New getter for available buildings
  getAvailableBuildings: () => BuildingInfo[]
}

// Building information with costs and requirements
export const BUILDING_INFO: Record<string, Omit<BuildingInfo, 'id'>> = {
  mouseFarms: {
    title: 'Mouse Farm',
    description: 'A basic facility that produces computer mice. Each mouse farm generates points automatically.',
    production: { points: 0.1 },
    cost: 10,
    levelRequirement: 1
  },
  keyboardFactories: {
    title: 'Keyboard Factory',
    description: 'Manufactures mechanical keyboards and generates tech parts. Essential for advanced upgrades.',
    production: { points: 0.2 },
    cost: 50,
    levelRequirement: 1
  },
  monitorDisplays: {
    title: 'Monitor Display',
    description: 'High-resolution displays that generate both points and tech parts. A balanced production facility.',
    production: { points: 0.2 },
    cost: 100,
    levelRequirement: 1
  },
  serverRooms: {
    title: 'Server Room',
    description: 'A powerful facility that generates significant amounts of both resources. Requires proper cooling.',
    production: { points: 5 },
    cost: 1000,
    levelRequirement: 1
  },
  dataCenters: {
    title: 'Data Center',
    description: 'The ultimate production facility. Generates massive amounts of resources but requires significant investment.',
    production: { points: 25 },
    cost: 5000,
    levelRequirement: 5
  },
  dataCities: {
    title: 'Data City',
    description: 'A massive network of data centers spanning an entire city. Requires level 10 to unlock.',
    production: { points: 100 },
    cost: 25000,
    levelRequirement: 10
  },
  dataCountries: {
    title: 'Data Country',
    description: 'A country-wide network of data cities. Requires level 20 to unlock.',
    production: { points: 500 },
    cost: 100000,
    levelRequirement: 20
  },
  dataContinents: {
    title: 'Data Continent',
    description: 'A continent-spanning network of data countries. Requires level 30 to unlock.',
    production: { points: 2500 },
    cost: 500000,
    levelRequirement: 30
  },
  dataWorlds: {
    title: 'Data World',
    description: 'A world-wide network of data continents. Requires level 40 to unlock.',
    production: { points: 10000 },
    cost: 2000000,
    levelRequirement: 40
  },
  dataMoons: {
    title: 'Data Moon',
    description: 'A moon-sized data processing facility. Requires level 50 to unlock.',
    production: { points: 50000 },
    cost: 10000000,
    levelRequirement: 50
  },
  dataSolarSystems: {
    title: 'Data Solar System',
    description: 'A solar system-wide network of data moons. Requires level 60 to unlock.',
    production: { points: 250000 },
    cost: 50000000,
    levelRequirement: 60
  },
  dataGalaxies: {
    title: 'Data Galaxy',
    description: 'A galaxy-spanning network of data solar systems. Requires level 70 to unlock.',
    production: { points: 1000000 },
    cost: 200000000,
    levelRequirement: 70
  },
  dataUniverses: {
    title: 'Data Universe',
    description: 'A universe-wide network of data galaxies. Requires level 80 to unlock.',
    production: { points: 5000000 },
    cost: 1000000000,
    levelRequirement: 80
  },
  dataGods: {
    title: 'Data God',
    description: 'The ultimate data processing entity. Requires level 90 to unlock.',
    production: { points: 25000000 },
    cost: 5000000000,
    levelRequirement: 90
  }
}

const initialState = {
  points: 0,
  mouseFarms: 0,
  keyboardFactories: 0,
  monitorDisplays: 0,
  officeSpace: 0,
  serverRooms: 0,
  dataCenters: 0,
  dataCities: 0,
  dataCountries: 0,
  dataContinents: 0,
  dataWorlds: 0,
  dataMoons: 0,
  dataSolarSystems: 0,
  dataGalaxies: 0,
  dataUniverses: 0,
  dataGods: 0,
  mouseFarmsLevel: 1,
  keyboardFactoriesLevel: 1,
  monitorDisplaysLevel: 1,
  officeSpaceLevel: 1,
  serverRoomsLevel: 1,
  dataCentersLevel: 1,
  dataCitiesLevel: 1,
  dataCountriesLevel: 1,
  dataContinentsLevel: 1,
  dataWorldsLevel: 1,
  dataMoonsLevel: 1,
  dataSolarSystemsLevel: 1,
  dataGalaxiesLevel: 1,
  dataUniversesLevel: 1,
  dataGodsLevel: 1,
  autoClickers: 0,
  clickPower: 1,
  clickPowerUpgrades: 0,
  pointsPerSecond: 0,
  playerLevel: 1,
}

// Production rates per building
const PRODUCTION_RATES = {
  mouseFarms: { points: 0.1 },
  keyboardFactories: { points: 0.2 },
  monitorDisplays: { points: 0.2 },
  officeSpace: { points: 1 },
  serverRooms: { points: 5 },
  dataCenters: { points: 25 },
  dataCities: { points: 100 },
  dataCountries: { points: 500 },
  dataContinents: { points: 2500 },
  dataWorlds: { points: 10000 },
  dataMoons: { points: 50000 },
  dataSolarSystems: { points: 250000 },
  dataGalaxies: { points: 1000000 },
  dataUniverses: { points: 5000000 },
  dataGods: { points: 25000000 },
}

// Building costs
const BUILDING_COSTS = {
  mouseFarms: 10,
  keyboardFactories: 50,
  monitorDisplays: 100,
  officeSpace: 500,
  serverRooms: 1000,
  dataCenters: 5000,
  dataCities: 25000,
  dataCountries: 100000,
  dataContinents: 500000,
  dataWorlds: 2000000,
  dataMoons: 10000000,
  dataSolarSystems: 50000000,
  dataGalaxies: 200000000,
  dataUniverses: 1000000000,
  dataGods: 5000000000,
}

// Building level requirements
const BUILDING_LEVEL_REQUIREMENTS = {
  mouseFarms: 1,
  keyboardFactories: 1,
  monitorDisplays: 1,
  officeSpace: 1,
  serverRooms: 1,
  dataCenters: 5,
  dataCities: 10,
  dataCountries: 20,
  dataContinents: 30,
  dataWorlds: 40,
  dataMoons: 50,
  dataSolarSystems: 60,
  dataGalaxies: 70,
  dataUniverses: 80,
  dataGods: 90,
}

// Calculate upgrade cost based on current level
const calculateUpgradeCost = (buildingType: BuildingType, currentLevel: number): number => {
  const baseCost = BUILDING_COSTS[buildingType]
  return Math.floor(baseCost * Math.pow(1.5, currentLevel - 1))
}

// Helper function to calculate click power upgrade cost
const calculateClickPowerUpgradeCost = (upgrades: number): number => {
  return Math.floor(20 * Math.pow(1.5, upgrades));
}

type BuildingType = keyof typeof BUILDING_COSTS
type UpgradeType = 'autoClickers' | 'clickPower'

// Helper function to get available buildings
const getAvailableBuildings = (playerLevel: number): BuildingInfo[] => {
  return Object.entries(BUILDING_INFO)
    .filter(([_, building]) => building.levelRequirement <= playerLevel)
    .map(([id, building]) => ({
      ...building,
      id
    }))
    .sort((a, b) => a.cost - b.cost)
}

export const useGameStore = create<GameState>()(
  persist(
    (set, get) => ({
      ...initialState,

      click: () => {
        const { clickPower, autoClickers } = get()
        const pointsPerClick = clickPower * (1 + autoClickers * 0.1)
        set((state) => ({
          points: state.points + pointsPerClick,
        }))
      },

      buyBuilding: (buildingType: BuildingType) => {
        const state = get()
        const cost = BUILDING_COSTS[buildingType]
        if (state.points >= cost) {
          set((state) => {
            const newCount = state[buildingType] + 1
            const rates = PRODUCTION_RATES[buildingType]
            const level = state[`${buildingType}Level` as keyof GameState] as number
            
            return {
              points: state.points - cost,
              [buildingType]: newCount,
              pointsPerSecond: state.pointsPerSecond + rates.points * level,
            }
          })
        }
      },

      buyUpgrade: (upgradeType: UpgradeType) => {
        const state = get()
        
        // Handle upgrade purchase
        if (upgradeType === 'clickPower') {
          const cost = calculateClickPowerUpgradeCost(state.clickPowerUpgrades)
          
          if (state.points >= cost) {
            set((state) => ({
              points: state.points - cost,
              clickPower: state.clickPower + 1,
              clickPowerUpgrades: state.clickPowerUpgrades + 1
            }))
          }
        }
      },

      getClickPowerUpgradeCost: () => {
        const { clickPowerUpgrades } = get()
        return calculateClickPowerUpgradeCost(clickPowerUpgrades)
      },

      upgradeBuilding: (buildingType: BuildingType) => {
        const state = get()
        const currentLevel = state[`${buildingType}Level` as keyof GameState] as number
        const cost = calculateUpgradeCost(buildingType, currentLevel)
        
        if (state.points >= cost && state[buildingType] > 0) {
          set((state) => {
            const newLevel = (state[`${buildingType}Level` as keyof GameState] as number) + 1
            const rates = PRODUCTION_RATES[buildingType]
            const count = state[buildingType]
            
            // Calculate the new points per second
            const oldProduction = rates.points * (newLevel - 1) * count
            const newProduction = rates.points * newLevel * count
            const productionDifference = newProduction - oldProduction
            
            return {
              points: state.points - cost,
              [`${buildingType}Level`]: newLevel,
              pointsPerSecond: state.pointsPerSecond + productionDifference,
            }
          })
        }
      },
      
      resetGame: () => {
        set(initialState)
      },

      tick: () => {
        const state = get()
        
        // Add production from buildings
        if (state.pointsPerSecond > 0) {
          set((state) => ({
            points: state.points + state.pointsPerSecond / 10, // 10 ticks per second
          }))
        }
        
        // Update player level based on points per second
        const playerLevel = Math.max(1, Math.floor(Math.log10(state.pointsPerSecond) + 1))
        if (playerLevel !== state.playerLevel) {
          set({ playerLevel })
        }
      },

      getAvailableBuildings: () => {
        const { playerLevel } = get()
        return getAvailableBuildings(playerLevel)
      },
    }),
    {
      name: 'clicker-game',
    }
  )
) 