import { ref, readonly } from 'vue'
import { useAquaticState } from './useAquaticState'
import type { AquaticEvent, ActiveEvent, EventFrequency, TimeOfDay, Season, DepthZone } from './types'

// ── Event catalog ──

const MINUTE_EVENTS: AquaticEvent[] = [
  { id: 'school-of-fish', name: 'School of Fish', frequency: 'minutes', minInterval: 120_000, maxInterval: 480_000, duration: 15_000, cssClass: 'evt-school-of-fish' },
  { id: 'bubble-burst', name: 'Bubble Burst', frequency: 'minutes', minInterval: 120_000, maxInterval: 480_000, duration: 8_000, cssClass: 'evt-bubble-burst' },
  { id: 'bioluminescent-flash', name: 'Bioluminescent Flash', frequency: 'minutes', minInterval: 180_000, maxInterval: 480_000, duration: 10_000, cssClass: 'evt-bioluminescent-flash' },
  { id: 'plankton-drift', name: 'Plankton Drift', frequency: 'minutes', minInterval: 150_000, maxInterval: 420_000, duration: 12_000, cssClass: 'evt-plankton-drift' },
  { id: 'fish-chase', name: 'Fish Chase', frequency: 'minutes', minInterval: 120_000, maxInterval: 360_000, duration: 10_000, cssClass: 'evt-fish-chase' },
]

const HOUR_EVENTS: AquaticEvent[] = [
  { id: 'whale-shadow', name: 'Whale Shadow', frequency: 'hours', minInterval: 3_600_000, maxInterval: 14_400_000, duration: 20_000, cssClass: 'evt-whale-shadow' },
  { id: 'current-change', name: 'Current Change', frequency: 'hours', minInterval: 3_600_000, maxInterval: 10_800_000, duration: 60_000, cssClass: 'evt-current-change' },
  { id: 'color-shift', name: 'Color Shift', frequency: 'hours', minInterval: 3_600_000, maxInterval: 14_400_000, duration: 30_000, cssClass: 'evt-color-shift' },
  { id: 'turtle-crossing', name: 'Turtle Crossing', frequency: 'hours', minInterval: 7_200_000, maxInterval: 14_400_000, duration: 25_000, cssClass: 'evt-turtle-crossing' },
  { id: 'manta-ray', name: 'Manta Ray', frequency: 'hours', minInterval: 5_400_000, maxInterval: 14_400_000, duration: 18_000, cssClass: 'evt-manta-ray' },
]

const DAY_EVENTS: AquaticEvent[] = [
  { id: 'day-night-shift', name: 'Day/Night Shift', frequency: 'days', minInterval: 86_400_000, maxInterval: 259_200_000, duration: 120_000, cssClass: 'evt-day-night-shift' },
  { id: 'seasonal-bloom', name: 'Seasonal Bloom', frequency: 'days', minInterval: 86_400_000, maxInterval: 259_200_000, duration: 180_000, cssClass: 'evt-seasonal-bloom' },
  { id: 'depth-change', name: 'Depth Change', frequency: 'days', minInterval: 86_400_000, maxInterval: 172_800_000, duration: 90_000, cssClass: 'evt-depth-change' },
  { id: 'kelp-forest', name: 'Kelp Forest', frequency: 'days', minInterval: 129_600_000, maxInterval: 259_200_000, duration: 150_000, cssClass: 'evt-kelp-forest' },
]

const MONTH_EVENTS: AquaticEvent[] = [
  { id: 'aurora-underwater', name: 'Aurora Underwater', frequency: 'months', minInterval: 2_592_000_000, maxInterval: 10_368_000_000, duration: 300_000, cssClass: 'evt-aurora-underwater' },
  { id: 'mythical-creature', name: 'Mythical Creature', frequency: 'months', minInterval: 2_592_000_000, maxInterval: 10_368_000_000, duration: 30_000, cssClass: 'evt-mythical-creature' },
  { id: 'volcanic-vent', name: 'Volcanic Vent', frequency: 'months', minInterval: 2_592_000_000, maxInterval: 7_776_000_000, duration: 120_000, cssClass: 'evt-volcanic-vent' },
  { id: 'crystal-formation', name: 'Crystal Formation', frequency: 'months', minInterval: 2_592_000_000, maxInterval: 10_368_000_000, duration: 240_000, cssClass: 'evt-crystal-formation' },
]

const STORAGE_KEY = 'aquatic-event-timestamps'

