'use client';

import { useEffect, useState, useCallback, useMemo } from 'react';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import {
  Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription,
} from '@/components/ui/dialog';
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table';
import {
  RefreshCw, CheckCircle2, AlertTriangle, WifiOff, GitCompare,
  Ticket, ChevronRight, ChevronDown, Sparkles, Loader2,
} from 'lucide-react';
import { Skeleton } from '@/components/ui/skeleton';

// ── Types ─────────────────────────────────────────────────────────────────────

type MatchStatus = 'both' | 'pulse_only' | 'datto_only' | 'offline_suppressed';

interface AtTicket {
  ticket_number: string;
  title: string;
  status: number | null;
  priority: number | null;
  created_at: string | null;
  completed_at: string | null;
  datto_source: string | null;
}

interface MatchRow {
  key: string;
  hostname: string | null;
  org_name: string | null;
  company_id: number | null;
  status: MatchStatus;
  pulse: {
    job_name: string;
    priority_level: string;
    hours_overdue: number;
    failure_category: string | null;
    opened_at: string;
  } | null;
  offline: { hours_offline: number; last_suppressed: string } | null;
  at_ticket_count: number;
  at_open_count: number;
  at_tickets: AtTicket[];
}

interface ClientGroup {
  org_name: string | null;
  company_id: number | null;
  rows: MatchRow[];
  counts: Record<MatchStatus, number>;
  totalAtTickets: number;
  totalAtOpen: number;
}

interface ComparisonData {
  period: string;
  summary: {
    pulse_open: number;
    datto_at_total: number;
    datto_at_open: number;
    both: number;
    pulse_only: number;
    datto_only: number;
    offline_suppressed: number;
  };
  matches: MatchRow[];
}

interface AnalysisResult {
  ticket_number: string;
  hostname: string;
  org_name: string;
  hours_offline: number | null;
  total_hours_logged: number;
  note_count: number;
  model: string;
  analysis: {
    would_suppress_correctly?: boolean;
    confidence?: string;
    work_summary?: string;
    reasoning?: string;
    recommendation?: string;
    raw?: string;
  };
}

// ── Constants ─────────────────────────────────────────────────────────────────

const PERIODS = [
  { value: '1d',  label: 'Last 24h' },
  { value: '7d',  label: 'Last 7d'  },
  { value: '14d', label: 'Last 14d' },
  { value: '30d', label: 'Last 30d' },
];

const CLOSED_STATUSES = [5, 29832279, 29832280];

const STATUS_CONFIG: Record<MatchStatus, {
  label: string;
  badgeVariant: 'default' | 'destructive' | 'secondary' | 'outline';
  rowAccent: string;
}> = {
  both:               { label: 'Both',         badgeVariant: 'default',     rowAccent: 'border-l-2 border-l-blue-500/50'       },
  pulse_only:         { label: 'Pulse Only',    badgeVariant: 'destructive', rowAccent: 'border-l-2 border-l-destructive/50'    },
  datto_only:         { label: 'Datto/AT',      badgeVariant: 'secondary',   rowAccent: 'border-l-2 border-l-orange-400/50'     },
  offline_suppressed: { label: 'Offline',       badgeVariant: 'outline',     rowAccent: 'border-l-2 border-l-muted-foreground/40' },
};

// ── Helpers ───────────────────────────────────────────────────────────────────

function timeAgo(dateStr: string | null | undefined): string {
  if (!dateStr) return '—';
  const diff = Date.now() - new Date(dateStr).getTime();
  const h = Math.floor(diff / 3_600_000);
  if (h < 1)  return 'Just now';
  if (h < 24) return `${h}h ago`;
  return `${Math.floor(h / 24)}d ago`;
}

function atStatusOpen(status: number | null): boolean {
  return !CLOSED_STATUSES.includes(status ?? -1);
}

function atStatusLabel(status: number | null): string {
  const map: Record<number, string> = { 1: 'New', 5: 'Complete', 8: 'In Progress', 47: 'Waiting' };
  return map[status ?? -1] ?? (status != null ? `#${status}` : '?');
}

function PriorityBadge({ level }: { level: string }) {
  const cls = level === 'critical' ? 'text-destructive border-destructive'
            : level === 'high'     ? 'text-orange-500 border-orange-500'
            : 'text-muted-foreground border-muted-foreground/40';
  return <Badge variant="outline" className={`text-[10px] px-1.5 ${cls}`}>{level}</Badge>;
}

