'use client'

import { useState, useEffect, useCallback, useRef } from 'react'
import { FMScenario, FMResult, FMComputeResponse } from '../types'

export function useFinancialModel() {
  const [scenarios, setScenarios] = useState<FMScenario[]>([])
  const [activeScenarioId, setActiveScenarioId] = useState<string | null>(null)
  const [compareMode, setCompareMode] = useState(false)
  const [results, setResults] = useState<Map<string, FMComputeResponse>>(new Map())
  const [loading, setLoading] = useState(true)
  const [computing, setComputing] = useState(false)
  const computeTimer = useRef<NodeJS.Timeout | null>(null)

  // Load scenarios on mount
  useEffect(() => {
    async function load() {
      try {
        const res = await fetch('/api/financial-model')
        if (res.ok) {
          const data: FMScenario[] = await res.json()
          setScenarios(data)
          const defaultScenario = data.find(s => s.is_default) || data[0]
          if (defaultScenario) {
            setActiveScenarioId(defaultScenario.id)
          }
        }
      } catch (err) {
        console.error('Failed to load financial model:', err)
      } finally {
        setLoading(false)
      }
    }
    load()
  }, [])

  // Compute when active scenario changes
  useEffect(() => {
    if (activeScenarioId && !results.has(activeScenarioId)) {
      compute(activeScenarioId)
    }
  }, [activeScenarioId]) // eslint-disable-line react-hooks/exhaustive-deps

  const compute = useCallback(async (scenarioId: string) => {
    setComputing(true)
    try {
      const res = await fetch('/api/financial-model/compute', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ scenarioId }),
      })
      if (res.ok) {
        const data: FMComputeResponse = await res.json()
        setResults(prev => new Map(prev).set(scenarioId, data))
      }
    } catch (err) {
      console.error('Compute failed:', err)
    } finally {
      setComputing(false)
    }
  }, [])

  const updateAssumption = useCallback(async (scenarioId: string, key: string, value: number | number[]) => {
    // Optimistic update in local state
    setScenarios(prev => prev.map(s => {
      if (s.id !== scenarioId) return s
      return {
        ...s,
        assumptions: s.assumptions.map(a => a.key === key ? { ...a, value } : a),
      }
    }))

    // Save to DB
    await fetch('/api/financial-model/assumptions', {
      method: 'PUT',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ scenarioId, key, value }),
    })

    // Debounced recompute
    if (computeTimer.current) clearTimeout(computeTimer.current)
    computeTimer.current = setTimeout(() => compute(scenarioId), 300)
  }, [compute])

  const computeAll = useCallback(async () => {
    for (const s of scenarios) {
      await compute(s.id)
    }
  }, [scenarios, compute])

  const activeScenario = scenarios.find(s => s.id === activeScenarioId) || null
  const activeResults = activeScenarioId ? results.get(activeScenarioId) || null : null

  return {
    scenarios,
    activeScenario,
    activeScenarioId,
    setActiveScenarioId,
    activeResults,
    results,
    loading,
    computing,
    compareMode,
    setCompareMode,
    compute,
    computeAll,
    updateAssumption,
  }
}
