import { router } from '@inertiajs/react';
import { useQuery } from '@tanstack/react-query';
import { Card, CardContent } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import {
  AlertTriangle, Building2, CalendarClock, Tag, ArrowRight, Award, RefreshCw, GraduationCap,
} from 'lucide-react';

type DraftCompany = { id: string; name: string };
type UnassignedBooking = { id: string; start_date: string; course?: { title: string } | null };
type ExpiringDiscount = { id: string; code: string; valid_until: string };
type ExpiringCert = { id: string; delegate_email: string; expires_at: string; course_id: string; courses?: { title: string } | null };
type ExpiredCert = { id: string };
type PendingReschedule = { id: string; requested_date: string; order_id: string; course_orders?: { customer_name?: string; courses?: { title: string } | null } | null };
type PendingCourse = { id: string; title: string; owner_company_name: string | null; kind: 'new' | 'changes' };

const apiGet = async <T,>(path: string): Promise<T[]> => {
  try {
    const res = await fetch(path);
    if (!res.ok) return [];
    return res.json();
  } catch {
    return [];
  }
};

const DashboardNotifications = () => {
  const { data: draftCompanies } = useQuery({
    queryKey: ['notif-draft-companies'],
    queryFn: () => apiGet<DraftCompany>('/api/admin/notifications/draft-companies'),
  });

  const { data: upcomingUnassigned } = useQuery({
    queryKey: ['notif-unassigned-bookings'],
    queryFn: () => apiGet<UnassignedBooking>('/api/admin/notifications/unassigned-bookings'),
  });

  const { data: expiringDiscounts } = useQuery({
    queryKey: ['notif-expiring-discounts'],
    queryFn: () => apiGet<ExpiringDiscount>('/api/admin/notifications/expiring-discounts'),
  });

  const { data: expiringCerts } = useQuery({
    queryKey: ['notif-expiring-certs'],
    queryFn: () => apiGet<ExpiringCert>('/api/admin/notifications/expiring-certs'),
  });

  const { data: expiredCerts } = useQuery({
    queryKey: ['notif-expired-certs'],
    queryFn: () => apiGet<ExpiredCert>('/api/admin/notifications/expired-certs'),
  });

  const { data: pendingReschedules } = useQuery({
    queryKey: ['notif-pending-reschedules'],
    queryFn: () => apiGet<PendingReschedule>('/api/admin/notifications/pending-reschedules'),
  });

  const { data: pendingCourses } = useQuery({
    queryKey: ['notif-pending-courses'],
    queryFn: () => apiGet<PendingCourse>('/api/admin/notifications/pending-courses'),
  });

  const notifications: Array<{
    icon: React.ElementType;
    color: string;
    bg: string;
    titleClass: string;
    descClass: string;
    actionClass: string;
    title: string;
    description: string;
    action: () => void;
    actionLabel: string;
  }> = [];

  // Per-tone class bundles. The `bg-X-50` cards stay light in both themes
  // (the `dark:bg-X-950/20` variant doesn't fire because we toggle via `.admin-light`,
  // not Tailwind's `.dark`). Pin readable text colours so titles aren't white-on-cream.
  const tones = {
    amber:  { bg: 'bg-amber-50 border-amber-200',  icon: 'text-amber-600',  title: 'text-amber-950', desc: 'text-amber-800/80', action: 'text-amber-900 hover:bg-amber-100' },
    red:    { bg: 'bg-red-50 border-red-200',      icon: 'text-red-600',    title: 'text-red-950',   desc: 'text-red-800/80',   action: 'text-red-900 hover:bg-red-100' },
    orange: { bg: 'bg-orange-50 border-orange-200',icon: 'text-orange-600', title: 'text-orange-950',desc: 'text-orange-800/80',action: 'text-orange-900 hover:bg-orange-100' },
    blue:   { bg: 'bg-blue-50 border-blue-200',    icon: 'text-blue-600',   title: 'text-blue-950',  desc: 'text-blue-800/80',  action: 'text-blue-900 hover:bg-blue-100' },
  } as const;

  if (draftCompanies && draftCompanies.length > 0) {
    notifications.push({
      icon: Building2,
      color: tones.amber.icon,
      bg: tones.amber.bg,
      titleClass: tones.amber.title,
      descClass: tones.amber.desc,
      actionClass: tones.amber.action,
      title: `${draftCompanies.length} company ${draftCompanies.length === 1 ? 'account' : 'accounts'} awaiting approval`,
      description:
        draftCompanies.slice(0, 3).map((c) => c.name).join(', ') +
        (draftCompanies.length > 3 ? ` +${draftCompanies.length - 3} more` : ''),
      action: () => router.visit('/admin/companies'),
      actionLabel: 'Review',
    });
  }

  if (pendingCourses && pendingCourses.length > 0) {
    notifications.push({
      icon: GraduationCap,
      color: tones.amber.icon,
      bg: tones.amber.bg,
      titleClass: tones.amber.title,
      descClass: tones.amber.desc,
      actionClass: tones.amber.action,
      title: `${pendingCourses.length} course${pendingCourses.length === 1 ? '' : 's'} awaiting approval`,
      description:
        pendingCourses
          .slice(0, 3)
          .map((c) => c.title + (c.owner_company_name ? ` (${c.owner_company_name})` : ''))
          .join(', ') + (pendingCourses.length > 3 ? ` +${pendingCourses.length - 3} more` : ''),
      action: () => router.visit('/admin/courses'),
      actionLabel: 'Review',
    });
  }

  if (upcomingUnassigned && upcomingUnassigned.length > 0) {
    notifications.push({
      icon: CalendarClock,
      color: tones.red.icon,
      bg: tones.red.bg,
      titleClass: tones.red.title,
      descClass: tones.red.desc,
      actionClass: tones.red.action,
      title: `${upcomingUnassigned.length} upcoming ${upcomingUnassigned.length === 1 ? 'booking' : 'bookings'} without a trainer`,
      description: upcomingUnassigned.slice(0, 2).map((o) => o.course?.title).filter(Boolean).join(', '),
      action: () => router.visit('/admin/orders?unassigned=1'),
      actionLabel: 'Assign',
    });
  }

  if (expiringDiscounts && expiringDiscounts.length > 0) {
    notifications.push({
      icon: Tag,
      color: tones.orange.icon,
      bg: tones.orange.bg,
      titleClass: tones.orange.title,
      descClass: tones.orange.desc,
      actionClass: tones.orange.action,
      title: `${expiringDiscounts.length} discount ${expiringDiscounts.length === 1 ? 'code' : 'codes'} expiring soon`,
      description: expiringDiscounts.slice(0, 3).map((d) => d.code).join(', '),
      action: () => router.visit('/admin/discount-codes'),
      actionLabel: 'View',
    });
  }

  if (expiredCerts && expiredCerts.length > 0) {
    notifications.push({
      icon: Award,
      color: tones.red.icon,
      bg: tones.red.bg,
      titleClass: tones.red.title,
      descClass: tones.red.desc,
      actionClass: tones.red.action,
      title: `${expiredCerts.length} expired certificate${expiredCerts.length === 1 ? '' : 's'} still marked active`,
      description: 'Review and update certificate statuses',
      action: () => router.visit('/admin/certificates'),
      actionLabel: 'Review',
    });
  }

  if (expiringCerts && expiringCerts.length > 0) {
    notifications.push({
      icon: Award,
      color: tones.amber.icon,
      bg: tones.amber.bg,
      titleClass: tones.amber.title,
      descClass: tones.amber.desc,
      actionClass: tones.amber.action,
      title: `${expiringCerts.length} certificate${expiringCerts.length === 1 ? '' : 's'} expiring within 30 days`,
      description: expiringCerts.slice(0, 3).map((c) => c.courses?.title).filter(Boolean).join(', '),
      action: () => router.visit('/admin/certificates'),
      actionLabel: 'View',
    });
  }

  if (pendingReschedules && pendingReschedules.length > 0) {
    notifications.push({
      icon: RefreshCw,
      color: tones.blue.icon,
      bg: tones.blue.bg,
      titleClass: tones.blue.title,
      descClass: tones.blue.desc,
      actionClass: tones.blue.action,
      title: `${pendingReschedules.length} reschedule ${pendingReschedules.length === 1 ? 'request' : 'requests'} pending`,
      description: pendingReschedules.slice(0, 3).map((r) => r.course_orders?.courses?.title).filter(Boolean).join(', '),
      action: () => router.visit('/admin/date-changes'),
      actionLabel: 'Review',
    });
  }

  if (notifications.length === 0) return null;

  return (
    <div className="space-y-3">
      <h2 className="text-sm font-semibold text-muted-foreground uppercase tracking-wider flex items-center gap-2">
        <AlertTriangle className="h-4 w-4" /> Requires Attention
      </h2>
      {/* Base grid-cols-1 is load-bearing: without it the implicit auto column is
          sized by the truncate (nowrap) description and overflows the viewport on mobile. */}
      <div className="grid grid-cols-1 gap-3 md:grid-cols-2 lg:grid-cols-3">
        {notifications.map((n, i) => (
          <Card key={i} className={`min-w-0 border ${n.bg}`}>
            <CardContent className="py-4 flex items-start gap-3">
              <n.icon className={`h-5 w-5 shrink-0 mt-0.5 ${n.color}`} />
              <div className="flex-1 min-w-0">
                <p className={`font-medium text-sm ${n.titleClass}`}>{n.title}</p>
                {n.description && (
                  <p className={`text-xs mt-0.5 truncate ${n.descClass}`}>{n.description}</p>
                )}
              </div>
              <Button
                variant="ghost"
                size="sm"
                className={`shrink-0 ${n.actionClass}`}
                onClick={n.action}
              >
                {n.actionLabel} <ArrowRight className="ml-1 h-3 w-3" />
              </Button>
            </CardContent>
          </Card>
        ))}
      </div>
    </div>
  );
};

export default DashboardNotifications;
