import { useMemo, useState } from 'react';
import { useParams } from 'react-router-dom';
import { useQuery } from '@tanstack/react-query';
import Col from 'react-bootstrap/Col';
import Row from 'react-bootstrap/Row';
import { VerticalTimeline } from 'react-vertical-timeline-component';

import { fetchEvents, fetchSources, type Source } from '../api/client';
import { Filters } from '../components/Filters';
import { TimelineEntry } from '../components/TimelineEntry';

const RANGE_MIN = new Date('2010-01-01T00:00:00Z').getTime();
const RANGE_MAX = Date.now();

function parseDate(s: string): number {
  // Accept YYYY-MM-DD or full ISO datetime
  const t = new Date(s.includes('T') ? s : s + 'T00:00:00Z').getTime();
  return isNaN(t) ? NaN : t;
}

function endOfDay(s: string): number {
  const t = new Date(s.includes('T') ? s : s + 'T23:59:59Z').getTime();
  return isNaN(t) ? NaN : t;
}

function parseTimespan(timespan?: string): [number, number] | null {
  if (!timespan) return null;
  if (timespan.includes('..')) {
    const [a, b] = timespan.split('..');
    const from = parseDate(a);
    const to = endOfDay(b);
    if (!isNaN(from) && !isNaN(to)) return [from, to];
  } else {
    const from = parseDate(timespan);
    const to = endOfDay(timespan);
    if (!isNaN(from)) return [from, to];
  }
  return null;
}

export function TimelineHome() {
  const { timespan } = useParams();

  const [enabledSources, setEnabledSources] = useState<Record<Source, boolean>>({
    github: true,
    gitea: true,
    hg: true,
    bugzilla: true,
  });
  const [rangeValue, setRangeValue] = useState<[number, number]>(() => {
    const parsed = parseTimespan(timespan);
    if (parsed) return parsed;
    const now = Date.now();
    const thirtyDaysAgo = now - 30 * 24 * 60 * 60 * 1000;
    return [thirtyDaysAgo, now];
  });
  const [limit, setLimit] = useState<number>(100);

  const sourcesQ = useQuery({
    queryKey: ['sources'],
    queryFn: fetchSources,
    refetchInterval: 60_000,
  });

  const activeSources = useMemo(
    () =>
      (Object.keys(enabledSources) as Source[]).filter((s) => enabledSources[s]),
    [enabledSources],
  );

  const eventsQ = useQuery({
    queryKey: ['events', rangeValue, activeSources, limit],
    queryFn: () =>
      fetchEvents({
        from: new Date(rangeValue[0]),
        to: new Date(rangeValue[1]),
        sources: activeSources,
        limit,
      }),
    refetchInterval: 60_000,
  });

  const events = eventsQ.data ?? [];

  return (
    <>
      <Filters
        enabledSources={enabledSources}
        onSourceToggle={(s, on) =>
          setEnabledSources((prev) => ({ ...prev, [s]: on }))
        }
        rangeMin={RANGE_MIN}
        rangeMax={RANGE_MAX}
        rangeValue={rangeValue}
        onRangeChange={setRangeValue}
        limit={limit}
        onLimitChange={setLimit}
        summaries={sourcesQ.data}
      />

      <Row>
        <Col>
          <p className="text-center" style={{ fontSize: '85%' }}>
            {eventsQ.isLoading
              ? 'loading…'
              : eventsQ.isError
                ? `error: ${(eventsQ.error as Error).message}`
                : `showing ${events.length} ${events.length === 1 ? 'activity' : 'activities'}`}
          </p>
          <VerticalTimeline>
            {events.map((item) => (
              <TimelineEntry key={item.id} item={item} />
            ))}
          </VerticalTimeline>
        </Col>
      </Row>
    </>
  );
}
