import React, { useEffect, useState, useContext } from 'react';
import { Typography, Spin, Message, Card, Grid } from '@arco-design/web-react';
import '@arco-design/web-react/dist/css/arco.css';
import { initVChartArcoTheme } from '@visactor/vchart-arco-theme';
import { VChart } from '@visactor/react-vchart';
import API_BASE_URL from './config';
import { MarketContext, MARKET_FULL_NAMES } from './App';

// TODO:
//
// - [ ] Cancel Promise if market changes
// - [ ] Fix Data Zoom being reset

const { Row, Col } = Grid;

function TimeAgo({ timestamp, prefix }) {
  const [now, setNow] = useState(new Date());

  useEffect(() => {
    const timer = setInterval(() => setNow(new Date()), 1000);
    return () => clearInterval(timer);
  }, []);

  const formatTimeAgo = () => {
    if (!timestamp) return '';
    const seconds = Math.floor((now - timestamp) / 1000);
    if (seconds < 60) return `${seconds} sec ago`;
    const minutes = Math.floor(seconds / 60);
    if (minutes < 60) return `${minutes} min ago`;
    const hours = Math.floor(minutes / 60);
    return `${hours} hr ago`;
  };

  return (
    <Typography.Text type="secondary" style={{ fontSize: 12, display: 'block', marginTop: 8 }}>
      {prefix}: {formatTimeAgo()}
    </Typography.Text>
  );
}

