'use client';

import { useState } from 'react';
import Link from 'next/link';
import type { Route } from 'next';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { ArrowLeft, Calendar, Pencil, Play, Plus, Trash2 } from 'lucide-react';
import { toast } from 'sonner';

import { PageHeader } from '@/components/shared/page-header';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { Card, CardContent } from '@/components/ui/card';
import { Skeleton } from '@/components/ui/skeleton';
import { Switch } from '@/components/ui/switch';
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table';
import { EmptyState } from '@/components/shared/empty-state';
import { apiFetch } from '@/lib/api/client';
import { toastError } from '@/lib/api/toast-error';
import { ScheduleDialog } from '@/components/reports/schedule-dialog';
import type { ReportSchedule, ReportTemplate } from '@/lib/db/schema/reports';

interface SchedulesResponse {
  data: ReportSchedule[];
}
interface TemplatesResponse {
  data: ReportTemplate[];
}

const CADENCE_LABELS: Record<string, string> = {
  weekly_monday_9: 'Weekly · Monday 9am',
  monthly_first_9: 'Monthly · 1st @ 9am',
  quarterly_first_9: 'Quarterly · 1st @ 9am',
};

export function ReportSchedulesPageClient({ portSlug }: { portSlug: string }) {
  const qc = useQueryClient();
  const [dialogOpen, setDialogOpen] = useState(false);
  const [editing, setEditing] = useState<ReportSchedule | undefined>(undefined);

  const schedulesQuery = useQuery<SchedulesResponse>({
    queryKey: ['report-schedules'],
    queryFn: () => apiFetch<SchedulesResponse>('/api/v1/reports/schedules?pageSize=50'),
  });

  // Pull all templates so we can resolve template_id → name in the
  // table without N round-trips. One extra query, cheap, port-scoped.
  const templatesQuery = useQuery<TemplatesResponse>({
    queryKey: ['report-templates', 'all'],
    queryFn: () => apiFetch<TemplatesResponse>('/api/v1/reports/templates'),
    staleTime: 30_000,
  });

  const toggleMutation = useMutation({
    mutationFn: async ({ id, enabled }: { id: string; enabled: boolean }) => {
      return apiFetch(`/api/v1/reports/schedules/${id}`, {
        method: 'PATCH',
        body: { enabled },
      });
    },
    onSuccess: () => {
      toast.success('Schedule updated');
      void qc.invalidateQueries({ queryKey: ['report-schedules'] });
    },
    onError: (err) => toastError(err),
  });

  const deleteMutation = useMutation({
    mutationFn: async (id: string) => {
      return apiFetch(`/api/v1/reports/schedules/${id}`, { method: 'DELETE' });
    },
    onSuccess: () => {
      toast.success('Schedule deleted');
      void qc.invalidateQueries({ queryKey: ['report-schedules'] });
    },
    onError: (err) => toastError(err),
  });

  const runNowMutation = useMutation({
    mutationFn: async (schedule: ReportSchedule) => {
      const tmpl = templatesQuery.data?.data.find((t) => t.id === schedule.templateId);
      if (!tmpl) throw new Error('Template no longer exists; cannot run.');
      return apiFetch(`/api/v1/reports/runs`, {
        method: 'POST',
        body: {
          kind: tmpl.kind,
          templateId: tmpl.id,
          // Re-stamp the discriminator onto config — the run-create
          // route's same cross-check requires config.kind === kind.
          config: { ...(tmpl.config as Record<string, unknown>), kind: tmpl.kind },
          outputFormat: schedule.outputFormat,
        },
      });
    },
    onSuccess: () => {
      toast.success('Run queued — check Runs tab in a few seconds');
      void qc.invalidateQueries({ queryKey: ['report-runs'] });
    },
    onError: (err) => toastError(err),
  });

  const templateById = new Map(templatesQuery.data?.data?.map((t) => [t.id, t]) ?? []);
  const rows = schedulesQuery.data?.data ?? [];

  return (
    <div className="space-y-4">
      <PageHeader
        eyebrow="Reports"
        title="Schedules"
        description="Recurring reports that auto-run and (optionally) email a recipient list."
        actions={
          <div className="flex items-center gap-2">
            <Button asChild variant="outline" size="sm">
              <Link href={`/${portSlug}/reports` as Route}>
                <ArrowLeft className="mr-1.5 h-4 w-4" aria-hidden />
                All reports
              </Link>
            </Button>
            <Button
              size="sm"
              onClick={() => {
                setEditing(undefined);
                setDialogOpen(true);
              }}
            >
              <Plus className="mr-1.5 h-4 w-4" aria-hidden />
              New schedule
            </Button>
          </div>
        }
      />

      {schedulesQuery.isLoading ? (
        <Skeleton className="h-[200px] w-full" aria-hidden />
      ) : rows.length === 0 ? (
        <EmptyState
          icon={Calendar}
          title="No schedules yet"
          description="Create a schedule against a saved template. Recipients are optional — runs are archived even without an email blast."
        />
      ) : (
        <Card>
          <CardContent className="p-0">
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>Template</TableHead>
                  <TableHead>Cadence</TableHead>
                  <TableHead>Recipients</TableHead>
                  <TableHead>Last run</TableHead>
                  <TableHead>Next run</TableHead>
                  <TableHead>Output</TableHead>
                  <TableHead className="w-20 text-right">Enabled</TableHead>
                  <TableHead className="w-32 text-right">Actions</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {rows.map((s) => {
                  const tmpl = templateById.get(s.templateId);
                  const recipientCount = Array.isArray(s.recipients) ? s.recipients.length : 0;
                  return (
                    <TableRow key={s.id}>
                      <TableCell className="font-medium">
                        {tmpl ? (
                          <>
                            {tmpl.name}
                            <span className="ml-1.5 text-xs text-muted-foreground capitalize">
                              · {tmpl.kind}
                            </span>
                          </>
                        ) : (
                          <span className="text-muted-foreground italic">template missing</span>
                        )}
                      </TableCell>
                      <TableCell>{CADENCE_LABELS[s.cadence] ?? s.cadence}</TableCell>
                      <TableCell>
                        {recipientCount === 0 ? (
                          <Badge variant="outline" className="text-muted-foreground">
                            archive only
                          </Badge>
                        ) : (
                          <Badge variant="outline">{recipientCount}</Badge>
                        )}
                      </TableCell>
                      <TableCell className="text-xs text-muted-foreground">
                        {s.lastRunAt ? new Date(s.lastRunAt).toLocaleString() : '—'}
                      </TableCell>
                      <TableCell className="text-xs text-muted-foreground">
                        {new Date(s.nextRunAt).toLocaleString()}
                      </TableCell>
                      <TableCell className="text-xs uppercase tracking-wide text-muted-foreground">
                        {s.outputFormat}
                      </TableCell>
                      <TableCell className="text-right">
                        <Switch
                          checked={s.enabled}
                          onCheckedChange={(enabled) =>
                            toggleMutation.mutate({ id: s.id, enabled })
                          }
                          disabled={toggleMutation.isPending}
                        />
                      </TableCell>
                      <TableCell className="text-right">
                        <div className="flex items-center justify-end gap-0.5">
                          <Button
                            variant="ghost"
                            size="icon"
                            className="h-7 w-7"
                            onClick={() => runNowMutation.mutate(s)}
                            disabled={runNowMutation.isPending || !tmpl}
                            aria-label="Run now"
                            title="Run this schedule now (one-off)"
                          >
                            <Play className="h-3.5 w-3.5" aria-hidden />
                          </Button>
                          <Button
                            variant="ghost"
                            size="icon"
                            className="h-7 w-7"
                            onClick={() => {
                              setEditing(s);
                              setDialogOpen(true);
                            }}
                            aria-label="Edit schedule"
                            title="Edit schedule"
                          >
                            <Pencil className="h-3.5 w-3.5" aria-hidden />
                          </Button>
                          <Button
                            variant="ghost"
                            size="icon"
                            className="h-7 w-7"
                            onClick={() => {
                              if (
                                confirm(
                                  `Delete schedule? This stops the recurring run; existing runs in the history stay.`,
                                )
                              ) {
                                deleteMutation.mutate(s.id);
                              }
                            }}
                            disabled={deleteMutation.isPending}
                            aria-label="Delete schedule"
                            title="Delete schedule"
                          >
                            <Trash2 className="h-3.5 w-3.5 text-destructive" aria-hidden />
                          </Button>
                        </div>
                      </TableCell>
                    </TableRow>
                  );
                })}
              </TableBody>
            </Table>
          </CardContent>
        </Card>
      )}

      <ScheduleDialog open={dialogOpen} onOpenChange={setDialogOpen} schedule={editing} />
    </div>
  );
}
