'use client';

import { useEffect } from 'react';
import {
  BriefcaseBusiness,
  CalendarClock,
  ChevronDown,
  Images,
  ListChecks,
} from 'lucide-react';

import { PersonInfo } from '@/components/person-avatar';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import {
  Collapsible,
  CollapsibleContent,
  CollapsibleTrigger,
} from '@/components/ui/collapsible';
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from '@/components/ui/card';
import { Progress } from '@/components/ui/progress';
import { getDefectVisual } from '@/constants/defectVisualConfig';
import { cn } from '@/lib/utils';
import type { TicketActor, TicketAssignmentSummary } from '@/types';
import { formatDate } from '@/utils/date';

import { useTicketAssignmentsQuery } from '../../hooks/useTicketQueries';
import { TicketDetectionPreview } from './TicketDetectionPreview';

interface TicketAssignmentsCardProps {
  ticketId: string;
  videoId?: string | null;
  initialAssignments?: TicketAssignmentSummary[];
  selectedAssignmentId?: number;
  onAssignmentChange: (assignmentId: number) => void;
}

function formatLabel(value: string) {
  return value
    .replaceAll('_', ' ')
    .replace(/\b\w/g, (character) => character.toUpperCase());
}

function AssignmentClassBadge({ className }: { className: string }) {
  const visual = getDefectVisual(className);
  const IssueIcon = visual.icon;

  return (
    <Badge
      variant="outline"
      className="h-6 gap-1.5 px-2 font-normal"
      style={{
        borderColor: `${visual.boundingBoxColor}66`,
        backgroundColor: `${visual.boundingBoxColor}14`,
        color: visual.boundingBoxColor,
      }}
    >
      <IssueIcon />
      {formatLabel(className)}
    </Badge>
  );
}

function AssignmentProgress({
  assignment,
}: {
  assignment: TicketAssignmentSummary;
}) {
  const total = Math.max(assignment.item_count, 0);
  const approved = Math.max(assignment.approved_detections, 0);
  const progress = total > 0 ? Math.min((approved / total) * 100, 100) : 0;

  return (
    <div className="min-w-0 space-y-2">
      <div className="flex min-w-0 flex-col gap-1 text-xs sm:flex-row sm:items-center sm:justify-between sm:gap-3">
        <span className="font-medium text-foreground">Repair progress</span>
        <span className="tabular-nums text-muted-foreground">
          {approved} of {total} approved
        </span>
      </div>
      <Progress value={assignment.is_complete ? 100 : progress} />
      <div className="flex min-w-0 flex-wrap gap-x-4 gap-y-1 text-xs">
        <span className="whitespace-nowrap text-emerald-600">
          {assignment.approved_detections} approved
        </span>
        <span className="whitespace-nowrap text-amber-600">
          {assignment.pending_detections} pending
        </span>
        <span className="whitespace-nowrap text-muted-foreground">
          {assignment.not_submitted_detections} not submitted
        </span>
      </div>
    </div>
  );
}

function AssignmentOverview({
  assignment,
}: {
  assignment: TicketAssignmentSummary;
}) {
  const criteria = assignment.criteria;
  const classNames = criteria?.class_names?.length
    ? criteria.class_names
    : assignment.defect_class
      ? [assignment.defect_class]
      : [];
  const worker: TicketActor = {
    user_id: assignment.assigned_to_user_id,
    name: assignment.assigned_to_name,
    email: assignment.assigned_to_email ?? null,
    avatar_url: assignment.assigned_to_avatar_url ?? null,
  };

  return (
    <div className="min-w-0 space-y-4 rounded-lg border p-3 sm:p-4">
      <div className="min-w-0">
        <p className="mb-2 text-xs font-medium text-muted-foreground">
          Assignment {assignment.id}
        </p>
        <PersonInfo person={worker} />
      </div>

      <div className="flex min-w-0 max-w-full flex-wrap items-center gap-2">
        {classNames.map((className) => (
          <AssignmentClassBadge key={className} className={className} />
        ))}
        <span className="flex items-center gap-1.5 text-xs text-muted-foreground">
          <ListChecks className="size-3.5" />
          {assignment.item_count}{' '}
          {assignment.item_count === 1 ? 'issue' : 'issues'}
        </span>
        {assignment.due_at ? (
          <span className="flex min-w-0 max-w-full items-center gap-1.5 text-xs text-muted-foreground">
            <CalendarClock className="size-3.5" />
            Due {formatDate(assignment.due_at)}
          </span>
        ) : null}
      </div>

      <AssignmentProgress assignment={assignment} />
    </div>
  );
}

