"use client";

import { useState, useEffect } from "react";
import Link from "next/link";
import { Card } from "@/components/ui/Card";
import { Badge } from "@/components/ui/Badge";
import { VideoPlayer } from "@/components/workout/VideoPlayer";
import { api } from "@/lib/api";
import type {
  GeneratedWorkout,
  WorkoutDetail,
  Exercise,
  PreviewDay,
  PreviewExercise,
} from "@/lib/types";

interface DayCardProps {
  // Saved mode
  workout?: GeneratedWorkout;
  detail?: WorkoutDetail;
  onUpdate?: () => void;
  // Preview mode
  previewDay?: PreviewDay;
  previewDayIndex?: number;
  onPreviewDayChange?: (dayIndex: number, newDay: PreviewDay) => void;
}

function formatTime(seconds: number): string {
  const mins = Math.round(seconds / 60);
  if (mins < 60) return `${mins}m`;
  const h = Math.floor(mins / 60);
  const m = mins % 60;
  return m > 0 ? `${h}h ${m}m` : `${h}h`;
}

function EditIcon({ className = "" }: { className?: string }) {
  return (
    <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={className}>
      <path d="M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z" />
      <path d="m15 5 4 4" />
    </svg>
  );
}

function TrashIcon({ className = "" }: { className?: string }) {
  return (
    <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={className}>
      <path d="M3 6h18" />
      <path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6" />
      <path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2" />
    </svg>
  );
}

function XIcon({ className = "" }: { className?: string }) {
  return (
    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={className}>
      <path d="M18 6 6 18" />
      <path d="m6 6 12 12" />
    </svg>
  );
}

function mediaUrl(path: string): string {
  if (typeof window === "undefined") return path;
  return `${window.location.protocol}//${window.location.hostname}:8001${path}`;
}

function PlayIcon({ className = "" }: { className?: string }) {
  return (
    <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="currentColor" className={className}>
      <polygon points="5 3 19 12 5 21 5 3" />
    </svg>
  );
}

function VideoModal({ src, title, onClose }: { src: string; title: string; onClose: () => void }) {
  return (
    <div
      className="fixed inset-0 z-50 flex items-center justify-center bg-black/70"
      onClick={onClose}
    >
      <div
        className="bg-zinc-900 border border-zinc-700 rounded-xl p-4 w-full max-w-lg flex flex-col gap-3"
        onClick={(e) => e.stopPropagation()}
      >
        <div className="flex items-center justify-between">
          <h3 className="text-sm font-semibold text-zinc-100 truncate">{title}</h3>
          <button onClick={onClose} className="text-zinc-400 hover:text-zinc-100 p-1">
            <XIcon />
          </button>
        </div>
        <VideoPlayer src={src} />
      </div>
    </div>
  );
}

function RefreshIcon({ className = "" }: { className?: string }) {
  return (
    <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={className}>
      <path d="M21 12a9 9 0 0 0-9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" />
      <path d="M3 3v5h5" />
      <path d="M3 12a9 9 0 0 0 9 9 9.75 9.75 0 0 0 6.74-2.74L21 16" />
      <path d="M16 16h5v5" />
    </svg>
  );
}

// Swap exercise modal — works for both preview and saved mode
function SwapModal({
  exerciseId,
  currentName,
  onSwap,
  onClose,
}: {
  exerciseId: number;
  currentName: string;
  onSwap: (newExercise: Exercise) => void;
  onClose: () => void;
}) {
  const [alternatives, setAlternatives] = useState<Exercise[]>([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    api
      .getSimilarExercises(exerciseId)
      .then(setAlternatives)
      .catch((err) => console.error("Failed to load alternatives:", err))
      .finally(() => setLoading(false));
  }, [exerciseId]);

  return (
    <div
      className="fixed inset-0 z-50 flex items-center justify-center bg-black/60"
      onClick={onClose}
    >
      <div
        className="bg-zinc-900 border border-zinc-700 rounded-xl p-4 w-full max-w-md max-h-[70vh] flex flex-col"
        onClick={(e) => e.stopPropagation()}
      >
        <div className="flex items-center justify-between mb-3">
          <h3 className="text-sm font-semibold text-zinc-100">
            Replace: {currentName}
          </h3>
          <button onClick={onClose} className="text-zinc-400 hover:text-zinc-100 p-1">
            <XIcon />
          </button>
        </div>
        {loading ? (
          <div className="text-center text-zinc-400 text-sm py-8">Loading alternatives...</div>
        ) : alternatives.length === 0 ? (
          <div className="text-center text-zinc-400 text-sm py-8">No alternatives found.</div>
        ) : (
          <div className="flex flex-col gap-1 overflow-y-auto">
            {alternatives.map((ex) => (
              <button
                key={ex.id}
                className="text-left px-3 py-2 rounded-lg hover:bg-zinc-800 transition-colors text-sm text-zinc-200"
                onClick={() => onSwap(ex)}
              >
                {ex.name}
                {ex.muscle_groups && (
                  <span className="text-[10px] text-zinc-500 ml-2">
                    {ex.muscle_groups}
                  </span>
                )}
              </button>
            ))}
          </div>
        )}
      </div>
    </div>
  );
}

