import { useMemo } from 'react'
import ReactECharts from 'echarts-for-react'
import { formatCurrency } from '@/lib/format'
import type { RoiResult } from '@/domain/roi'

interface CumulativeSavingsChartProps {
  roi: RoiResult          // caso ajustado (o base si no hay ajuste)
  horizonYears: number
  currency: string
  investment: number      // inversión ajustada (usada para cálculo de valores del eje Y)
  roiBase?: RoiResult     // caso base original — cuando presente, se muestra como línea secundaria
}

export function CumulativeSavingsChart({
  roi,
  horizonYears,
  currency,
  investment,
  roiBase,
}: CumulativeSavingsChartProps) {
  const option = useMemo(() => {
    const years = Array.from({ length: horizonYears + 1 }, (_, i) => i)
    const values = years.map((y) => roi.annualSavings * y - investment)

    const markLineData: unknown[] = []
    if (isFinite(roi.paybackYears) && roi.paybackYears > 0 && roi.paybackYears <= horizonYears) {
      markLineData.push({
        xAxis: roi.paybackYears,
        name: 'Payback',
        label: {
          formatter: `Payback\n${roi.paybackYears.toFixed(1)} años`,
          position: 'insideEndTop',
          fontSize: 10,
          color: '#16A34A',
          padding: [0, 0, 0, 8],
          offset: [4, 0],
        },
        lineStyle: { color: '#16A34A', type: 'dashed', width: 2 },
      })
    }

    // Línea de referencia en y=0 para identificar el break-even visualmente
    markLineData.push({
      yAxis: 0,
      name: 'Break-even',
      label: { formatter: '', position: 'insideStartTop' },
      lineStyle: { color: '#94a3b8', type: 'solid', width: 1 },
    })

    // Caso base (sliders de sensibilidad activos) — recupera la inversión original a partir
    // de cumulativeSavingsHorizon (= annualSavings × horizonYears − investment), sin necesidad
    // de una prop adicional: roiBase ya contiene toda la información necesaria.
    let baseValues: number[] | null = null
    if (roiBase) {
      const investmentBase = roiBase.annualSavings * horizonYears - roiBase.cumulativeSavingsHorizon
      baseValues = years.map((y) => roiBase.annualSavings * y - investmentBase)
    }

    // Fill-between: dos series stackeadas (lower invisible + diff coloreado) para sombrear
    // exactamente el área entre la línea base y la ajustada, sin importar cuál es mayor.
    const lowerValues = baseValues ? values.map((v, i) => Math.min(v, baseValues![i])) : null
    const diffValues = baseValues ? values.map((v, i) => Math.abs(v - baseValues![i])) : null

    const allValues = baseValues ? [...values, ...baseValues] : values
    const yMin = Math.min(...allValues, 0)
    const yMax = Math.max(...allValues, 0)
    // Margen del 10% para que las líneas no queden pegadas al borde del gráfico
    const yPad = Math.max((yMax - yMin) * 0.1, 1)

    const series: Record<string, unknown>[] = []

    if (lowerValues && diffValues) {
      series.push({
        name: 'fill-lower',
        type: 'line',
        data: years.map((y, i) => [y, lowerValues![i]]),
        stack: 'fill-band',
        symbol: 'none',
        lineStyle: { opacity: 0 },
        silent: true,
        tooltip: { show: false },
      })
      series.push({
        name: 'fill-diff',
        type: 'line',
        data: years.map((y, i) => [y, diffValues![i]]),
        stack: 'fill-band',
        symbol: 'none',
        lineStyle: { opacity: 0 },
        areaStyle: { color: '#F59845', opacity: 0.08 },
        silent: true,
        tooltip: { show: false },
      })
    }

    if (baseValues) {
      series.push({
        name: 'Base',
        type: 'line',
        data: years.map((y, i) => [y, baseValues![i]]),
        smooth: false,
        symbol: 'circle',
        symbolSize: 5,
        lineStyle: { color: '#94a3b8', width: 1.5, type: 'dashed' },
        itemStyle: { color: '#94a3b8' },
      })
    }

    series.push({
      name: 'Ajustado',
      type: 'line',
      data: years.map((y, i) => [y, values[i]]),
      smooth: false,
      lineStyle: { color: '#F59845', width: 2.5 },
      areaStyle: baseValues
        ? undefined
        : {
            color: {
              type: 'linear',
              x: 0, y: 0, x2: 0, y2: 1,
              colorStops: [
                { offset: 0, color: 'rgba(245,152,69,0.18)' },
                { offset: 1, color: 'rgba(245,152,69,0.02)' },
              ],
            },
          },
      itemStyle: { color: '#F59845' },
      symbolSize: 6,
      markLine: {
        silent: true,
        symbol: ['none', 'none'],
        data: markLineData,
      },
    })

    return {
      tooltip: {
        trigger: 'axis',
        formatter: (params: unknown[]) => {
          const typedParams = params as Array<{ seriesName: string; value: [number, number] }>
          const adjustedP = typedParams.find((p) => p.seriesName === 'Ajustado')
          const baseP = typedParams.find((p) => p.seriesName === 'Base')
          if (!adjustedP) return ''
          const year = adjustedP.value[0]
          const val = adjustedP.value[1]
          let html = `<div style="font-size:12px;line-height:1.6">
            <div style="font-weight:600;margin-bottom:4px">Año ${year}</div>
            <div>Acumulado ajustado: <strong style="color:${val >= 0 ? '#16A34A' : '#EF4444'}">${formatCurrency(val, currency)}</strong></div>`
          if (baseP) {
            const baseVal = baseP.value[1]
            html += `<div>Acumulado base: <strong style="color:${baseVal >= 0 ? '#16A34A' : '#EF4444'}">${formatCurrency(baseVal, currency)}</strong></div>`
          }
          html += '</div>'
          return html
        },
      },
      grid: { left: 16, right: 24, top: 16, bottom: 8, containLabel: true },
      xAxis: {
        type: 'value',
        name: 'Año',
        nameLocation: 'end',
        nameTextStyle: { fontSize: 10, color: '#94a3b8' },
        min: 0,
        max: horizonYears,
        interval: 1,
        axisLabel: { fontSize: 11, formatter: (v: number) => `Año ${v}` },
        splitLine: { lineStyle: { color: '#f1f5f9' } },
      },
      yAxis: {
        type: 'value',
        min: baseValues ? yMin - yPad : undefined,
        max: baseValues ? yMax + yPad : undefined,
        axisLabel: {
          fontSize: 11,
          formatter: (v: number) => {
            if (v === 0) return '0'
            const abs = Math.abs(v)
            const sign = v < 0 ? '-' : ''
            if (abs >= 1_000_000) return `${sign}${(abs / 1_000_000).toFixed(1)}M`
            if (abs >= 1_000) return `${sign}${(abs / 1_000).toFixed(0)}k`
            return String(v)
          },
        },
        splitLine: { lineStyle: { color: '#f1f5f9' } },
      },
      series,
    }
  }, [roi, horizonYears, currency, investment, roiBase])

  return <ReactECharts option={option} style={{ height: 280 }} notMerge />
}
