'use client';

import { useEffect, useState } from 'react';
import { toast } from 'sonner';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Skeleton } from '@/components/ui/skeleton';
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import { CheckCircle2, AlertTriangle, Loader2 } from 'lucide-react';
import { PageHeader } from '@/components/navigation/page-header';
import { useUserTimezone } from '@/lib/hooks/use-user-timezone';

interface Candidate {
  ciId: string;
  confidence: string | null;
  hostname: string | null;
  serial: string | null;
  mac: string | null;
  companyId: string | null;
  companyName: string | null;
  isDeleted: boolean;
}

interface Review {
  id: string;
  detectedAt: string;
  xref: {
    id: string;
    source: string;
    sourceId: string;
    hostname: string | null;
    serial: string | null;
    mac: string | null;
    companyId: string | null;
    companyName: string | null;
    lastSeenAt: string | null;
  };
  candidates: Candidate[];
}

const SOURCES = ['all', 'datto_rmm', 'itglue', 's1', 'veeam'] as const;
type SourceFilter = (typeof SOURCES)[number];

function confidenceColor(c: string | null): 'default' | 'secondary' | 'outline' {
  if (c === 'exact_serial') return 'default';
  if (c === 'mac') return 'default';
  if (c === 'hostname_in_company') return 'secondary';
  return 'outline';
}

const CONFIDENCE_RANK: Record<string, number> = {
  exact_serial: 0,
  mac: 1,
  hostname_in_company: 2,
};

function dedupeCandidates(candidates: Candidate[]): Candidate[] {
  const byId = new Map<string, Candidate>();
  for (const c of candidates) {
    const existing = byId.get(c.ciId);
    if (!existing) {
      byId.set(c.ciId, c);
      continue;
    }
    const a = CONFIDENCE_RANK[existing.confidence ?? ''] ?? 99;
    const b = CONFIDENCE_RANK[c.confidence ?? ''] ?? 99;
    if (b < a) byId.set(c.ciId, c);
  }
  return Array.from(byId.values());
}