function MarketDataPage() {
  const { selectedMarket } = useContext(MarketContext);
  const [fiveMinZoom, setFiveMinZoom] = useState({ start: 0.9, end: 1 });
  const [dayAheadZoom, setDayAheadZoom] = useState({ start: 0.05, end: 1 });
  const [fiveMinData, setFiveMinData] = useState([]);
  const [dayAheadData, setDayAheadData] = useState([]);
  const [loading, setLoading] = useState(true);
  const [fiveMinLastUpdated, setFiveMinLastUpdated] = useState(null);
  const [dayAheadLastUpdated, setDayAheadLastUpdated] = useState(null);
  const [now, setNow] = useState(new Date());

  useEffect(() => {
    const fetchFiveMinData = async () => {
      try {
        const res = await fetch(`${API_BASE_URL}/market/real-time?market=${selectedMarket}`);
        if (!res.ok) throw new Error('Failed to fetch real-time data');
        const json = await res.json();
        setFiveMinData(json);
        setFiveMinLastUpdated(new Date());
      } catch (err) {
        console.error(err);
        Message.error('Failed to load real-time market data.');
      }
    };

    const fetchDayAheadData = async () => {
      try {
        const res = await fetch(`${API_BASE_URL}/market/day-ahead?market=${selectedMarket}`);
        if (!res.ok) throw new Error('Failed to fetch day-ahead data');
        const json = await res.json();
        setDayAheadData(json);
        setDayAheadLastUpdated(new Date());
      } catch (err) {
        console.error(err);
        Message.error('Failed to load day-ahead market data.');
      }
    };

    const initialize = async () => {
      setLoading(true);
      await Promise.all([fetchFiveMinData(), fetchDayAheadData()]);
      setLoading(false);

      initVChartArcoTheme({
        defaultMode: 'light',
        isWatchingMode: true
      });
    };

    initialize();

    const fiveMinInterval = setInterval(fetchFiveMinData, 5 * 60 * 1000);
    const dayAheadInterval = setInterval(fetchDayAheadData, 60 * 60 * 1000);
    const timer = setInterval(() => setNow(new Date()), 1000);

    return () => {
      clearInterval(fiveMinInterval);
      clearInterval(dayAheadInterval);
      clearInterval(timer);
    };
  }, [selectedMarket]);

  const getChartSpec = (data, title, zoom) => ({
    type: 'line',
    data: {
      values: data.map(d => ({
        timestamp: new Date(d.timestamp).toLocaleString(),
        LMP: d.lmp,
        Energy: d.energy,
        Congestion: d.congestion,
        Loss: d.loss
      })),
      transforms: [{
        type: 'fold',
        options: { key: 'name', value: 'value', fields: ['LMP', 'Energy', 'Congestion', 'Loss'] }
      }]
    },
    xField: 'timestamp',
    yField: 'value',
    seriesField: 'name',
    smooth: true,
    legend: { position: 'top' },
    tooltip: {
      formatter: (datum) => ({
        name: datum.name,
        value: datum.value.toFixed(2)
      })
    },
    dataZoom: [{
      orient: 'bottom',
      height: 20,
      start: zoom?.start ?? (title === 'fiveMin' ? 0.9 : 0.05),
      end: zoom?.end ?? 1,
      onChange: (e) => {
        if (title === 'fiveMin') {
          setFiveMinZoom({ start: e.start, end: e.end });
        } else {
          setDayAheadZoom({ start: e.start, end: e.end });
        }
      }
    }]
  });

  const computeKPIs = (data) => {
    if (!data.length) return { avgLmp: 0, totalEnergy: 0, maxCongestion: 0, avgLoss: 0 };
    const avgLmp = data.reduce((sum, d) => sum + d.lmp, 0) / data.length;
    const totalEnergy = data.reduce((sum, d) => sum + d.energy, 0);
    const maxCongestion = Math.max(...data.map(d => d.congestion));
    const avgLoss = data.reduce((sum, d) => sum + d.loss, 0) / data.length;
    return { avgLmp, totalEnergy, maxCongestion, avgLoss };
  };

  const fiveMinKPIs = computeKPIs(fiveMinData);
  const dayAheadKPIs = computeKPIs(dayAheadData);

  return (
    <div style={{ padding: 20, background: 'var(--color-fill-2)', animation: 'fadeIn 0.5s ease' }}>
      <Typography.Title heading={3} style={{ textAlign: 'center', marginBottom: 20 }}>
        Market Data for {MARKET_FULL_NAMES[selectedMarket]}
      </Typography.Title>

      {loading ? (
        <Spin style={{ display: 'block', margin: '80px auto' }} />
      ) : (
        <>
          <div style={{ textAlign: 'center', marginBottom: 24 }}>
            <TimeAgo timestamp={fiveMinLastUpdated} prefix="Real-Time Last Updated" />
            <TimeAgo timestamp={dayAheadLastUpdated} prefix="Day-Ahead Last Updated" />
          </div>

          <Row gutter={24} style={{ marginBottom: 30 }}>
            {[
              { label: 'Avg Real-Time LMP ($/MWh)', value: fiveMinKPIs.avgLmp },
              { label: 'Total Real-Time Energy (MWh)', value: fiveMinKPIs.totalEnergy },
              { label: 'Max Real-Time Congestion ($)', value: fiveMinKPIs.maxCongestion },
              { label: 'Avg Real-Time Loss ($)', value: fiveMinKPIs.avgLoss }
            ].map((item, idx) => (
              <Col xs={12} md={6} key={idx} style={{ marginBottom: 16 }}>
                <Card
                  hoverable
                  style={{
                    textAlign: 'center',
                    borderRadius: 12,
                    boxShadow: '0 4px 12px rgba(0,0,0,0.05)'
                  }}
                  title={item.label}
                >
                  <Typography.Title heading={5}>${item.value.toFixed(2)}</Typography.Title>
                </Card>
              </Col>
            ))}
          </Row>

          <Row gutter={24} style={{ marginBottom: 30 }}>
            {[
              { label: 'Avg Day-Ahead LMP ($/MWh)', value: dayAheadKPIs.avgLmp },
              { label: 'Total Day-Ahead Energy (MWh)', value: dayAheadKPIs.totalEnergy },
              { label: 'Max Day-Ahead Congestion ($)', value: dayAheadKPIs.maxCongestion },
              { label: 'Avg Day-Ahead Loss ($)', value: dayAheadKPIs.avgLoss }
            ].map((item, idx) => (
              <Col xs={12} md={6} key={idx} style={{ marginBottom: 16 }}>
                <Card
                  hoverable
                  style={{
                    textAlign: 'center',
                    borderRadius: 12,
                    boxShadow: '0 4px 12px rgba(0,0,0,0.05)'
                  }}
                  title={item.label}
                >
                  <Typography.Title heading={5}>${item.value.toFixed(2)}</Typography.Title>
                </Card>
              </Col>
            ))}
          </Row>

          <Row gutter={24}>
            <Col xs={24} md={12}>
              <Card title="Real-Time Market Data" style={{ borderRadius: 12, marginBottom: 24 }}>
                <div style={{ padding: 10 }}>
                  <VChart spec={getChartSpec(fiveMinData, 'fiveMin', fiveMinZoom)} />
                </div>
              </Card>
            </Col>
            <Col xs={24} md={12}>
              <Card title="Day-Ahead Market Data" style={{ borderRadius: 12, marginBottom: 24 }}>
                <div style={{ padding: 10 }}>
                  <VChart spec={getChartSpec(dayAheadData, 'dayAhead', dayAheadZoom)} />
                </div>
              </Card>
            </Col>
          </Row>
        </>
      )}

      <style>{`
        @keyframes fadeIn {
          from { opacity: 0; transform: translateY(10px); }
          to { opacity: 1; transform: translateY(0); }
        }
      `}</style>
    </div>
  );
}

export default MarketDataPage;