// ── Helpers ──

function pickRandom<T>(arr: T[]): T {
  return arr[Math.floor(Math.random() * arr.length)]
}

function randomBetween(min: number, max: number): number {
  return min + Math.random() * (max - min)
}

function loadTimestamps(): Record<string, number> {
  try {
    return JSON.parse(localStorage.getItem(STORAGE_KEY) || '{}')
  } catch {
    return {}
  }
}

function saveTimestamp(frequency: EventFrequency) {
  const ts = loadTimestamps()
  ts[frequency] = Date.now()
  localStorage.setItem(STORAGE_KEY, JSON.stringify(ts))
}

// ── Composable ──

export function useAquaticEvents() {
  const { setEventModifier, clearEventModifier, setTimeOfDay, setSeason, setDepthZone } = useAquaticState()
  const activeEvents = ref<ActiveEvent[]>([])
  const timerIds: number[] = []

  const TIERS: { frequency: EventFrequency; events: AquaticEvent[] }[] = [
    { frequency: 'minutes', events: MINUTE_EVENTS },
    { frequency: 'hours', events: HOUR_EVENTS },
    { frequency: 'days', events: DAY_EVENTS },
    { frequency: 'months', events: MONTH_EVENTS },
  ]

  function start() {
    const timestamps = loadTimestamps()
    const now = Date.now()

    for (const tier of TIERS) {
      const lastFired = timestamps[tier.frequency] || 0
      const elapsed = now - lastFired
      // Pick a representative event to check interval
      const sample = tier.events[0]
      const minWait = sample.minInterval

      if (elapsed >= minWait) {
        // Enough time passed — trigger one soon (5-30s from now)
        const initialDelay = randomBetween(5_000, 30_000)
        const id = window.setTimeout(() => {
          triggerRandomFromTier(tier.frequency, tier.events)
          scheduleTier(tier.frequency, tier.events)
        }, initialDelay)
        timerIds.push(id)
      } else {
        // Wait for remaining time, then start normal cycle
        const remaining = minWait - elapsed
        const id = window.setTimeout(() => {
          scheduleTier(tier.frequency, tier.events)
        }, remaining)
        timerIds.push(id)
      }
    }
  }

  function stop() {
    timerIds.forEach(id => clearTimeout(id))
    timerIds.length = 0
    // Clean up active events
    for (const ae of activeEvents.value) {
      clearEventModifier(ae.event.id)
    }
    activeEvents.value = []
  }

  function scheduleTier(frequency: EventFrequency, events: AquaticEvent[]) {
    const event = pickRandom(events)
    const delay = randomBetween(event.minInterval, event.maxInterval)
    const id = window.setTimeout(() => {
      triggerRandomFromTier(frequency, events)
      scheduleTier(frequency, events)
    }, delay)
    timerIds.push(id)
  }

  function triggerRandomFromTier(frequency: EventFrequency, events: AquaticEvent[]) {
    // Filter out already-active events
    const available = events.filter(e =>
      !activeEvents.value.some(ae => ae.event.id === e.id)
    )
    if (available.length === 0) return

    const event = pickRandom(available)
    triggerEvent(event, frequency)
  }

  function triggerEvent(event: AquaticEvent, frequency: EventFrequency) {
    const now = Date.now()
    const active: ActiveEvent = {
      event,
      startedAt: now,
      endsAt: now + event.duration,
    }
    activeEvents.value = [...activeEvents.value, active]
    setEventModifier(event.id, event.cssClass)
    saveTimestamp(frequency)

    // Special state mutations for certain events
    if (event.id === 'day-night-shift') {
      const options: TimeOfDay[] = ['day', 'twilight', 'night']
      setTimeOfDay(pickRandom(options))
    }
    if (event.id === 'seasonal-bloom') {
      const options: Season[] = ['spring', 'summer', 'autumn', 'winter']
      setSeason(pickRandom(options))
    }
    if (event.id === 'depth-change') {
      const options: DepthZone[] = ['surface', 'midwater', 'deep']
      setDepthZone(pickRandom(options))
    }

    // Schedule end
    const endId = window.setTimeout(() => {
      activeEvents.value = activeEvents.value.filter(ae => ae !== active)
      clearEventModifier(event.id)
    }, event.duration)
    timerIds.push(endId)
  }

  return {
    activeEvents: readonly(activeEvents),
    start,
    stop,
  }
}