// ── Analyze Dialog ────────────────────────────────────────────────────────────

function AnalyzeDialog({
  ticket, hostname, orgName, hoursOffline, onClose,
}: {
  ticket: AtTicket;
  hostname: string;
  orgName: string;
  hoursOffline?: number;
  onClose: () => void;
}) {
  const [loading, setLoading] = useState(true);
  const [result, setResult]   = useState<AnalysisResult | null>(null);
  const [error, setError]     = useState<string | null>(null);

  useEffect(() => {
    fetch('/api/veeam/rpo-analyze', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        at_ticket_number: ticket.ticket_number,
        hostname,
        org_name: orgName,
        hours_offline: hoursOffline,
      }),
    })
      .then(r => r.json())
      .then(d => { if (d.error) setError(d.error); else setResult(d); })
      .catch(e => setError(e.message))
      .finally(() => setLoading(false));
  }, [ticket.ticket_number, hostname, orgName, hoursOffline]);

  const a = result?.analysis;
  const suppressed = a?.would_suppress_correctly;

  return (
    <Dialog open onOpenChange={onClose}>
      <DialogContent className="max-w-xl">
        <DialogHeader>
          <DialogTitle className="flex items-center gap-2">
            <Sparkles className="h-4 w-4 text-blue-500" />
            RPO Suppression Analysis
          </DialogTitle>
          <DialogDescription>
            {ticket.ticket_number} · {hostname} · {orgName}
          </DialogDescription>
        </DialogHeader>

        {loading && (
          <div className="flex items-center gap-2 py-8 justify-center text-muted-foreground">
            <Loader2 className="h-4 w-4 animate-spin" />
            <span className="text-sm">Analyzing ticket work...</span>
          </div>
        )}

        {error && (
          <div className="text-sm text-destructive py-4">{error}</div>
        )}

        {result && a && (
          <div className="space-y-4 py-2">
            {/* Verdict */}
            <div className={`rounded-lg border px-4 py-3 flex items-start gap-3 ${
              suppressed ? 'border-green-500/30 bg-green-500/5' : 'border-orange-500/30 bg-orange-500/5'
            }`}>
              <div className="mt-0.5">
                {suppressed
                  ? <CheckCircle2 className="h-5 w-5 text-green-500" />
                  : <AlertTriangle className="h-5 w-5 text-orange-500" />}
              </div>
              <div>
                <div className="font-medium text-sm">
                  {suppressed
                    ? 'Suppression would have been correct'
                    : 'Human intervention was needed'}
                </div>
                <div className="text-xs text-muted-foreground mt-0.5">
                  Confidence: {a.confidence ?? 'unknown'}
                  {result.total_hours_logged > 0 && ` · ${result.total_hours_logged.toFixed(2)}h logged`}
                  {result.note_count > 0 && ` · ${result.note_count} note${result.note_count !== 1 ? 's' : ''}`}
                </div>
              </div>
            </div>

            {/* Work summary */}
            {a.work_summary && (
              <div>
                <div className="text-xs font-medium text-muted-foreground uppercase tracking-wide mb-1">Work Summary</div>
                <p className="text-sm">{a.work_summary}</p>
              </div>
            )}

            {/* Reasoning */}
            {a.reasoning && (
              <div>
                <div className="text-xs font-medium text-muted-foreground uppercase tracking-wide mb-1">Reasoning</div>
                <p className="text-sm text-muted-foreground">{a.reasoning}</p>
              </div>
            )}

            {/* Recommendation */}
            {a.recommendation && (
              <div className="rounded border px-3 py-2 bg-muted/30">
                <p className="text-xs text-muted-foreground">{a.recommendation}</p>
              </div>
            )}

            {a.raw && <pre className="text-xs bg-muted p-3 rounded overflow-auto max-h-40">{a.raw}</pre>}

            <div className="text-[10px] text-muted-foreground">Model: {result.model}</div>
          </div>
        )}
      </DialogContent>
    </Dialog>
  );
}

// ── AT Ticket Cell ────────────────────────────────────────────────────────────

