import { useCallback, useMemo, useState } from 'react';
import { useSearchParams } from 'react-router-dom';
import {Alert, Container, Group, Text} from '@mantine/core';
import { IconAlertTriangle, IconShip } from '@tabler/icons-react';
import { ApiErrorAlert, EmptyState, notify, PageHeader, PageLoader } from '@ema-platform/ui';
import { useDateDisplayer } from '@ema-platform/shared';
import {
  downloadAuthedFile,
  extractErrorMessage,
  useGetVesselReportQuery,
} from '@ema-platform/api';
import type { VesselReportQuery } from '@ema-platform/api';
import { KpiTiles } from './KpiTiles';
import { ReportCharts } from './ReportCharts';
import { ReportFilters } from './ReportFilters';
import { ReportTables } from './ReportTables';
import { queryToSearchParams, searchParamsToQuery } from './report-format';

/**
 * The vessel registration dashboard (module 11).
 *
 * One `GET /vessels/report` call fills the whole screen — KPIs, four time
 * series, fifteen breakdowns and four worklists — so the filter bar drives a
 * single refetch rather than a dozen independent ones.
 *
 * Filter state lives in the URL. A filtered dashboard is the thing an officer
 * wants to send someone, and rebuilding six selects from a description is not
 * how that conversation should go.
 */
export function VesselRegistrationReportPage() {
  const [searchParams, setSearchParams] = useSearchParams();
  const [exporting, setExporting] = useState(false);
  const showDate = useDateDisplayer();

  const query: VesselReportQuery = useMemo(
    () => searchParamsToQuery(searchParams),
    [searchParams],
  );

  const setQuery = useCallback(
    (next: VesselReportQuery) => {
      // `replace` so a session of narrowing filters does not bury the page the
      // officer arrived from under twenty history entries.
      setSearchParams(queryToSearchParams(next), { replace: true });
    },
    [setSearchParams],
  );

  const { data: report, isLoading, isFetching, error } = useGetVesselReportQuery(
    query,
  );

  const exportCsv = useCallback(async () => {
    setExporting(true);
    try {
      const params = queryToSearchParams(query).toString();
      const { rowCount, truncated } = await downloadAuthedFile(
        `/vessels/report/export${params ? `?${params}` : ''}`,
        'vessel-register.csv',
      );
      if (truncated) {
        notify.error(
          `Export cut off at ${rowCount ?? 'the row limit'} rows. Narrow the filter and export again.`,
        );
      } else {
        notify.success(
          `Exported ${rowCount ?? 'the filtered'} vessel${rowCount === 1 ? '' : 's'}.`,
        );
      }
    } catch (err) {
      notify.error(extractErrorMessage(err, 'Could not export the register'));
    } finally {
      setExporting(false);
    }
  }, [query]);

  // Only the very first load blanks the page; a filter change keeps the last
  // report on screen so the dashboard does not flash between every tweak.
  if (isLoading) return <PageLoader />;

  return (
    <Container size="xl" py="md">
      <PageHeader
        title="Vessel registration report"
        subtitle={
          report
            ? `Register-wide totals with a ${showDate(report.filters.from)} – ${showDate(report.filters.to)} window on the trends.`
            : 'The national vessel register at a glance.'
        }
      />

      <ReportFilters
        query={query}
        onChange={setQuery}
        report={report}
        onExport={exportCsv}
        exporting={exporting}
      />

      {error && <ApiErrorAlert error={error} title="Could not load the report" />}

      {report && (
        <>
          {report.truncated && (
            <Alert
              color="yellow"
              icon={<IconAlertTriangle size={16} />}
              mb="md"
              title="Partial figures"
            >
              The register is larger than this report can scan in one pass, so
              every figure below covers only part of it. Narrow the filter for
              an exact answer.
            </Alert>
          )}

          {report.kpis.register.total === 0 ? (
            <EmptyState
              icon={IconShip}
              title="No vessels match this filter"
              description={
                Object.keys(query).length > 0
                  ? 'Nothing on the register matches the current filter. Clear it to see the whole book.'
                  : 'No vessels have been registered yet. Entries appear here once a registration certificate is issued.'
              }
            />
          ) : (
            <div style={{ opacity: isFetching ? 0.6 : 1, transition: 'opacity 120ms' }}>
              <KpiTiles report={report} />
              <div style={{ marginTop: 'var(--mantine-spacing-md)' }}>
                <ReportCharts report={report} />
              </div>
              <ReportTables report={report} />
            </div>
          )}
        </>
      )}
    </Container>
  );
}

export default VesselRegistrationReportPage;
