import React, { useMemo, useState } from 'react';
import { useParams } from 'react-router-dom';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { ProjectPageShell } from '@/features/projects/components/ProjectPageShell';
import { ReportPageLayout } from '@/features/projects/components/ReportPageLayout';
import { useProjectSprints } from '@/features/projects/hooks/useProjectSprints';
import {
  getReportByKey,
  type ReportDefinition,
} from '@/features/projects/reports/reportCatalog';
import { api } from '@/shared/utils/api';
import type { ChartData } from '@/features/projects/components/ReportChart';

interface ReportPayload {
  meta?: Record<string, unknown>;
  summary?: Record<string, unknown>;
  chart?: ChartData;
  table?: {
    headers: string[];
    rows: Array<Record<string, unknown>>;
  };
  error?: string;
}

async function fetchReport(
  projectId: string,
  definition: ReportDefinition,
  sprintId?: string,
): Promise<ReportPayload> {
  const params = sprintId ? `?sprint_id=${sprintId}` : '';
  const response = await api.get<{ data: ReportPayload }>(
    `/projects/${projectId}/reports/${definition.apiPath}${params}`,
  );
  return (response as { data: ReportPayload }).data;
}

const ProjectEnterpriseReportPage: React.FC = () => {
  const { id, reportKey } = useParams<{ id: string; reportKey: string }>();
  const queryClient = useQueryClient();
  const [selectedSprint, setSelectedSprint] = useState('');
  const definition = reportKey ? getReportByKey(reportKey) : undefined;

  const { data: sprints } = useProjectSprints(id);

  const { data, isLoading } = useQuery({
    queryKey: ['projects', id, 'reports', reportKey, selectedSprint],
    queryFn: () => fetchReport(id!, definition!, selectedSprint || undefined),
    enabled: Boolean(id && definition),
  });

  const sprintOptions = useMemo(
    () => [
      { value: '', label: 'Active Sprint' },
      ...(sprints ?? []).map((s) => ({ value: s.id, label: s.name })),
    ],
    [sprints],
  );

  if (!id || !definition) return null;

  const hasChart = Boolean(data?.chart?.labels?.length);
  const isEmpty = !data || Boolean(data.error) || (!hasChart && !data.table?.rows?.length);

  const handleExportCsv = definition.exportType
    ? () => window.open(`/api/v1/projects/${id}/reports/export/${definition.exportType}`, '_blank')
    : undefined;

  const handleExportExcel = handleExportCsv;

  return (
    <ProjectPageShell projectId={id}>
      {() => (
        <ReportPageLayout
          title={definition.title}
          subtitle={definition.subtitle}
          isLoading={isLoading}
          isEmpty={isEmpty}
          emptyMessage={data?.error ?? definition.emptyMessage}
          filters={
            definition.supportsSprintFilter
              ? [
                  {
                    id: 'sprint',
                    label: 'Sprint',
                    value: selectedSprint,
                    options: sprintOptions,
                    onChange: setSelectedSprint,
                  },
                ]
              : undefined
          }
          summaryMetrics={
            data?.summary && definition.buildSummary
              ? definition.buildSummary(data.summary)
              : undefined
          }
          chartType={hasChart ? definition.chartType : undefined}
          chartData={hasChart ? data?.chart : undefined}
          chartHeight={350}
          tableData={data?.table}
          onRefresh={() =>
            queryClient.invalidateQueries({
              queryKey: ['projects', id, 'reports', reportKey, selectedSprint],
            })
          }
          onExportCsv={handleExportCsv}
          onExportExcel={handleExportExcel}
        />
      )}
    </ProjectPageShell>
  );
};

export default ProjectEnterpriseReportPage;
