import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
import { useQuery } from '@tanstack/react-query';
import Alert from 'react-bootstrap/Alert';
import Col from 'react-bootstrap/Col';
import Row from 'react-bootstrap/Row';
import Spinner from 'react-bootstrap/Spinner';

import { fetchCv, filesForSection } from '../api/cv';
import { CvHeader } from '../components/cv/CvHeader';
import { CvSection } from '../components/cv/CvSection';
import { CvTimeline } from '../components/cv/CvTimeline';
import './CvPage.css';

export function CvPage() {
  const { hash } = useLocation();
  const cvQ = useQuery({
    queryKey: ['cv-gist'],
    queryFn: fetchCv,
    staleTime: 5 * 60_000,
  });

  // Scroll to the anchored entry once the gist resolves and the section
  // body has rendered its ids. Re-runs if the user changes the hash while
  // already on the page.
  useEffect(() => {
    if (!cvQ.data || !hash) return;
    const target = document.getElementById(hash.slice(1));
    if (target) {
      target.scrollIntoView({ behavior: 'smooth', block: 'start' });
    }
  }, [cvQ.data, hash]);

  if (cvQ.isLoading) {
    return (
      <>
        <CvHeader />
        <div className="d-flex align-items-center gap-2">
          <Spinner animation="border" role="status" size="sm" />
          <span>loading cv…</span>
        </div>
      </>
    );
  }

  if (cvQ.isError) {
    const msg = (cvQ.error as Error).message;
    const rateHint = /403|rate limit/i.test(msg)
      ? ' (github limits unauthenticated requests to 60/hour per ip — try again shortly)'
      : '';
    return (
      <>
        <CvHeader />
        <Alert variant="danger">
          <Alert.Heading>cv unavailable</Alert.Heading>
          <p className="mb-2">
            {msg}
            {rateHint}
          </p>
          <button className="btn btn-outline-light" onClick={() => cvQ.refetch()}>
            retry
          </button>
        </Alert>
      </>
    );
  }

  const data = cvQ.data!;
  const bodySections = data.config.sections.filter((s) => s.placement === 'body');
  const navSections = data.config.sections.filter((s) => s.placement === 'nav');

  if (bodySections.length === 0 && navSections.length === 0) {
    return (
      <>
        <CvHeader />
        <Alert variant="warning">cv unavailable: no sections in config</Alert>
      </>
    );
  }

  return (
    <>
      <CvHeader />
      <Row>
        <Col lg={9} className="cv-body">
          {bodySections.map((section) => (
            <CvSection
              key={section.name}
              section={section}
              files={filesForSection(data, section)}
            />
          ))}
        </Col>
        <Col lg={3} className="cv-sidebar">
          {navSections.map((section) => (
            <CvSection
              key={section.name}
              section={section}
              files={filesForSection(data, section)}
            />
          ))}
          <CvTimeline data={data} />
        </Col>
      </Row>
    </>
  );
}