export function DayCard({
  workout,
  detail: externalDetail,
  onUpdate,
  previewDay,
  previewDayIndex,
  onPreviewDayChange,
}: DayCardProps) {
  const isPreview = !!previewDay;

  // Saved mode state
  const [deleting, setDeleting] = useState(false);
  const [fetchedDetail, setFetchedDetail] = useState<WorkoutDetail | null>(null);
  const [regenerating, setRegenerating] = useState(false);

  // Video preview modal state
  const [videoPreview, setVideoPreview] = useState<{ src: string; title: string } | null>(null);

  // Swap modal state
  const [swapTarget, setSwapTarget] = useState<{
    exerciseId: number;
    name: string;
    // For saved mode
    supersetExerciseId?: number;
    // For preview mode
    supersetIndex?: number;
    exerciseIndex?: number;
  } | null>(null);

  // Saved mode: fetch detail if not provided
  useEffect(() => {
    if (isPreview) return;
    if (externalDetail || !workout?.workout || workout.is_rest_day) return;
    let cancelled = false;
    api.getWorkoutDetail(workout.workout).then((data) => {
      if (!cancelled) setFetchedDetail(data);
    }).catch((err) => {
      console.error(`[DayCard] Failed to fetch detail for workout ${workout.workout}:`, err);
    });
    return () => { cancelled = true; };
  }, [isPreview, workout?.workout, workout?.is_rest_day, externalDetail]);

  const detail = externalDetail || fetchedDetail;

  // ============================================
  // Preview mode handlers
  // ============================================

  const handlePreviewDeleteDay = () => {
    if (previewDayIndex === undefined || !previewDay || !onPreviewDayChange) return;
    onPreviewDayChange(previewDayIndex, {
      ...previewDay,
      is_rest_day: true,
      focus_area: "Rest Day",
      target_muscles: [],
      workout_spec: undefined,
    });
  };

  const handlePreviewDeleteSuperset = (ssIdx: number) => {
    if (previewDayIndex === undefined || !previewDay?.workout_spec || !onPreviewDayChange) return;
    const newSupersets = previewDay.workout_spec.supersets.filter((_, i) => i !== ssIdx);
    onPreviewDayChange(previewDayIndex, {
      ...previewDay,
      workout_spec: { ...previewDay.workout_spec, supersets: newSupersets },
    });
  };

  const handlePreviewDeleteExercise = (ssIdx: number, exIdx: number) => {
    if (previewDayIndex === undefined || !previewDay?.workout_spec || !onPreviewDayChange) return;
    const newSupersets = previewDay.workout_spec.supersets.map((ss, i) => {
      if (i !== ssIdx) return ss;
      const newExercises = ss.exercises.filter((_, j) => j !== exIdx);
      return { ...ss, exercises: newExercises };
    }).filter((ss) => ss.exercises.length > 0);
    onPreviewDayChange(previewDayIndex, {
      ...previewDay,
      workout_spec: { ...previewDay.workout_spec, supersets: newSupersets },
    });
  };

  const handlePreviewSwapExercise = (ssIdx: number, exIdx: number, ex: PreviewExercise) => {
    setSwapTarget({
      exerciseId: ex.exercise_id,
      name: ex.exercise_name,
      supersetIndex: ssIdx,
      exerciseIndex: exIdx,
    });
  };

  const handlePreviewSwapConfirm = (newExercise: Exercise) => {
    if (!swapTarget || swapTarget.supersetIndex === undefined || swapTarget.exerciseIndex === undefined) return;
    if (previewDayIndex === undefined || !previewDay?.workout_spec || !onPreviewDayChange) return;

    const ssIdx = swapTarget.supersetIndex;
    const exIdx = swapTarget.exerciseIndex;

    const newSupersets = previewDay.workout_spec.supersets.map((ss, i) => {
      if (i !== ssIdx) return ss;
      const newExercises = ss.exercises.map((ex, j) => {
        if (j !== exIdx) return ex;
        return {
          ...ex,
          exercise_id: newExercise.id,
          exercise_name: newExercise.name,
          muscle_groups: newExercise.muscle_groups || "",
        };
      });
      return { ...ss, exercises: newExercises };
    });

    onPreviewDayChange(previewDayIndex, {
      ...previewDay,
      workout_spec: { ...previewDay.workout_spec, supersets: newSupersets },
    });
    setSwapTarget(null);
  };

  const handlePreviewRegenerate = async () => {
    if (previewDayIndex === undefined || !previewDay || !onPreviewDayChange) return;
    setRegenerating(true);
    try {
      const newDay = await api.previewDay({
        target_muscles: previewDay.target_muscles,
        focus_area: previewDay.focus_area,
        workout_type_id: previewDay.workout_type_id,
        date: previewDay.date,
      });
      onPreviewDayChange(previewDayIndex, newDay);
    } catch (err) {
      console.error("Failed to regenerate day:", err);
    } finally {
      setRegenerating(false);
    }
  };

  // ============================================
  // Saved mode handlers
  // ============================================

  const handleDeleteDay = async (e: React.MouseEvent) => {
    e.preventDefault();
    e.stopPropagation();
    if (!confirm("Remove this workout day?")) return;
    setDeleting(true);
    try {
      await api.deleteWorkoutDay(workout!.id);
      onUpdate?.();
    } catch (err) {
      console.error("Failed to delete day:", err);
    } finally {
      setDeleting(false);
    }
  };

  const handleDeleteSuperset = async (e: React.MouseEvent, supersetId: number) => {
    e.preventDefault();
    e.stopPropagation();
    try {
      await api.deleteSuperset(supersetId);
      onUpdate?.();
    } catch (err) {
      console.error("Failed to delete superset:", err);
    }
  };

  const handleDeleteExercise = async (e: React.MouseEvent, seId: number) => {
    e.preventDefault();
    e.stopPropagation();
    try {
      await api.deleteSupersetExercise(seId);
      onUpdate?.();
    } catch (err) {
      console.error("Failed to delete exercise:", err);
    }
  };

  const handleSavedSwapExercise = (seId: number, exerciseId: number, name: string) => (e: React.MouseEvent) => {
    e.preventDefault();
    e.stopPropagation();
    setSwapTarget({ supersetExerciseId: seId, exerciseId, name });
  };

  const handleSavedSwapConfirm = async (newExercise: Exercise) => {
    if (!swapTarget?.supersetExerciseId) return;
    try {
      await api.swapExercise(swapTarget.supersetExerciseId, newExercise.id);
      setSwapTarget(null);
      onUpdate?.();
    } catch (err) {
      console.error("Failed to swap exercise:", err);
    }
  };

  // ============================================
  // Render: Preview mode
  // ============================================

  if (isPreview && previewDay) {
    if (previewDay.is_rest_day) return null;

    const spec = previewDay.workout_spec;
    const typeName = previewDay.workout_type_name?.replace(/_/g, " ");

    return (
      <>
        <Card className="p-4 flex flex-col gap-3 relative">
          {/* Top-right actions */}
          <div className="absolute top-3 right-3 flex items-center gap-1 z-10">
            <button
              onClick={handlePreviewRegenerate}
              disabled={regenerating}
              className="p-1 rounded-md text-zinc-500 hover:text-[#39FF14] hover:bg-zinc-800 transition-colors"
              title="Regenerate this day"
            >
              <RefreshIcon className={regenerating ? "animate-spin" : ""} />
            </button>
            <button
              onClick={handlePreviewDeleteDay}
              className="p-1 rounded-md text-zinc-500 hover:text-red-400 hover:bg-zinc-800 transition-colors"
              title="Remove this day"
            >
              <XIcon />
            </button>
          </div>

          {/* Header */}
          <div className="flex items-start justify-between gap-2 pr-14">
            <div className="flex-1 min-w-0">
              {typeName && (
                <Badge variant="accent" className="text-[10px] capitalize mb-1.5">
                  {typeName}
                </Badge>
              )}
              {previewDay.focus_area && (
                <p className="text-sm font-semibold text-zinc-100 break-words">
                  {previewDay.focus_area}
                </p>
              )}
            </div>
            {spec?.estimated_time && (
              <span className="text-xs text-zinc-400 font-medium whitespace-nowrap mt-0.5">
                {formatTime(spec.estimated_time)}
              </span>
            )}
          </div>

          {/* Supersets */}
          {spec && spec.supersets.length > 0 && (
            <div className="flex flex-col gap-2">
              {spec.supersets.map((superset, si) => (
                <div key={si} className="bg-zinc-800/50 rounded-lg px-3 py-2 group/superset">
                  <div className="flex items-center justify-between mb-1">
                    <span className="text-[10px] font-semibold text-zinc-400 uppercase tracking-wider">
                      {superset.name}
                    </span>
                    <div className="flex items-center gap-1.5">
                      <span className="text-[10px] text-zinc-500">
                        {superset.rounds}x
                      </span>
                      <button
                        onClick={() => handlePreviewDeleteSuperset(si)}
                        className="p-0.5 rounded text-zinc-600 hover:text-red-400 opacity-0 group-hover/superset:opacity-100 transition-opacity"
                        title="Delete superset"
                      >
                        <TrashIcon />
                      </button>
                    </div>
                  </div>
                  <div className="flex flex-col gap-0.5">
                    {superset.exercises.map((ex, ei) => (
                      <div
                        key={ei}
                        className="flex items-center justify-between gap-1 group/exercise"
                      >
                        <div className="flex items-center gap-1 flex-1 min-w-0">
                          <span className="text-xs text-zinc-200 break-words">
                            {ex.exercise_name}
                          </span>
                          {ex.video_url && (
                            <button
                              onClick={() => setVideoPreview({ src: mediaUrl(ex.video_url!), title: ex.exercise_name })}
                              className="flex-shrink-0 p-0.5 rounded text-zinc-500 hover:text-[#39FF14] transition-colors"
                              title="Preview video"
                            >
                              <PlayIcon />
                            </button>
                          )}
                        </div>
                        <div className="flex items-center gap-1 shrink-0">
                          <span className="text-xs font-semibold text-[#39FF14] whitespace-nowrap">
                            {ex.reps ? `${ex.reps} reps` : ex.duration ? `${ex.duration}s` : ""}
                          </span>
                          <div className="flex items-center gap-0.5 opacity-0 group-hover/exercise:opacity-100 transition-opacity">
                            <button
                              onClick={() => handlePreviewSwapExercise(si, ei, ex)}
                              className="p-0.5 rounded text-zinc-500 hover:text-[#39FF14]"
                              title="Swap exercise"
                            >
                              <EditIcon />
                            </button>
                            <button
                              onClick={() => handlePreviewDeleteExercise(si, ei)}
                              className="p-0.5 rounded text-zinc-500 hover:text-red-400"
                              title="Delete exercise"
                            >
                              <TrashIcon />
                            </button>
                          </div>
                        </div>
                      </div>
                    ))}
                  </div>
                </div>
              ))}
            </div>
          )}

          {/* Muscle summary fallback */}
          {!spec && previewDay.target_muscles.length > 0 && (
            <p className="text-xs text-zinc-400 break-words">
              {previewDay.target_muscles.join(", ")}
            </p>
          )}
        </Card>

        {swapTarget && (
          <SwapModal
            exerciseId={swapTarget.exerciseId}
            currentName={swapTarget.name}
            onSwap={handlePreviewSwapConfirm}
            onClose={() => setSwapTarget(null)}
          />
        )}

        {videoPreview && (
          <VideoModal
            src={videoPreview.src}
            title={videoPreview.title}
            onClose={() => setVideoPreview(null)}
          />
        )}
      </>
    );
  }

  // ============================================
  // Render: Saved mode
  // ============================================

  if (!workout || workout.is_rest_day) return null;

  const typeName = workout.workout_type_name?.replace(/_/g, " ");
  const sortedSupersets = detail
    ? [...detail.supersets].sort((a, b) => a.order - b.order)
    : [];

  const cardContent = (
    <Card className="p-4 flex flex-col gap-3 relative">
      <button
        onClick={handleDeleteDay}
        disabled={deleting}
        className="absolute top-3 right-3 p-1 rounded-md text-zinc-500 hover:text-red-400 hover:bg-zinc-800 transition-colors z-10"
        title="Remove this day"
      >
        <XIcon />
      </button>

      <div className="flex items-start justify-between gap-2 pr-6">
        <div className="flex-1 min-w-0">
          {typeName && (
            <Badge variant="accent" className="text-[10px] capitalize mb-1.5">
              {typeName}
            </Badge>
          )}
          {workout.focus_area && (
            <p className="text-sm font-semibold text-zinc-100 break-words">
              {workout.focus_area}
            </p>
          )}
        </div>
        {detail?.estimated_time && (
          <span className="text-xs text-zinc-400 font-medium whitespace-nowrap mt-0.5">
            {formatTime(detail.estimated_time)}
          </span>
        )}
      </div>

      {sortedSupersets.length > 0 && (
        <div className="flex flex-col gap-2">
          {sortedSupersets.map((superset, si) => {
            const sortedExercises = [...superset.exercises].sort(
              (a, b) => a.order - b.order
            );
            return (
              <div key={superset.id ?? `s-${si}`} className="bg-zinc-800/50 rounded-lg px-3 py-2 group/superset">
                <div className="flex items-center justify-between mb-1">
                  <span className="text-[10px] font-semibold text-zinc-400 uppercase tracking-wider">
                    {superset.name || `Set ${superset.order}`}
                  </span>
                  <div className="flex items-center gap-1.5">
                    <span className="text-[10px] text-zinc-500">
                      {superset.rounds}x
                    </span>
                    {superset.id && (
                      <button
                        onClick={(e) => handleDeleteSuperset(e, superset.id)}
                        className="p-0.5 rounded text-zinc-600 hover:text-red-400 opacity-0 group-hover/superset:opacity-100 transition-opacity"
                        title="Delete superset"
                      >
                        <TrashIcon />
                      </button>
                    )}
                  </div>
                </div>
                <div className="flex flex-col gap-0.5">
                  {sortedExercises.map((se, ei) => (
                    <div
                      key={se.id ?? `e-${si}-${ei}`}
                      className="flex items-center justify-between gap-1 group/exercise"
                    >
                      <div className="flex items-center gap-1 flex-1 min-w-0">
                        <span className="text-xs text-zinc-200 break-words">
                          {se.exercise.name}
                        </span>
                        {se.exercise.video_url && (
                          <button
                            onClick={(e) => { e.preventDefault(); e.stopPropagation(); setVideoPreview({ src: mediaUrl(se.exercise.video_url), title: se.exercise.name }); }}
                            className="flex-shrink-0 p-0.5 rounded text-zinc-500 hover:text-[#39FF14] transition-colors"
                            title="Preview video"
                          >
                            <PlayIcon />
                          </button>
                        )}
                      </div>
                      <div className="flex items-center gap-1 shrink-0">
                        <span className="text-xs font-semibold text-[#39FF14] whitespace-nowrap">
                          {se.reps ? `${se.reps} reps` : se.duration ? `${se.duration}s` : ""}
                        </span>
                        {se.id && (
                          <div className="flex items-center gap-0.5 opacity-0 group-hover/exercise:opacity-100 transition-opacity">
                            <button
                              onClick={handleSavedSwapExercise(se.id, se.exercise.id, se.exercise.name)}
                              className="p-0.5 rounded text-zinc-500 hover:text-[#39FF14]"
                              title="Swap exercise"
                            >
                              <EditIcon />
                            </button>
                            <button
                              onClick={(e) => handleDeleteExercise(e, se.id)}
                              className="p-0.5 rounded text-zinc-500 hover:text-red-400"
                              title="Delete exercise"
                            >
                              <TrashIcon />
                            </button>
                          </div>
                        )}
                      </div>
                    </div>
                  ))}
                </div>
              </div>
            );
          })}
        </div>
      )}

      {!detail && workout.target_muscles.length > 0 && (
        <p className="text-xs text-zinc-400 break-words">
          {workout.target_muscles.join(", ")}
        </p>
      )}

      {/* Status badges for saved workouts */}
      {workout.status === "accepted" && (
        <div className="mt-auto pt-1">
          <Badge variant="success">Saved</Badge>
        </div>
      )}
      {workout.status === "completed" && (
        <div className="mt-auto pt-1">
          <Badge variant="accent">Completed</Badge>
        </div>
      )}
    </Card>
  );

  const modal = swapTarget ? (
    <SwapModal
      exerciseId={swapTarget.exerciseId}
      currentName={swapTarget.name}
      onSwap={handleSavedSwapConfirm}
      onClose={() => setSwapTarget(null)}
    />
  ) : null;

  const videoModal = videoPreview ? (
    <VideoModal
      src={videoPreview.src}
      title={videoPreview.title}
      onClose={() => setVideoPreview(null)}
    />
  ) : null;

  if (workout.workout) {
    return (
      <>
        <Link href={`/workout/${workout.workout}`} className="block">
          {cardContent}
        </Link>
        {modal}
        {videoModal}
      </>
    );
  }

  return (
    <>
      {cardContent}
      {modal}
      {videoModal}
    </>
  );
}