export default function DeviceLinkConflictsPage() {
  const tz = useUserTimezone();
  const [items, setItems] = useState<Review[] | null>(null);
  const [total, setTotal] = useState(0);
  const [error, setError] = useState<string | null>(null);
  const [source, setSource] = useState<SourceFilter>('all');
  const [resolving, setResolving] = useState<string | null>(null);

  async function load(): Promise<void> {
    setError(null);
    setItems(null);
    try {
      const params = new URLSearchParams({ limit: '100' });
      if (source !== 'all') params.set('source', source);
      const res = await fetch(`/api/admin/device-link-conflicts?${params}`);
      if (!res.ok) {
        const data = (await res.json().catch(() => ({}))) as { error?: string };
        throw new Error(data.error ?? `Request failed: ${res.status}`);
      }
      const data = (await res.json()) as { items: Review[]; total: number };
      setItems(data.items);
      setTotal(data.total);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Unknown error');
    }
  }

  useEffect(() => {
    void load();
  }, [source]);

  async function resolve(reviewId: string, ciId: string): Promise<void> {
    setResolving(`${reviewId}:${ciId}`);
    try {
      const res = await fetch(`/api/admin/device-link-conflicts/${reviewId}/resolve`, {
        method: 'POST',
        headers: { 'content-type': 'application/json' },
        body: JSON.stringify({ ciId }),
      });
      const data = (await res.json().catch(() => ({}))) as { error?: string };
      if (!res.ok) throw new Error(data.error ?? `Request failed: ${res.status}`);
      toast.success(`Linked to CI ${ciId}`);
      setItems((prev) => prev?.filter((r) => r.id !== reviewId) ?? null);
      setTotal((t) => Math.max(0, t - 1));
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Resolve failed');
    } finally {
      setResolving(null);
    }
  }

  return (
    <>
      <PageHeader
        title="Device-link conflicts"
        description="Cases where the reconciler found two or more configuration_items matching one external device record. Pick the right CI to break the tie."
        breadcrumbs={[{ label: 'Admin', href: '/admin' }, { label: 'Device-Link Conflicts' }]}
        accent
      />
      <div className="container mx-auto px-6 py-6 max-w-6xl space-y-6">
      <Card>
        <CardHeader>
          <CardTitle className="flex items-center gap-2">
            <AlertTriangle className="size-5 text-amber-500" />
            Device-link conflicts
          </CardTitle>
        </CardHeader>
        <CardContent className="space-y-4">
          <p className="text-sm text-muted-foreground">
            Cases where the reconciler found two or more configuration_items
            matching one external device record. Pick the right CI to break the
            tie. Skipped rows stay unlinked until resolved.
          </p>

          <div className="flex items-center gap-3">
            <span className="text-sm font-medium">Source:</span>
            <Select value={source} onValueChange={(v) => setSource(v as SourceFilter)}>
              <SelectTrigger className="w-[200px]">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                {SOURCES.map((s) => (
                  <SelectItem key={s} value={s}>
                    {s}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
            <span className="text-sm text-muted-foreground">
              {total} unresolved {total === 1 ? 'conflict' : 'conflicts'}
            </span>
          </div>

          {error && (
            <Alert variant="destructive">
              <AlertTitle>Failed to load</AlertTitle>
              <AlertDescription>{error}</AlertDescription>
            </Alert>
          )}

          {items === null && !error && (
            <div className="space-y-2">
              <Skeleton className="h-24 w-full" />
              <Skeleton className="h-24 w-full" />
              <Skeleton className="h-24 w-full" />
            </div>
          )}

          {items !== null && items.length === 0 && !error && (
            <Alert>
              <CheckCircle2 className="size-4" />
              <AlertTitle>No conflicts</AlertTitle>
              <AlertDescription>
                Nothing waiting for review on this filter.
              </AlertDescription>
            </Alert>
          )}

          {items?.map((r) => {
            const candidates = dedupeCandidates(r.candidates);
            return (
            <Card key={r.id} className="border-amber-200">
              <CardHeader className="pb-3">
                <div className="flex items-baseline justify-between gap-3">
                  <div className="space-y-0.5">
                    <div className="text-sm font-mono">
                      {r.xref.source}:{r.xref.sourceId}
                    </div>
                    <div className="text-base font-medium">
                      {r.xref.hostname ?? '(no hostname)'}
                      {r.xref.companyName && (
                        <span className="text-sm text-muted-foreground ml-2">
                          @ {r.xref.companyName}
                        </span>
                      )}
                    </div>
                  </div>
                  <Badge variant="outline" className="text-xs">
                    {candidates.length} candidates
                  </Badge>
                </div>
                <div className="text-xs text-muted-foreground space-x-3">
                  {r.xref.serial && <span>serial: {r.xref.serial}</span>}
                  {r.xref.mac && <span>mac: {r.xref.mac}</span>}
                  {r.xref.lastSeenAt && (
                    <span>last seen: {new Date(r.xref.lastSeenAt).toLocaleString(undefined, { timeZone: tz })}</span>
                  )}
                </div>
              </CardHeader>
              <CardContent className="space-y-2">
                {candidates.map((c) => {
                  const isResolving = resolving === `${r.id}:${c.ciId}`;
                  return (
                    <div
                      key={c.ciId}
                      className="flex items-center justify-between gap-3 rounded-md border p-3"
                    >
                      <div className="space-y-0.5 min-w-0 flex-1">
                        <div className="flex items-center gap-2 text-sm">
                          <span className="font-medium truncate">
                            {c.hostname ?? '(no hostname)'}
                          </span>
                          {c.isDeleted && (
                            <Badge variant="destructive" className="text-xs">
                              deleted
                            </Badge>
                          )}
                          {c.confidence && (
                            <Badge
                              variant={confidenceColor(c.confidence)}
                              className="text-xs"
                            >
                              {c.confidence}
                            </Badge>
                          )}
                        </div>
                        <div className="text-xs text-muted-foreground space-x-3">
                          <span className="font-mono">CI {c.ciId}</span>
                          {c.serial && <span>serial: {c.serial}</span>}
                          {c.companyName && <span>@ {c.companyName}</span>}
                        </div>
                      </div>
                      <Button
                        size="sm"
                        disabled={isResolving || c.isDeleted}
                        onClick={() => void resolve(r.id, c.ciId)}
                      >
                        {isResolving ? (
                          <>
                            <Loader2 className="size-3 animate-spin mr-1" />
                            Linking…
                          </>
                        ) : (
                          'Link to this CI'
                        )}
                      </Button>
                    </div>
                  );
                })}
              </CardContent>
            </Card>
            );
          })}
        </CardContent>
      </Card>
      </div>
    </>
  );
}
