'use client';

import { useEffect, useMemo, useState } from 'react';
import { AlertTriangle, ChevronLeft, ChevronRight } from 'lucide-react';

import DetectionLocationMap from '@/components/map/detectionLocationMap';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Skeleton } from '@/components/ui/skeleton';
import AnnotatedDetectionImage from '@/components/video/annotatedDetectionImage';
import { getDefectVisual } from '@/constants/defectVisualConfig';
import { cn } from '@/lib/utils';

import { useTicketClassDetectionsQuery } from '../../hooks/useTicketQueries';

interface TicketClassDetectionPreviewProps {
  videoId?: string | null;
  defectClassName: string;
  displayName: string;
  totalCount?: number;
}

function DetectionMetadataBar({
  items,
}: {
  items: { label: string; value: string | number }[];
}) {
  return (
    <div className="rounded-lg bg-muted/40 px-4 py-4">
      <div className="grid grid-cols-1 gap-4 sm:grid-cols-3 sm:divide-x sm:divide-border/70">
        {items.map((item, index) => (
          <div
            key={item.label}
            className={cn(
              'space-y-1',
              index === 0 && 'sm:pr-4',
              index === 1 && 'sm:px-4',
              index === 2 && 'sm:pl-4',
            )}
          >
            <p className="text-xs text-muted-foreground">{item.label}</p>
            <div className="text-sm font-semibold text-foreground">
              {item.value}
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

function TicketClassDetectionPreviewSkeleton() {
  return (
    <>
      <div className="grid grid-cols-1 gap-4 xl:grid-cols-2">
        <div className="min-w-0 space-y-2">
          <Skeleton className="h-3 w-24" />
          <Skeleton className="aspect-video w-full rounded-lg" />
        </div>
        <div className="min-w-0 space-y-2">
          <Skeleton className="h-3 w-28" />
          <Skeleton
            className="w-full rounded-lg"
            style={{ aspectRatio: '16 / 9' }}
          />
        </div>
      </div>

      <div className="rounded-lg bg-muted/40 px-4 py-4">
        <div className="grid grid-cols-1 gap-4 sm:grid-cols-3 sm:divide-x sm:divide-border/70">
          {Array.from({ length: 3 }).map((_, index) => (
            <div
              key={index}
              className={cn(
                'space-y-1',
                index === 0 && 'sm:pr-4',
                index === 1 && 'sm:px-4',
                index === 2 && 'sm:pl-4',
              )}
            >
              <Skeleton className="h-3 w-16" />
              <Skeleton className="h-4 w-20" />
            </div>
          ))}
        </div>
      </div>
    </>
  );
}

export function TicketClassDetectionPreview({
  videoId,
  defectClassName,
  displayName,
  totalCount,
}: TicketClassDetectionPreviewProps) {
  const [currentIndex, setCurrentIndex] = useState(0);
  const visual = getDefectVisual(defectClassName);
  const IssueIcon = visual.icon;

  useEffect(() => {
    setCurrentIndex(0);
  }, [defectClassName]);

  const queryParams = useMemo(
    () => ({
      class_name: defectClassName,
      skip: currentIndex,
      limit: 1,
      sort: 'timestamp_asc',
    }),
    [currentIndex, defectClassName],
  );

  const detectionsQuery = useTicketClassDetectionsQuery(
    videoId ?? undefined,
    queryParams,
  );
  const detectionResult = detectionsQuery.data;
  const activeDetection = detectionResult?.items[0];
  const detectionCount = detectionResult?.total ?? totalCount ?? 0;
  const mediaAspectRatio =
    detectionResult &&
    detectionResult.video_width > 0 &&
    detectionResult.video_height > 0
      ? `${detectionResult.video_width} / ${detectionResult.video_height}`
      : '16 / 9';

  useEffect(() => {
    if (detectionCount === 0 && currentIndex !== 0) {
      setCurrentIndex(0);
      return;
    }

    if (detectionCount > 0 && currentIndex > detectionCount - 1) {
      setCurrentIndex(detectionCount - 1);
    }
  }, [currentIndex, detectionCount]);

  const isNavigationDisabled =
    detectionCount === 0 || detectionsQuery.isLoading;

  return (
    <div className="space-y-4">
      <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
        <div className="flex min-w-0 items-center gap-3">
          <span
            className={cn(
              'flex size-10 shrink-0 self-start items-center justify-center rounded-lg',
              visual.cardClassName,
            )}
          >
            <IssueIcon className={cn('size-5', visual.colorClassName)} />
          </span>
          <div className="min-w-0 space-y-1">
            <div className="flex min-w-0 flex-wrap items-center gap-2">
              <h3>{displayName}</h3>
              <Badge
                variant="secondary"
                className={cn(
                  'rounded-lg',
                  visual.cardClassName,
                  visual.colorClassName,
                )}
              >
                {detectionCount} Detections
              </Badge>
            </div>
            <p className="text-muted-foreground">
              Review detections in ascending timestamp order.
            </p>
          </div>
        </div>

        <div className="flex items-center gap-2 self-start sm:self-auto">
          <Button
            type="button"
            variant="secondary"
            onClick={() =>
              setCurrentIndex((index) =>
                detectionCount === 0
                  ? 0
                  : (index - 1 + detectionCount) % detectionCount,
              )
            }
            disabled={isNavigationDisabled}
            aria-label="Previous detection"
          >
            <ChevronLeft className="size-4" />
          </Button>
          <div className="min-w-16 text-center text-sm font-medium text-foreground">
            {detectionCount === 0
              ? '0 of 0'
              : `${currentIndex + 1} of ${detectionCount}`}
          </div>
          <Button
            type="button"
            variant="secondary"
            onClick={() =>
              setCurrentIndex((index) =>
                detectionCount === 0 ? 0 : (index + 1) % detectionCount,
              )
            }
            disabled={isNavigationDisabled}
            aria-label="Next detection"
          >
            <ChevronRight className="size-4" />
          </Button>
        </div>
      </div>

      {detectionsQuery.isLoading && !detectionsQuery.data ? (
        <TicketClassDetectionPreviewSkeleton />
      ) : detectionsQuery.isError ? (
        <div className="rounded-lg border border-dashed border-destructive/40 bg-destructive/5 px-4 py-8 text-center">
          <div className="flex flex-col items-center gap-2">
            <AlertTriangle className="size-6 text-destructive" />
            <p className="text-sm font-medium text-destructive">
              Failed to load detection preview.
            </p>
            <Button
              type="button"
              variant="outline"
              size="sm"
              onClick={() => void detectionsQuery.refetch()}
            >
              Retry
            </Button>
          </div>
        </div>
      ) : !activeDetection || !detectionResult ? (
        <div className="rounded-lg border border-dashed bg-muted/20 px-4 py-10 text-center text-sm text-muted-foreground">
          No detections are available for this issue.
        </div>
      ) : (
        <>
          <div className="grid grid-cols-1 items-start gap-4 xl:grid-cols-2">
            <div className="min-w-0 space-y-2">
              <p className="text-muted-foreground">Detection Image</p>
              <div className="overflow-hidden rounded-lg">
                <AnnotatedDetectionImage
                  detection={activeDetection}
                  videoWidth={detectionResult.video_width}
                  videoHeight={detectionResult.video_height}
                />
              </div>
            </div>

            <DetectionLocationMap
              className="min-w-0"
              latitude={activeDetection.location.latitude}
              longitude={activeDetection.location.longitude}
              label={`${displayName} - Frame ${activeDetection.frame.number}`}
              title="Location on Map"
              variant="plain"
              aspectRatio={mediaAspectRatio}
              showCoordinates={false}
            />
          </div>

          <DetectionMetadataBar
            items={[
              {
                label: 'Confidence',
                value: `${Math.round(activeDetection.detection.confidence * 100)}%`,
              },
              {
                label: 'Frame',
                value: activeDetection.frame.number,
              },
              {
                label: 'Timestamp',
                value: `${activeDetection.frame.timestamp_seconds}s`,
              },
            ]}
          />
        </>
      )}
    </div>
  );
}
