/**
 * Sprint Progress Component
 *
 * Displays sprint overview with progress bar, issue stats, and burndown chart.
 */

'use client';

import { TrendingUp, Calendar } from 'lucide-react';
import { format } from 'date-fns';
import { cn } from '@/lib/utils';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import { Skeleton } from '@/components/ui/skeleton';
import { ProgressBar } from './ProgressBar';
import { BurndownChart } from './BurndownChart';
import type { Sprint, BurndownDataPoint } from './types';

// ============================================================================
// Types
// ============================================================================

interface SprintProgressProps {
  /** Current sprint data */
  sprint: Sprint | null;
  /** Burndown chart data */
  burndownData?: BurndownDataPoint[];
  /** List of available sprints for selector */
  availableSprints?: { id: string; name: string }[];
  /** Currently selected sprint ID */
  selectedSprintId?: string;
  /** Callback when sprint selection changes */
  onSprintChange?: (sprintId: string) => void;
  /** Whether data is loading */
  isLoading?: boolean;
  /** Additional CSS classes */
  className?: string;
}

// ============================================================================
// Helper Functions
// ============================================================================

function formatSprintDates(startDate?: string, endDate?: string): string {
  if (!startDate || !endDate) return 'Dates not set';
  try {
    const start = format(new Date(startDate), 'MMM d');
    const end = format(new Date(endDate), 'MMM d, yyyy');
    return `${start} - ${end}`;
  } catch {
    /* istanbul ignore next -- defensive catch for invalid date strings */
    return 'Invalid dates';
  }
}

function calculateProgress(sprint: Sprint): number {
  if (sprint.total_issues === 0) return 0;
  return Math.round((sprint.completed_issues / sprint.total_issues) * 100);
}

// ============================================================================
// Subcomponents
// ============================================================================

interface StatCardProps {
  value: number;
  label: string;
  colorClass: string;
}

function StatCard({ value, label, colorClass }: StatCardProps) {
  return (
    <div className="rounded-lg border p-3 text-center">
      <div className={cn('text-2xl font-bold', colorClass)}>{value}</div>
      <div className="text-xs text-muted-foreground">{label}</div>
    </div>
  );
}

function SprintProgressSkeleton() {
  return (
    <Card>
      <CardHeader>
        <div className="flex items-center justify-between">
          <div className="space-y-2">
            <Skeleton className="h-5 w-40" />
            <Skeleton className="h-4 w-56" />
          </div>
          <Skeleton className="h-9 w-32" />
        </div>
      </CardHeader>
      <CardContent>
        <div className="space-y-6">
          {/* Progress bar skeleton */}
          <div className="space-y-2">
            <div className="flex justify-between">
              <Skeleton className="h-4 w-24" />
              <Skeleton className="h-4 w-12" />
            </div>
            <Skeleton className="h-2 w-full rounded-full" />
          </div>

          {/* Stats grid skeleton */}
          <div className="grid grid-cols-2 gap-4 sm:grid-cols-4">
            {[1, 2, 3, 4].map((i) => (
              <div key={i} className="rounded-lg border p-3 text-center">
                <Skeleton className="mx-auto h-8 w-8" />
                <Skeleton className="mx-auto mt-1 h-3 w-16" />
              </div>
            ))}
          </div>

          {/* Burndown skeleton */}
          <div className="space-y-2">
            <Skeleton className="h-4 w-28" />
            <Skeleton className="h-32 w-full" />
          </div>
        </div>
      </CardContent>
    </Card>
  );
}

// ============================================================================
// Main Component
// ============================================================================

export function SprintProgress({
  sprint,
  burndownData = [],
  availableSprints = [],
  selectedSprintId,
  onSprintChange,
  isLoading = false,
  className,
}: SprintProgressProps) {
  if (isLoading) {
    return <SprintProgressSkeleton />;
  }

  if (!sprint) {
    return (
      <Card className={className} data-testid="sprint-progress">
        <CardHeader>
          <CardTitle className="flex items-center gap-2">
            <TrendingUp className="h-5 w-5" aria-hidden="true" />
            Sprint Overview
          </CardTitle>
          <CardDescription>No active sprint</CardDescription>
        </CardHeader>
        <CardContent>
          <div className="flex flex-col items-center justify-center py-8 text-center text-muted-foreground">
            <Calendar className="mb-2 h-8 w-8" aria-hidden="true" />
            <p className="text-sm">No sprint is currently active</p>
            <p className="mt-1 text-xs">Create a sprint to track progress</p>
          </div>
        </CardContent>
      </Card>
    );
  }

  const progress = calculateProgress(sprint);
  const dateRange = formatSprintDates(sprint.start_date, sprint.end_date);

  return (
    <Card className={className} data-testid="sprint-progress">
      <CardHeader>
        <div className="flex items-center justify-between">
          <div>
            <CardTitle className="flex items-center gap-2">
              <TrendingUp className="h-5 w-5" aria-hidden="true" />
              Sprint Overview
            </CardTitle>
            <CardDescription>
              {sprint.name} ({dateRange})
            </CardDescription>
          </div>

          {availableSprints.length > 1 && onSprintChange && (
            <Select value={selectedSprintId || sprint.id} onValueChange={onSprintChange}>
              <SelectTrigger className="w-32" aria-label="Select sprint">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                {availableSprints.map((s) => (
                  <SelectItem key={s.id} value={s.id}>
                    {s.name}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          )}
        </div>
      </CardHeader>
      <CardContent>
        <div className="space-y-6">
          {/* Sprint Progress */}
          <ProgressBar
            value={progress}
            showLabel
            aria-label={`Sprint progress: ${progress}% complete`}
          />

          {/* Issue Stats Grid */}
          <div
            className="grid grid-cols-2 gap-4 sm:grid-cols-4"
            role="list"
            aria-label="Sprint issue statistics"
          >
            <StatCard
              value={sprint.completed_issues}
              label="Completed"
              colorClass="text-green-600"
            />
            <StatCard
              value={sprint.in_progress_issues}
              label="In Progress"
              colorClass="text-blue-600"
            />
            <StatCard value={sprint.blocked_issues} label="Blocked" colorClass="text-red-600" />
            <StatCard value={sprint.todo_issues} label="To Do" colorClass="text-gray-600" />
          </div>

          {/* Burndown Chart */}
          <div>
            <h4 className="mb-2 text-sm font-medium">Burndown Chart</h4>
            <BurndownChart data={burndownData} height={120} />
          </div>
        </div>
      </CardContent>
    </Card>
  );
}