export function TicketAssignmentsCard({
  ticketId,
  videoId,
  initialAssignments,
  selectedAssignmentId,
  onAssignmentChange,
}: TicketAssignmentsCardProps) {
  const assignmentsQuery = useTicketAssignmentsQuery(
    ticketId,
    initialAssignments,
  );
  const assignments = (assignmentsQuery.data?.items ?? []).filter(
    (assignment) => assignment.item_count > 0,
  );
  const selectedAssignment =
    assignments.find((assignment) => assignment.id === selectedAssignmentId) ??
    assignments[0];
  const activeAssignmentId = selectedAssignment
    ? String(selectedAssignment.id)
    : '';
  const resolvedAssignmentId = selectedAssignment?.id;

  useEffect(() => {
    if (
      resolvedAssignmentId !== undefined &&
      resolvedAssignmentId !== selectedAssignmentId
    ) {
      onAssignmentChange(resolvedAssignmentId);
    }
  }, [onAssignmentChange, resolvedAssignmentId, selectedAssignmentId]);

  return (
    <Card className="min-w-0 max-w-full">
      <CardHeader className="min-w-0 px-3 sm:px-6">
        <div className="flex items-start justify-between gap-3">
          <div className="min-w-0">
            <CardTitle className="flex items-center gap-2">
              <BriefcaseBusiness className="size-5 text-primary" />
              Work Assignments
            </CardTitle>
            <CardDescription className="mt-1">
              Issues grouped by assignee, scope, and repair progress.
            </CardDescription>
          </div>
          {assignmentsQuery.data ? (
            <Badge variant="default">
              {assignments.length}{' '}
              {assignments.length === 1 ? 'Assignment' : 'Assignments'}
            </Badge>
          ) : null}
        </div>
      </CardHeader>
      <CardContent className="min-w-0 space-y-3 overflow-hidden px-3 sm:px-6">
        {assignmentsQuery.isLoading ? (
          Array.from({ length: 2 }).map((_, index) => (
            <div
              key={index}
              className="h-40 animate-pulse rounded-lg bg-muted"
            />
          ))
        ) : assignmentsQuery.isError ? (
          <div className="rounded-lg border border-dashed p-6 text-center">
            <p className="text-sm font-medium">
              Unable to load work assignments.
            </p>
            <Button
              type="button"
              variant="outline"
              size="sm"
              className="mt-3"
              onClick={() => void assignmentsQuery.refetch()}
            >
              Try again
            </Button>
          </div>
        ) : selectedAssignment ? (
          <div className="min-w-0 space-y-3">
            <nav
              aria-label="Work assignments"
              className="w-full max-w-full overflow-x-auto overflow-y-hidden overscroll-x-contain touch-pan-x"
            >
              <div
                role="tablist"
                aria-orientation="horizontal"
                className="flex w-max min-w-full border-b"
              >
                {assignments.map((assignment) => {
                  const assignmentId = String(assignment.id);
                  const isActive = assignmentId === activeAssignmentId;

                  return (
                    <button
                      key={assignment.id}
                      id={`assignment-tab-${assignmentId}`}
                      type="button"
                      role="tab"
                      aria-selected={isActive}
                      aria-controls={`assignment-panel-${assignmentId}`}
                      tabIndex={isActive ? 0 : -1}
                      className={cn(
                        'relative shrink-0 px-3 py-2.5 text-sm font-medium whitespace-nowrap transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset',
                        isActive
                          ? 'text-foreground after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 after:bg-foreground'
                          : 'text-muted-foreground hover:text-foreground',
                      )}
                      onClick={() => onAssignmentChange(assignment.id)}
                    >
                      Assignment {assignment.id}
                    </button>
                  );
                })}
              </div>
            </nav>

            <div
              id={`assignment-panel-${activeAssignmentId}`}
              role="tabpanel"
              aria-labelledby={`assignment-tab-${activeAssignmentId}`}
              className="min-w-0"
            >
              <AssignmentOverview assignment={selectedAssignment} />
              {videoId ? (
                <Collapsible
                  key={selectedAssignment.id}
                  className="group mt-4 overflow-hidden rounded-lg border"
                >
                  <CollapsibleTrigger asChild>
                    <Button
                      type="button"
                      variant="ghost"
                      className="h-auto w-full justify-between rounded-none px-4 py-3"
                    >
                      <span className="flex items-center gap-2 font-medium">
                        <Images className="size-4 text-primary" />
                        Assigned issue images
                      </span>
                      <ChevronDown className="size-4 text-muted-foreground transition-transform group-data-[state=open]:rotate-180" />
                    </Button>
                  </CollapsibleTrigger>
                  <CollapsibleContent>
                    <div className="border-t p-4">
                      <TicketDetectionPreview
                        key={`${videoId}:${selectedAssignment.id}`}
                        ticketId={ticketId}
                        videoId={videoId}
                        assignmentId={selectedAssignment.id}
                      />
                    </div>
                  </CollapsibleContent>
                </Collapsible>
              ) : null}
            </div>
          </div>
        ) : (
          <div className="rounded-lg border border-dashed px-4 py-8 text-center">
            <p className="text-sm font-medium">No work assignments yet</p>
            <p className="mt-1 text-sm text-muted-foreground">
              Work assignments will appear here after issues are allocated.
            </p>
          </div>
        )}
      </CardContent>
    </Card>
  );
}