function AtTicketCell({ tickets, ticketCount, hostname, orgName, hoursOffline }: {
  tickets: AtTicket[];
  ticketCount: number;
  hostname: string | null;
  orgName: string | null;
  hoursOffline?: number;
}) {
  const [analyzing, setAnalyzing] = useState<AtTicket | null>(null);

  if (tickets.length === 0) return <span className="text-muted-foreground">—</span>;

  return (
    <>
      <div className="space-y-1.5">
        {tickets.map((t, i) => {
          const isOpen = atStatusOpen(t.status);
          const isClosed = !isOpen;
          return (
            <div key={i} className="flex items-center gap-1.5 flex-wrap">
              <span className="font-mono font-medium">{t.ticket_number}</span>
              <Badge
                variant="outline"
                className={`text-[10px] h-4 px-1 ${isOpen ? 'text-orange-500 border-orange-500' : 'text-green-600 border-green-600/50'}`}
              >
                {atStatusLabel(t.status)}
              </Badge>
              {t.datto_source && (
                <span className="text-muted-foreground text-[10px]">{t.datto_source}</span>
              )}
              <span className="text-muted-foreground text-[10px]">{timeAgo(t.created_at)}</span>
              {isClosed && hostname && (
                <button
                  onClick={() => setAnalyzing(t)}
                  className="inline-flex items-center gap-0.5 text-[10px] text-blue-500 hover:text-blue-400 transition-colors"
                >
                  <Sparkles className="h-2.5 w-2.5" />
                  Analyze
                </button>
              )}
            </div>
          );
        })}
        {ticketCount > 5 && (
          <div className="text-muted-foreground text-[10px]">+{ticketCount - 5} more</div>
        )}
      </div>

      {analyzing && (
        <AnalyzeDialog
          ticket={analyzing}
          hostname={hostname ?? ''}
          orgName={orgName ?? ''}
          hoursOffline={hoursOffline}
          onClose={() => setAnalyzing(null)}
        />
      )}
    </>
  );
}

// ── Client Group Row ──────────────────────────────────────────────────────────

function ClientGroupRow({ group, defaultOpen }: { group: ClientGroup; defaultOpen: boolean }) {
  const [open, setOpen] = useState(defaultOpen);

  const actionable = group.counts.both + group.counts.pulse_only;

  return (
    <>
      {/* Group summary header — columns align with the detail table below */}
      <TableRow
        className="bg-muted/30 cursor-pointer select-none"
        onClick={() => setOpen(o => !o)}
      >
        {/* Device col: chevron + org name */}
        <TableCell className="w-44">
          <div className="flex items-center gap-1.5">
            {open
              ? <ChevronDown  className="h-3.5 w-3.5 text-muted-foreground flex-shrink-0" />
              : <ChevronRight className="h-3.5 w-3.5 text-muted-foreground flex-shrink-0" />}
            <span className="font-semibold text-sm truncate">{group.org_name ?? 'Unknown'}</span>
          </div>
        </TableCell>
        {/* Match col: status pills */}
        <TableCell className="w-36">
          <div className="flex flex-wrap gap-1">
            {group.counts.both > 0 && (
              <Badge variant="default"     className="text-[10px] h-4 px-1">{group.counts.both} Both</Badge>
            )}
            {group.counts.pulse_only > 0 && (
              <Badge variant="destructive" className="text-[10px] h-4 px-1">{group.counts.pulse_only} Pulse</Badge>
            )}
            {group.counts.datto_only > 0 && (
              <Badge variant="secondary"   className="text-[10px] h-4 px-1">{group.counts.datto_only} Datto</Badge>
            )}
            {group.counts.offline_suppressed > 0 && (
              <Badge variant="outline"     className="text-[10px] h-4 px-1">{group.counts.offline_suppressed} Offline</Badge>
            )}
          </div>
        </TableCell>
        {/* Pulse shadow col: total devices flagged */}
        <TableCell className="text-xs text-muted-foreground">
          {actionable > 0
            ? <span className="font-medium text-foreground">{actionable} device{actionable !== 1 ? 's' : ''} need attention</span>
            : <span>{group.rows.length} device{group.rows.length !== 1 ? 's' : ''}</span>}
        </TableCell>
        {/* AT tickets col: ticket count */}
        <TableCell className="text-xs text-muted-foreground">
          {group.totalAtTickets > 0
            ? <>{group.totalAtTickets} ticket{group.totalAtTickets !== 1 ? 's' : ''}{group.totalAtOpen > 0 && <span className="text-orange-500 ml-1">· {group.totalAtOpen} open</span>}</>
            : <span>—</span>}
        </TableCell>
      </TableRow>

      {/* Device detail rows */}
      {open && group.rows.map((row) => {
        const cfg = STATUS_CONFIG[row.status];
        return (
          <TableRow key={row.key} className={`align-top text-xs ${cfg.rowAccent}`}>
            <TableCell className="pl-9 num font-medium w-44 text-[11px]">
              {row.hostname ?? <span className="italic text-muted-foreground">unknown</span>}
            </TableCell>
            <TableCell className="w-36">
              <Badge variant={cfg.badgeVariant} className="text-[10px]">{cfg.label}</Badge>
            </TableCell>
            <TableCell className="space-y-0.5 max-w-[240px]">
              {row.pulse ? (
                <>
                  <div className="flex items-center gap-1.5">
                    <PriorityBadge level={row.pulse.priority_level} />
                    <span className="font-medium">{row.pulse.hours_overdue}h overdue</span>
                  </div>
                  <div className="text-muted-foreground truncate">{row.pulse.failure_category ?? '—'}</div>
                  <div className="text-muted-foreground text-[10px]">since {timeAgo(row.pulse.opened_at)}</div>
                </>
              ) : row.offline ? (
                <span className="flex items-center gap-1 text-muted-foreground">
                  <WifiOff className="h-3 w-3" />offline {Math.round(row.offline.hours_offline)}h
                </span>
              ) : (
                <span className="text-muted-foreground">—</span>
              )}
            </TableCell>
            <TableCell>
              <AtTicketCell
                tickets={row.at_tickets}
                ticketCount={row.at_ticket_count}
                hostname={row.hostname}
                orgName={row.org_name}
                hoursOffline={row.offline?.hours_offline}
              />
            </TableCell>
          </TableRow>
        );
      })}
    </>
  );
}

