import { useState, useEffect, useCallback } from 'react';
import type {
  Account,
  AnalyticsSummaryResponse,
  ByCategoryItem,
  TimeseriesItem,
  Granularity,
} from '@family-budget/shared';
import { getAccounts } from '../api/accounts';
import { getSummary, getByCategory, getTimeseries } from '../api/analytics';
import {
  PeriodSelector,
  type PeriodState,
} from '../components/PeriodSelector';
import { SummaryCards } from '../components/SummaryCards';
import { TimeseriesChart } from '../components/TimeseriesChart';
import { CategoryChart } from '../components/CategoryChart';
import { toISODate } from '../utils/format';

function getDefaultPeriod(): PeriodState {
  const now = new Date();
  return {
    mode: 'month',
    from: toISODate(new Date(now.getFullYear(), now.getMonth(), 1)),
    to: toISODate(now),
  };
}

export function AnalyticsPage() {
  const [period, setPeriod] = useState<PeriodState>(getDefaultPeriod);
  const [accountId, setAccountId] = useState<string>('');
  const [onlyConfirmed, setOnlyConfirmed] = useState(false);
  const [accounts, setAccounts] = useState<Account[]>([]);
  const [summary, setSummary] = useState<AnalyticsSummaryResponse | null>(
    null,
  );
  const [byCategory, setByCategory] = useState<ByCategoryItem[]>([]);
  const [timeseries, setTimeseries] = useState<TimeseriesItem[]>([]);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    getAccounts().then(setAccounts).catch(() => {});
  }, []);

  const fetchAll = useCallback(async () => {
    if (!period.from || !period.to) return;
    setLoading(true);

    let gran: Granularity;
    switch (period.mode) {
      case 'week':
        gran = 'day';
        break;
      case 'month':
        gran = 'week';
        break;
      default:
        gran = 'month';
        break;
    }

    const base = {
      from: period.from,
      to: period.to,
      ...(accountId ? { accountId: Number(accountId) } : {}),
      ...(onlyConfirmed ? { onlyConfirmed: true } : {}),
    };

    try {
      const [s, bc, ts] = await Promise.all([
        getSummary(base),
        getByCategory(base),
        getTimeseries({ ...base, granularity: gran }),
      ]);
      setSummary(s);
      setByCategory(bc);
      setTimeseries(ts);
    } catch {
      // 401 handled by interceptor
    } finally {
      setLoading(false);
    }
  }, [period, accountId, onlyConfirmed]);

  useEffect(() => {
    fetchAll();
  }, [fetchAll]);

  return (
    <div className="page">
      <div className="page-header">
        <h1>Аналитика</h1>
      </div>

      <div className="analytics-controls">
        <PeriodSelector period={period} onChange={setPeriod} />
        <div className="analytics-filters">
          <div className="filter-group">
            <label>Счёт</label>
            <select
              value={accountId}
              onChange={(e) => setAccountId(e.target.value)}
            >
              <option value="">Все счета</option>
              {accounts.map((a) => (
                <option key={a.id} value={a.id}>
                  {a.alias || a.accountNumberMasked}
                </option>
              ))}
            </select>
          </div>
          <div className="filter-group filter-group-checkbox">
            <label>
              <input
                type="checkbox"
                checked={onlyConfirmed}
                onChange={(e) => setOnlyConfirmed(e.target.checked)}
              />
              Только подтверждённые
            </label>
          </div>
        </div>
      </div>

      {loading ? (
        <div className="section-loading">Загрузка данных...</div>
      ) : (
        <>
          {summary && <SummaryCards summary={summary} />}
          <div className="analytics-charts">
            <div className="chart-card">
              <h3>Динамика</h3>
              <TimeseriesChart data={timeseries} />
            </div>
            <div className="chart-card">
              <h3>По категориям</h3>
              <CategoryChart data={byCategory} />
            </div>
          </div>
        </>
      )}
    </div>
  );
}