// ── Page ──────────────────────────────────────────────────────────────────────

export default function VeeamComparisonPage() {
  const [data, setData]     = useState<ComparisonData | null>(null);
  const [period, setPeriod] = useState('7d');
  const [loading, setLoading] = useState(true);
  const [filter, setFilter] = useState<MatchStatus | 'all'>('all');

  const fetchData = useCallback(async () => {
    setLoading(true);
    try {
      const res = await fetch(`/api/veeam/rpo-comparison?period=${period}`);
      setData(await res.json());
    } finally {
      setLoading(false);
    }
  }, [period]);

  useEffect(() => { fetchData(); }, [fetchData]);

  const groups = useMemo<ClientGroup[]>(() => {
    if (!data) return [];
    const filtered = data.matches.filter(m => filter === 'all' || m.status === filter);

    const byOrg = new Map<string, ClientGroup>();
    for (const row of filtered) {
      const key = row.org_name ?? '(Unknown)';
      if (!byOrg.has(key)) {
        byOrg.set(key, {
          org_name: row.org_name, company_id: row.company_id,
          rows: [], counts: { both: 0, pulse_only: 0, datto_only: 0, offline_suppressed: 0 },
          totalAtTickets: 0, totalAtOpen: 0,
        });
      }
      const g = byOrg.get(key)!;
      g.rows.push(row);
      g.counts[row.status]++;
      g.totalAtTickets += row.at_ticket_count;
      g.totalAtOpen    += row.at_open_count;
    }

    return Array.from(byOrg.values()).sort((a, b) => {
      const aScore = (a.counts.both + a.counts.pulse_only) > 0 ? 1 : 0;
      const bScore = (b.counts.both + b.counts.pulse_only) > 0 ? 1 : 0;
      if (bScore !== aScore) return bScore - aScore;
      return (a.org_name ?? '').localeCompare(b.org_name ?? '');
    });
  }, [data, filter]);

  const filteredTotal = data?.matches.filter(m => filter === 'all' || m.status === filter).length ?? 0;

  return (
    <div className="container mx-auto px-6 py-6 space-y-6">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-bold flex items-center gap-2">
            <GitCompare className="h-6 w-6" />
            Veeam RPO — Shadow vs Datto/AT
          </h1>
          <p className="text-sm text-muted-foreground mt-1">
            What Pulse <em>would</em> ticket (shadow mode) vs what Datto RMM actually created in Autotask.
            Click <Sparkles className="h-3 w-3 inline text-blue-500" /> Analyze on any closed ticket to evaluate suppression accuracy.
          </p>
        </div>
        <div className="flex items-center gap-2">
          {PERIODS.map(p => (
            <Button key={p.value} variant={period === p.value ? 'default' : 'outline'} size="sm" onClick={() => setPeriod(p.value)}>
              {p.label}
            </Button>
          ))}
          <Button variant="outline" size="sm" onClick={fetchData} disabled={loading}>
            <RefreshCw className={`h-4 w-4 ${loading ? 'animate-spin' : ''}`} />
          </Button>
        </div>
      </div>

      {loading && !data ? (
        <div className="grid gap-4 md:grid-cols-4">
          {[...Array(4)].map((_, i) => <Skeleton key={i} className="h-24" />)}
        </div>
      ) : data && (
        <>
          {/* Summary cards */}
          <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
            {([
              { key: 'both',               label: 'Both Agree',        icon: CheckCircle2, iconCls: 'text-blue-500',        value: data.summary.both,               sub: 'Pulse + Datto both flagged',                                                       valCls: '' },
              { key: 'pulse_only',         label: 'Pulse Only',        icon: AlertTriangle,iconCls: 'text-destructive',     value: data.summary.pulse_only,         sub: 'No AT ticket from Datto',                                                          valCls: 'text-destructive' },
              { key: 'datto_only',         label: 'Datto / AT Only',   icon: Ticket,       iconCls: 'text-orange-500',      value: data.summary.datto_only,         sub: `${data.summary.datto_at_total} total · ${data.summary.datto_at_open} open`,        valCls: 'text-orange-500' },
              { key: 'offline_suppressed', label: 'Offline Suppressed',icon: WifiOff,      iconCls: 'text-muted-foreground',value: data.summary.offline_suppressed, sub: 'Device offline — suppressed',                                                      valCls: '' },
            ] as const).map(({ key, label, icon: Icon, iconCls, value, sub, valCls }) => (
              <Card key={key} className="cursor-pointer hover:bg-muted/30" onClick={() => setFilter(key as any)}>
                <CardHeader className="flex flex-row items-center justify-between pb-2">
                  <CardTitle className="text-sm font-medium">{label}</CardTitle>
                  <Icon className={`h-4 w-4 ${iconCls}`} />
                </CardHeader>
                <CardContent>
                  <div className={`text-2xl font-bold ${valCls}`}>{value}</div>
                  <p className="text-xs text-muted-foreground">{sub}</p>
                </CardContent>
              </Card>
            ))}
          </div>

          {/* Table */}
          <Tabs value={filter} onValueChange={v => setFilter(v as any)}>
            <TabsList>
              <TabsTrigger value="all">
                All <Badge variant="secondary" className="ml-1.5 h-4 px-1 text-[10px]">{data.matches.length}</Badge>
              </TabsTrigger>
              <TabsTrigger value="both">Both ({data.summary.both})</TabsTrigger>
              <TabsTrigger value="pulse_only">Pulse Only ({data.summary.pulse_only})</TabsTrigger>
              <TabsTrigger value="datto_only">Datto/AT ({data.summary.datto_only})</TabsTrigger>
              <TabsTrigger value="offline_suppressed">Offline ({data.summary.offline_suppressed})</TabsTrigger>
            </TabsList>

            <TabsContent value={filter} className="mt-4">
              <div className="rounded-md border overflow-hidden">
                <Table>
                  <TableHeader className="bg-muted/50">
                    <TableRow>
                      <TableHead className="text-xs w-44">Device</TableHead>
                      <TableHead className="text-xs w-36">Match</TableHead>
                      <TableHead className="text-xs">Pulse Shadow</TableHead>
                      <TableHead className="text-xs">Autotask Tickets</TableHead>
                    </TableRow>
                  </TableHeader>
                  <TableBody>
                    {groups.length > 0 ? groups.map(group => (
                      <ClientGroupRow
                        key={group.org_name ?? 'unknown'}
                        group={group}
                        defaultOpen={(group.counts.both + group.counts.pulse_only) > 0}
                      />
                    )) : (
                      <TableRow>
                        <TableCell colSpan={4} className="px-4 py-10 text-center text-sm text-muted-foreground">
                          {data.matches.length === 0
                            ? 'No data yet — RPO check must run at least once.'
                            : 'No rows match this filter.'}
                        </TableCell>
                      </TableRow>
                    )}
                  </TableBody>
                </Table>
              </div>
              {groups.length > 0 && (
                <p className="text-xs text-muted-foreground mt-2 pl-1">
                  {groups.length} client{groups.length !== 1 ? 's' : ''} · {filteredTotal} device{filteredTotal !== 1 ? 's' : ''}
                </p>
              )}
            </TabsContent>
          </Tabs>
        </>
      )}
    </div>
  );
}
