"use client";

import { useMemo, useRef, useState } from "react";
import { ChevronLeft, Upload, Trash2, Check, X } from "lucide-react";
import Link from "next/link";
import { Exercise } from "@prisma/client";
import {
  deriveEquipmentOptions,
  deriveMuscleGroupOptions,
  deriveTrackingFieldOptions,
  displayLabel,
  normalizeValue,
  Option,
} from "@/lib/exerciseOptions";

interface ParsedSet {
  setNumber: number;
  weight?: number;
  weightUnit: string;
  reps?: number;
  durationSeconds?: number;
  distance?: number;
  distanceUnit?: string;
  calories?: number;
  rpe?: number;
  customMetrics?: Record<string, string>;
  notes?: string;
}

interface ParsedExercise {
  exerciseId: string;
  exerciseName: string;
  sourceName?: string;
  unmapped?: boolean;
  sets: ParsedSet[];
}

interface ParsedWorkout {
  date: string;
  exercises: ParsedExercise[];
}

interface WorkoutState extends ParsedWorkout {
  status: "pending" | "approved" | "skipped";
}

interface ExerciseOption {
  id: string;
  name: string;
}

interface NewExerciseDraft {
  name: string;
  type: string;
  muscleGroups: string[];
  inputFields: string[];
}

interface SeedExercisePayload {
  name: string;
  type?: string;
  muscleGroups?: string[];
  inputFields?: string[];
  defaultWeightUnit?: string | null;
}

export default function ImportCSVPage() {
  const [workouts, setWorkouts] = useState<WorkoutState[]>([]);
  const [currentIndex, setCurrentIndex] = useState(0);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [unmapped, setUnmapped] = useState<string[]>([]);
  const [exerciseLibrary, setExerciseLibrary] = useState<Exercise[]>([]);
  const [exerciseOptions, setExerciseOptions] = useState<ExerciseOption[]>([]);
  const [mapSelections, setMapSelections] = useState<Record<string, string>>({});
  const [createDrafts, setCreateDrafts] = useState<Record<string, NewExerciseDraft>>({});
  const [creatingFor, setCreatingFor] = useState<Record<string, boolean>>({});
  const [showCreateFor, setShowCreateFor] = useState<Record<string, boolean>>({});
  const [addingTypeFor, setAddingTypeFor] = useState<Record<string, boolean>>({});
  const [newTypeTextFor, setNewTypeTextFor] = useState<Record<string, string>>({});
  const [sessionTypes, setSessionTypes] = useState<Option[]>([]);
  const [addingMuscleFor, setAddingMuscleFor] = useState<Record<string, boolean>>({});
  const [newMuscleTextFor, setNewMuscleTextFor] = useState<Record<string, string>>({});
  const [sessionMuscles, setSessionMuscles] = useState<string[]>([]);
  const [addingFieldFor, setAddingFieldFor] = useState<Record<string, boolean>>({});
  const [newFieldTextFor, setNewFieldTextFor] = useState<Record<string, string>>({});
  const [sessionFields, setSessionFields] = useState<Option[]>([]);
  const [seedFile, setSeedFile] = useState<File | null>(null);
  const [seeding, setSeeding] = useState(false);
  const [seedResult, setSeedResult] = useState<{
    created: number;
    skipped: number;
    errors: Array<{ name: string; error: string }>;
  } | null>(null);
  const fileInputRef = useRef<HTMLInputElement>(null);
  const seedInputRef = useRef<HTMLInputElement>(null);

  const currentWorkout = workouts[currentIndex];
  const approved = workouts.filter((w) => w.status === "approved").length;
  const skipped = workouts.filter((w) => w.status === "skipped").length;
  const remaining = workouts.filter((w) => w.status === "pending").length;

  const equipmentOptions = useMemo(() => {
    const base = deriveEquipmentOptions(exerciseLibrary);
    const merged = [...base];
    for (const option of sessionTypes) {
      if (!merged.some((item) => item.value === option.value)) {
        merged.push(option);
      }
    }
    return merged;
  }, [exerciseLibrary, sessionTypes]);

  const muscleOptions = useMemo(() => {
    const base = deriveMuscleGroupOptions(exerciseLibrary);
    const merged = [...base];
    for (const muscle of sessionMuscles) {
      if (!merged.includes(muscle)) {
        merged.push(muscle);
      }
    }
    return merged;
  }, [exerciseLibrary, sessionMuscles]);

  const trackingOptions = useMemo(() => {
    const base = deriveTrackingFieldOptions(exerciseLibrary);
    const merged = [...base];
    for (const option of sessionFields) {
      if (!merged.some((item) => item.value === option.value)) {
        merged.push(option);
      }
    }
    return merged;
  }, [exerciseLibrary, sessionFields]);

  const getDefaultFieldsForType = (type: string): string[] => {
    if (type === "cardio") {
      return ["sets", "duration", "distance", "calories", "notes"];
    }
    if (type === "bodyweight") {
      return ["sets", "reps", "notes"];
    }
    return ["sets", "reps", "weight", "notes"];
  };

  const getUnresolvedInWorkout = (workout: WorkoutState): string[] => {
    const unresolved = workout.exercises
      .filter((exercise) => !exercise.exerciseId)
      .map((exercise) => exercise.sourceName || exercise.exerciseName);
    return Array.from(new Set(unresolved));
  };

  const applyExerciseResolution = (
    sourceName: string,
    resolvedExercise: { id: string; name: string }
  ) => {
    setWorkouts((prev) =>
      prev.map((workout) => ({
        ...workout,
        exercises: workout.exercises.map((exercise) => {
          const exerciseSource = exercise.sourceName || exercise.exerciseName;
          if (
            !exercise.exerciseId &&
            exerciseSource.toLowerCase() === sourceName.toLowerCase()
          ) {
            return {
              ...exercise,
              exerciseId: resolvedExercise.id,
              exerciseName: resolvedExercise.name,
              unmapped: false,
            };
          }
          return exercise;
        }),
      }))
    );

    setUnmapped((prev) =>
      prev.filter((name) => name.toLowerCase() !== sourceName.toLowerCase())
    );
    setMapSelections((prev) => {
      const next = { ...prev };
      delete next[sourceName];
      return next;
    });
    setShowCreateFor((prev) => {
      const next = { ...prev };
      delete next[sourceName];
      return next;
    });
  };

  const handleFileChange = async (
    event: React.ChangeEvent<HTMLInputElement>
  ) => {
    const file = event.target.files?.[0];
    if (!file) return;

    setLoading(true);
    setError(null);

    try {
      const formData = new FormData();
      formData.append("file", file);

      const response = await fetch("/api/import/parse", {
        method: "POST",
        body: formData,
      });

      if (!response.ok) {
        const data = await response.json();
        throw new Error(data.error || "Failed to parse CSV");
      }

      const data = await response.json();
      const initialWorkouts: WorkoutState[] = data.workouts.map(
        (w: ParsedWorkout) => ({
          ...w,
          status: "pending" as const,
        })
      );

      const exercisesResponse = await fetch("/api/exercises");
      if (!exercisesResponse.ok) {
        throw new Error("Failed to load exercise library");
      }
      const exercisesData = await exercisesResponse.json();
      const options: ExerciseOption[] = (exercisesData || []).map((exercise: any) => ({
        id: exercise.id,
        name: exercise.name,
      }));

      setWorkouts(initialWorkouts);
      setUnmapped(data.unmapped || []);
      setExerciseLibrary(exercisesData || []);
      setExerciseOptions(options);
      setMapSelections({});
      setShowCreateFor({});
      setCreatingFor({});
      setAddingTypeFor({});
      setNewTypeTextFor({});
      setSessionTypes([]);
      setAddingMuscleFor({});
      setNewMuscleTextFor({});
      setSessionMuscles([]);
      setAddingFieldFor({});
      setNewFieldTextFor({});
      setSessionFields([]);
      const initialDrafts: Record<string, NewExerciseDraft> = {};
      for (const name of data.unmapped || []) {
        initialDrafts[name] = {
          name,
          type: "other",
          muscleGroups: [],
          inputFields: ["sets", "reps", "weight", "notes"],
        };
      }
      setCreateDrafts(initialDrafts);
      setCurrentIndex(0);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to parse CSV");
    } finally {
      setLoading(false);
    }
  };

  const handleDragOver = (e: React.DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    e.stopPropagation();
  };

  const handleDrop = (e: React.DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    e.stopPropagation();

    const files = e.dataTransfer.files;
    if (files.length > 0) {
      const file = files[0];
      if (fileInputRef.current) {
        const dataTransfer = new DataTransfer();
        dataTransfer.items.add(file);
        fileInputRef.current.files = dataTransfer.files;

        const event = new Event("change", { bubbles: true });
        fileInputRef.current.dispatchEvent(event);
      }
    }
  };

  const updateSet = (
    exerciseIdx: number,
    setIdx: number,
    field: keyof ParsedSet,
    value: any
  ) => {
    if (!currentWorkout) return;

    const updatedWorkouts = [...workouts];
    const workout = updatedWorkouts[currentIndex];
    const set = workout.exercises[exerciseIdx].sets[setIdx];

    if (field === "setNumber") {
      set[field] = value ? parseInt(value, 10) : 0;
    } else if (field === "reps") {
      set[field] = value ? parseInt(value, 10) : undefined;
    } else if (field === "weight") {
      set[field] = value ? parseFloat(value) : undefined;
    } else {
      (set[field] as any) = value;
    }

    setWorkouts(updatedWorkouts);
  };

  const deleteSet = (exerciseIdx: number, setIdx: number) => {
    if (!currentWorkout) return;

    const updatedWorkouts = [...workouts];
    const workout = updatedWorkouts[currentIndex];
    const exercise = workout.exercises[exerciseIdx];

    // Remove the set
    exercise.sets.splice(setIdx, 1);

    // Renumber remaining sets
    exercise.sets.forEach((set, idx) => {
      set.setNumber = idx + 1;
    });

    // If no sets left, remove the exercise
    if (exercise.sets.length === 0) {
      workout.exercises.splice(exerciseIdx, 1);
    }

    setWorkouts(updatedWorkouts);
  };

  const deleteExercise = (exerciseIdx: number) => {
    if (!currentWorkout) return;

    const updatedWorkouts = [...workouts];
    const workout = updatedWorkouts[currentIndex];
    workout.exercises.splice(exerciseIdx, 1);

    setWorkouts(updatedWorkouts);
  };

  const approveWorkout = async () => {
    if (!currentWorkout) return;

    try {
      setLoading(true);
      setError(null);

      const unresolved = getUnresolvedInWorkout(currentWorkout);
      if (unresolved.length > 0) {
        throw new Error(
          `Resolve unmapped exercises before approving: ${unresolved.join(", ")}`
        );
      }

      // Transform workout to API format
      const setLogs = [];
      for (const exercise of currentWorkout.exercises) {
        for (const set of exercise.sets) {
          const payloadSet: any = {
            exerciseId: exercise.exerciseId,
            setNumber: set.setNumber,
            weightUnit: set.weightUnit,
          };

          if (typeof set.weight === "number" && !Number.isNaN(set.weight)) {
            payloadSet.weight = set.weight;
          }
          if (typeof set.reps === "number" && !Number.isNaN(set.reps)) {
            payloadSet.reps = set.reps;
          }
          if (typeof set.notes === "string" && set.notes.trim().length > 0) {
            payloadSet.notes = set.notes.trim();
          }
          if (
            typeof set.durationSeconds === "number" &&
            !Number.isNaN(set.durationSeconds)
          ) {
            payloadSet.durationSeconds = set.durationSeconds;
          }
          if (typeof set.distance === "number" && !Number.isNaN(set.distance)) {
            payloadSet.distance = set.distance;
            if (set.distanceUnit) payloadSet.distanceUnit = set.distanceUnit;
          }
          if (typeof set.calories === "number" && !Number.isNaN(set.calories)) {
            payloadSet.calories = set.calories;
          }
          if (typeof set.rpe === "number" && !Number.isNaN(set.rpe)) {
            payloadSet.rpe = set.rpe;
          }
          if (
            set.customMetrics &&
            typeof set.customMetrics === "object" &&
            Object.keys(set.customMetrics).length > 0
          ) {
            payloadSet.customMetrics = set.customMetrics;
          }

          setLogs.push(payloadSet);
        }
      }

      const response = await fetch("/api/workouts", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          date: currentWorkout.date,
          sets: setLogs,
        }),
      });

      if (!response.ok) {
        const data = await response.json().catch(() => null);
        throw new Error(data?.error || "Failed to save workout");
      }

      // Mark as approved and move to next
      const updatedWorkouts = [...workouts];
      updatedWorkouts[currentIndex].status = "approved";
      setWorkouts(updatedWorkouts);

      // Find next pending workout
      const nextPending = updatedWorkouts.findIndex(
        (w) => w.status === "pending"
      );
      if (nextPending !== -1) {
        setCurrentIndex(nextPending);
      } else {
        setCurrentIndex(currentIndex + 1);
      }
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to save workout");
    } finally {
      setLoading(false);
    }
  };

  const skipWorkout = () => {
    if (!currentWorkout) return;

    const updatedWorkouts = [...workouts];
    updatedWorkouts[currentIndex].status = "skipped";
    setWorkouts(updatedWorkouts);

    // Find next pending workout
    const nextPending = updatedWorkouts.findIndex(
      (w, idx) => w.status === "pending" && idx > currentIndex
    );
    if (nextPending !== -1) {
      setCurrentIndex(nextPending);
    } else {
      setCurrentIndex(currentIndex + 1);
    }
  };

  const deleteWorkout = () => {
    const updatedWorkouts = workouts.filter((_, idx) => idx !== currentIndex);
    setWorkouts(updatedWorkouts);

    if (updatedWorkouts.length > 0) {
      setCurrentIndex(Math.min(currentIndex, updatedWorkouts.length - 1));
    }
  };

  const handleSeedFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0] || null;
    setSeedFile(file);
    setSeedResult(null);
  };

  const applyExerciseSeed = async () => {
    if (!seedFile) {
      setError("Select a seed JSON file first.");
      return;
    }

    setSeeding(true);
    setError(null);
    setSeedResult(null);
    try {
      const text = await seedFile.text();
      const parsed = JSON.parse(text);
      const exercises: SeedExercisePayload[] = Array.isArray(parsed)
        ? parsed
        : Array.isArray(parsed?.exercises)
          ? parsed.exercises
          : [];

      if (exercises.length === 0) {
        throw new Error("Seed file has no exercises.");
      }

      const response = await fetch("/api/import/exercises/seed", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ exercises }),
      });
      const data = await response.json().catch(() => null);
      if (!response.ok) {
        throw new Error(data?.error || "Failed to import exercise seed.");
      }

      setSeedResult({
        created: data.created || 0,
        skipped: data.skipped || 0,
        errors: data.errors || [],
      });
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to apply exercise seed.");
    } finally {
      setSeeding(false);
    }
  };

  const handleMapToExisting = (sourceName: string) => {
    const selectedId = mapSelections[sourceName];
    if (!selectedId) {
      setError(`Select an exercise to map "${sourceName}" first`);
      return;
    }
    const selectedExercise = exerciseOptions.find((exercise) => exercise.id === selectedId);
    if (!selectedExercise) {
      setError("Selected exercise was not found");
      return;
    }
    applyExerciseResolution(sourceName, selectedExercise);
    setError(null);
  };

  const updateCreateDraft = (
    sourceName: string,
    updater: (draft: NewExerciseDraft) => NewExerciseDraft
  ) => {
    setCreateDrafts((prev) => {
      const existing = prev[sourceName] || {
        name: sourceName,
        type: "other",
        muscleGroups: [],
        inputFields: ["sets", "reps", "weight", "notes"],
      };
      return {
        ...prev,
        [sourceName]: updater(existing),
      };
    });
  };

  const commitTypeFor = (sourceName: string) => {
    const value = normalizeValue(newTypeTextFor[sourceName] || "");
    if (!value) {
      setAddingTypeFor((prev) => ({ ...prev, [sourceName]: false }));
      setNewTypeTextFor((prev) => ({ ...prev, [sourceName]: "" }));
      return;
    }
    if (!equipmentOptions.some((option) => option.value === value)) {
      setSessionTypes((prev) => [...prev, { value, label: displayLabel(value) }]);
    }
    updateCreateDraft(sourceName, (prev) => ({
      ...prev,
      type: value,
      inputFields: getDefaultFieldsForType(value),
    }));
    setAddingTypeFor((prev) => ({ ...prev, [sourceName]: false }));
    setNewTypeTextFor((prev) => ({ ...prev, [sourceName]: "" }));
  };

  const commitMuscleFor = (sourceName: string) => {
    const value = normalizeValue(newMuscleTextFor[sourceName] || "");
    if (!value) {
      setAddingMuscleFor((prev) => ({ ...prev, [sourceName]: false }));
      setNewMuscleTextFor((prev) => ({ ...prev, [sourceName]: "" }));
      return;
    }
    if (!muscleOptions.includes(value)) {
      setSessionMuscles((prev) => [...prev, value]);
    }
    updateCreateDraft(sourceName, (prev) => ({
      ...prev,
      muscleGroups: prev.muscleGroups.includes(value)
        ? prev.muscleGroups
        : [...prev.muscleGroups, value],
    }));
    setAddingMuscleFor((prev) => ({ ...prev, [sourceName]: false }));
    setNewMuscleTextFor((prev) => ({ ...prev, [sourceName]: "" }));
  };

  const commitFieldFor = (sourceName: string) => {
    const value = normalizeValue(newFieldTextFor[sourceName] || "");
    if (!value || value === "sets") {
      setAddingFieldFor((prev) => ({ ...prev, [sourceName]: false }));
      setNewFieldTextFor((prev) => ({ ...prev, [sourceName]: "" }));
      return;
    }
    if (!trackingOptions.some((option) => option.value === value)) {
      setSessionFields((prev) => [...prev, { value, label: displayLabel(value) }]);
    }
    updateCreateDraft(sourceName, (prev) => ({
      ...prev,
      inputFields: prev.inputFields.includes(value)
        ? prev.inputFields
        : [...prev.inputFields, value],
    }));
    setAddingFieldFor((prev) => ({ ...prev, [sourceName]: false }));
    setNewFieldTextFor((prev) => ({ ...prev, [sourceName]: "" }));
  };

  const createExerciseFromUnmapped = async (sourceName: string) => {
    const draft = createDrafts[sourceName];
    if (!draft?.name?.trim()) {
      setError(`Exercise name is required for "${sourceName}"`);
      return;
    }
    if (!draft.inputFields || draft.inputFields.length === 0) {
      setError(`Pick at least one tracked field for "${sourceName}"`);
      return;
    }

    setCreatingFor((prev) => ({ ...prev, [sourceName]: true }));
    setError(null);
    try {
      const response = await fetch("/api/exercises", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          name: draft.name.trim(),
          type: draft.type,
          muscleGroups: draft.muscleGroups,
          inputFields: draft.inputFields,
        }),
      });
      const data = await response.json().catch(() => null);
      if (!response.ok) {
        throw new Error(data?.error || "Failed to create exercise");
      }

      const createdExercise: ExerciseOption = {
        id: data.id,
        name: data.name,
      };
      setExerciseOptions((prev) =>
        [...prev, createdExercise].sort((a, b) => a.name.localeCompare(b.name))
      );
      setExerciseLibrary((prev) => [...prev, data as Exercise]);
      applyExerciseResolution(sourceName, createdExercise);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to create exercise");
    } finally {
      setCreatingFor((prev) => ({ ...prev, [sourceName]: false }));
    }
  };

  // Upload step
  if (workouts.length === 0) {
    return (
      <div className="min-h-screen bg-[#0A0A0A] pb-24 md:pb-8">
        {/* Header */}
        <div className="border-b border-zinc-800 sticky top-0 z-40 bg-[#0A0A0A]">
          <div className="max-w-4xl mx-auto px-4 py-4 flex items-center gap-4">
            <Link
              href="/main/workouts"
              className="p-2 hover:bg-zinc-900 rounded-lg -ml-2 text-zinc-400 hover:text-white"
              aria-label="Back"
            >
              <ChevronLeft className="w-6 h-6" />
            </Link>
            <h1 className="text-2xl font-display text-white tracking-wider">
              Import Workouts
            </h1>
          </div>
        </div>

        {/* Upload Area */}
        <div className="max-w-4xl mx-auto px-4 py-12">
          <div className="mb-6 p-4 bg-zinc-900 border border-zinc-800 rounded-lg">
            <h3 className="text-sm font-semibold text-white mb-2">
              Optional: Pre-create missing exercises from seed JSON
            </h3>
            <p className="text-xs text-zinc-500 mb-3">
              Use this first if your historical file references exercises not in your library.
            </p>

            {seedResult && (
              <div className="mb-3 text-xs rounded border border-zinc-700 bg-zinc-950 p-3 text-zinc-300">
                <p>
                  Created: {seedResult.created} · Skipped existing: {seedResult.skipped}
                </p>
                {seedResult.errors.length > 0 && (
                  <p className="text-yellow-400 mt-1">
                    Errors: {seedResult.errors.length} (first: {seedResult.errors[0].name})
                  </p>
                )}
              </div>
            )}

            <div className="flex flex-col sm:flex-row gap-2">
              <input
                ref={seedInputRef}
                type="file"
                accept=".json"
                onChange={handleSeedFileChange}
                className="hidden"
              />
              <button
                type="button"
                onClick={() => seedInputRef.current?.click()}
                className="px-4 py-2 bg-zinc-800 border border-zinc-700 text-sm text-zinc-200 rounded hover:bg-zinc-700"
              >
                {seedFile ? `Selected: ${seedFile.name}` : "Select Seed JSON"}
              </button>
              <button
                type="button"
                onClick={applyExerciseSeed}
                disabled={seeding || !seedFile}
                className="px-4 py-2 bg-white text-black text-sm font-semibold rounded hover:bg-zinc-200 disabled:opacity-50"
              >
                {seeding ? "Creating..." : "Create Missing Exercises"}
              </button>
            </div>
          </div>

          {error && (
            <div className="mb-6 p-4 bg-red-900/20 border border-red-800 rounded-lg">
              <p className="text-red-200">{error}</p>
              <button
                onClick={() => setError(null)}
                className="mt-2 text-sm text-red-300 hover:text-red-200"
              >
                Dismiss
              </button>
            </div>
          )}

          <div className="bg-zinc-900 rounded-lg p-12 border-2 border-dashed border-zinc-700 hover:border-zinc-600 transition-colors cursor-pointer"
            onDragOver={handleDragOver}
            onDrop={handleDrop}
            onClick={() => fileInputRef.current?.click()}
          >
            <input
              ref={fileInputRef}
              type="file"
              accept=".csv"
              onChange={handleFileChange}
              className="hidden"
            />

            <div className="flex flex-col items-center gap-4">
              <div className="p-4 bg-zinc-800 rounded-lg">
                <Upload className="w-8 h-8 text-zinc-400" />
              </div>
              <div className="text-center">
                <h2 className="text-xl font-semibold text-white mb-2">
                  Upload CSV File
                </h2>
                <p className="text-zinc-400 mb-4">
                  Drag and drop your CSV file here or click to select
                </p>
                <p className="text-sm text-zinc-500">
                  CSV columns: date, exercise, set, weight, reps, duration_seconds,
                  distance, distance_unit, calories, rpe, notes, custom_*
                </p>
              </div>
              {loading && (
                <p className="text-zinc-400 text-sm">Parsing CSV...</p>
              )}
            </div>
          </div>

          {/* Example Format */}
          <div className="mt-12 bg-zinc-900 rounded-lg p-6 border border-zinc-800">
            <h3 className="text-lg font-semibold text-white mb-4">
              CSV Format Example
            </h3>
            <pre className="text-xs text-zinc-400 overflow-x-auto bg-zinc-950 p-4 rounded border border-zinc-800">
              {`date,exercise,set,weight,weight_unit,reps,duration_seconds,distance,distance_unit,calories,rpe,notes,custom_temperature,custom_watts,custom_metrics_json
2025-02-15,Bench,1,225,lbs,5,,,,,8,good form,,,
2025-02-15,Bench,2,225,lbs,5,,,,,8,,,,
2025-02-16,Squat,1,315,lbs,8,,,,,9,30kg per leg,,,
2025-02-17,Assault Bike,1,,, ,900,5,mi,120,7,,,"{\"resistance\":\"8\"}"
2025-02-18,Cold Plunge,1,,, ,180,,,,,felt great,50,,`}
            </pre>
          </div>
        </div>
      </div>
    );
  }

  // Review step
  if (!currentWorkout) {
    return (
      <div className="min-h-screen bg-[#0A0A0A] pb-24 md:pb-8">
        <div className="border-b border-zinc-800 sticky top-0 z-40 bg-[#0A0A0A]">
          <div className="max-w-4xl mx-auto px-4 py-4 flex items-center gap-4">
            <Link
              href="/main/workouts"
              className="p-2 hover:bg-zinc-900 rounded-lg -ml-2 text-zinc-400 hover:text-white"
              aria-label="Back"
            >
              <ChevronLeft className="w-6 h-6" />
            </Link>
            <h1 className="text-2xl font-display text-white tracking-wider">
              Import Complete
            </h1>
          </div>
        </div>

        <div className="max-w-4xl mx-auto px-4 py-12">
          <div className="bg-zinc-900 rounded-lg p-8 border border-zinc-800 text-center">
            <Check className="w-12 h-12 text-green-500 mx-auto mb-4" />
            <h2 className="text-2xl font-semibold text-white mb-2">
              All Done!
            </h2>
            <p className="text-zinc-400 mb-6">
              {approved} workouts approved, {skipped} skipped
            </p>
            <Link
              href="/main/workouts"
              className="inline-block px-6 py-2 bg-white text-black font-semibold rounded-lg hover:bg-zinc-200 transition-colors"
            >
              View Workouts
            </Link>
          </div>
        </div>
      </div>
    );
  }

  return (
    <div className="min-h-screen bg-[#0A0A0A] pb-24 md:pb-8">
      {/* Header */}
      <div className="border-b border-zinc-800 sticky top-0 z-40 bg-[#0A0A0A]">
        <div className="max-w-4xl mx-auto px-4 py-4">
          <div className="flex items-center justify-between mb-4">
            <div className="flex items-center gap-4">
              <button
                onClick={() => setWorkouts([])}
                className="p-2 hover:bg-zinc-900 rounded-lg -ml-2 text-zinc-400 hover:text-white"
                aria-label="Back"
              >
                <ChevronLeft className="w-6 h-6" />
              </button>
              <h1 className="text-2xl font-display text-white tracking-wider">
                Review Workouts
              </h1>
            </div>
          </div>

          {/* Progress Bar */}
          <div className="space-y-2">
            <div className="flex justify-between text-sm">
              <span className="text-zinc-400">
                {approved} approved, {skipped} skipped, {remaining} remaining
              </span>
              <span className="text-zinc-500">
                {currentIndex + 1} of {workouts.length}
              </span>
            </div>
            <div className="w-full bg-zinc-800 h-2 rounded-full overflow-hidden">
              <div
                className="h-full bg-white transition-all duration-300"
                style={{
                  width: `${((approved + skipped) / workouts.length) * 100}%`,
                }}
              />
            </div>
          </div>
        </div>
      </div>

      {/* Content */}
      <div className="max-w-4xl mx-auto px-4 py-6">
        {error && (
          <div className="mb-6 p-4 bg-red-900/20 border border-red-800 rounded-lg">
            <p className="text-red-200">{error}</p>
          </div>
        )}

        {/* Unmapped Exercises Resolution */}
        {unmapped.length > 0 && (
          <div className="mb-6 p-4 bg-yellow-900/20 border border-yellow-800 rounded-lg">
            <p className="text-yellow-200 font-semibold mb-2">
              Unmapped exercises (resolve each one before approval):
            </p>
            <div className="space-y-4">
              {unmapped.map((name) => {
                const draft = createDrafts[name] || {
                  name,
                  type: "other",
                  muscleGroups: [],
                  inputFields: ["sets", "reps", "weight", "notes"],
                };
                const isCreating = !!creatingFor[name];
                const createOpen = !!showCreateFor[name];
                return (
                  <div
                    key={name}
                    className="bg-yellow-900/15 border border-yellow-700/50 rounded-lg p-3"
                  >
                    <p className="text-yellow-100 text-sm font-semibold mb-3">{name}</p>

                    <div className="flex flex-col gap-2 sm:flex-row sm:items-center">
                      <select
                        value={mapSelections[name] || ""}
                        onChange={(e) =>
                          setMapSelections((prev) => ({ ...prev, [name]: e.target.value }))
                        }
                        className="flex-1 bg-zinc-900 border border-zinc-700 rounded px-3 py-2 text-sm text-white"
                      >
                        <option value="">Map to existing exercise...</option>
                        {exerciseOptions.map((option) => (
                          <option key={option.id} value={option.id}>
                            {option.name}
                          </option>
                        ))}
                      </select>
                      <button
                        type="button"
                        onClick={() => handleMapToExisting(name)}
                        className="px-3 py-2 bg-zinc-800 border border-zinc-700 text-white text-sm rounded hover:bg-zinc-700 transition"
                      >
                        Map
                      </button>
                      <button
                        type="button"
                        onClick={() =>
                          setShowCreateFor((prev) => ({ ...prev, [name]: !prev[name] }))
                        }
                        className="px-3 py-2 bg-white text-black text-sm rounded hover:bg-zinc-200 transition"
                      >
                        {createOpen ? "Hide Create" : "Create New"}
                      </button>
                    </div>

                    {createOpen && (
                      <div className="mt-3 space-y-3 bg-zinc-900/80 border border-zinc-700 rounded-lg p-3">
                        <div>
                          <label className="block text-xs text-zinc-400 mb-1">Exercise Name</label>
                          <input
                            type="text"
                            value={draft.name}
                            onChange={(e) =>
                              updateCreateDraft(name, (prev) => ({
                                ...prev,
                                name: e.target.value,
                              }))
                            }
                            className="w-full bg-zinc-800 border border-zinc-700 rounded px-3 py-2 text-sm text-white"
                          />
                        </div>

                        <div>
                          <label className="block text-xs text-zinc-400 mb-1">Equipment Type</label>
                          <div className="flex flex-wrap gap-2">
                            {equipmentOptions.map((option) => (
                              <button
                                key={option.value}
                                type="button"
                                onClick={() =>
                                  updateCreateDraft(name, (prev) => ({
                                    ...prev,
                                    type: option.value,
                                    inputFields: getDefaultFieldsForType(option.value),
                                  }))
                                }
                                className={`px-2.5 py-1 rounded text-xs font-medium transition ${
                                  draft.type === option.value
                                    ? "bg-white text-black"
                                    : "bg-zinc-800 text-zinc-300"
                                }`}
                              >
                                {option.label}
                              </button>
                            ))}
                            {addingTypeFor[name] ? (
                              <input
                                autoFocus
                                value={newTypeTextFor[name] || ""}
                                onChange={(e) =>
                                  setNewTypeTextFor((prev) => ({
                                    ...prev,
                                    [name]: e.target.value,
                                  }))
                                }
                                onBlur={() => commitTypeFor(name)}
                                onKeyDown={(e) => {
                                  if (e.key === "Enter") {
                                    e.preventDefault();
                                    commitTypeFor(name);
                                  }
                                }}
                                placeholder="New"
                                className="w-20 px-2 py-1 rounded text-xs bg-zinc-800 border border-zinc-600 text-white"
                              />
                            ) : (
                              <button
                                type="button"
                                onClick={() =>
                                  setAddingTypeFor((prev) => ({ ...prev, [name]: true }))
                                }
                                className="px-2.5 py-1 rounded text-xs font-medium bg-zinc-800 text-zinc-400 border border-dashed border-zinc-600"
                              >
                                +
                              </button>
                            )}
                          </div>
                        </div>

                        <div>
                          <label className="block text-xs text-zinc-400 mb-1">
                            Tracking Fields
                          </label>
                          <div className="flex flex-wrap gap-2">
                            {trackingOptions.map((field) => {
                              const active = draft.inputFields.includes(field.value);
                              return (
                                <button
                                  key={field.value}
                                  type="button"
                                  onClick={() =>
                                    updateCreateDraft(name, (prev) => ({
                                      ...prev,
                                      inputFields: field.value === "sets"
                                        ? prev.inputFields
                                        : active
                                        ? prev.inputFields.filter((value) => value !== field.value)
                                        : [...prev.inputFields, field.value],
                                    }))
                                  }
                                  className={`px-2.5 py-1 rounded text-xs font-medium transition ${
                                    active
                                      ? "bg-white text-black"
                                      : "bg-zinc-800 text-zinc-300"
                                  }`}
                                >
                                  {field.label}
                                </button>
                              );
                            })}
                            {addingFieldFor[name] ? (
                              <input
                                autoFocus
                                value={newFieldTextFor[name] || ""}
                                onChange={(e) =>
                                  setNewFieldTextFor((prev) => ({
                                    ...prev,
                                    [name]: e.target.value,
                                  }))
                                }
                                onBlur={() => commitFieldFor(name)}
                                onKeyDown={(e) => {
                                  if (e.key === "Enter") {
                                    e.preventDefault();
                                    commitFieldFor(name);
                                  }
                                }}
                                placeholder="New"
                                className="w-20 px-2 py-1 rounded text-xs bg-zinc-800 border border-zinc-600 text-white"
                              />
                            ) : (
                              <button
                                type="button"
                                onClick={() =>
                                  setAddingFieldFor((prev) => ({ ...prev, [name]: true }))
                                }
                                className="px-2.5 py-1 rounded text-xs font-medium bg-zinc-800 text-zinc-400 border border-dashed border-zinc-600"
                              >
                                +
                              </button>
                            )}
                          </div>
                        </div>

                        <div>
                          <label className="block text-xs text-zinc-400 mb-1">Muscle Groups</label>
                          <div className="flex flex-wrap gap-2">
                            {muscleOptions.map((group) => {
                              const active = draft.muscleGroups.includes(group);
                              return (
                                <button
                                  key={group}
                                  type="button"
                                  onClick={() =>
                                    updateCreateDraft(name, (prev) => ({
                                      ...prev,
                                      muscleGroups: active
                                        ? prev.muscleGroups.filter((value) => value !== group)
                                        : [...prev.muscleGroups, group],
                                    }))
                                  }
                                  className={`px-2.5 py-1 rounded text-xs font-medium transition ${
                                    active
                                      ? "bg-white text-black"
                                      : "bg-zinc-800 text-zinc-300"
                                  }`}
                                >
                                  {displayLabel(group)}
                                </button>
                              );
                            })}
                            {addingMuscleFor[name] ? (
                              <input
                                autoFocus
                                value={newMuscleTextFor[name] || ""}
                                onChange={(e) =>
                                  setNewMuscleTextFor((prev) => ({
                                    ...prev,
                                    [name]: e.target.value,
                                  }))
                                }
                                onBlur={() => commitMuscleFor(name)}
                                onKeyDown={(e) => {
                                  if (e.key === "Enter") {
                                    e.preventDefault();
                                    commitMuscleFor(name);
                                  }
                                }}
                                placeholder="New"
                                className="w-20 px-2 py-1 rounded text-xs bg-zinc-800 border border-zinc-600 text-white"
                              />
                            ) : (
                              <button
                                type="button"
                                onClick={() =>
                                  setAddingMuscleFor((prev) => ({ ...prev, [name]: true }))
                                }
                                className="px-2.5 py-1 rounded text-xs font-medium bg-zinc-800 text-zinc-400 border border-dashed border-zinc-600"
                              >
                                +
                              </button>
                            )}
                          </div>
                        </div>

                        <button
                          type="button"
                          onClick={() => createExerciseFromUnmapped(name)}
                          disabled={isCreating}
                          className="w-full py-2 bg-white text-black text-sm font-semibold rounded hover:bg-zinc-200 disabled:opacity-50"
                        >
                          {isCreating ? "Creating..." : "Create and Map"}
                        </button>
                      </div>
                    )}
                  </div>
                );
              })}
            </div>
          </div>
        )}

        {/* Workout Card */}
        <div className="bg-zinc-900 rounded-lg border border-zinc-800 overflow-hidden">
          {/* Date Header */}
          <div className="bg-zinc-800 px-6 py-4 border-b border-zinc-700">
            <h2 className="text-xl font-semibold text-white">
              {new Date(currentWorkout.date).toLocaleDateString("en-US", {
                weekday: "long",
                year: "numeric",
                month: "long",
                day: "numeric",
              })}
            </h2>
          </div>

          {/* Exercises */}
          <div className="divide-y divide-zinc-800">
            {currentWorkout.exercises.map((exercise, exIdx) => (
              <div key={exIdx} className="p-6">
                <div className="flex items-center justify-between mb-4">
                  <div className="flex items-center gap-2">
                    <h3 className="text-lg font-semibold text-white">
                      {exercise.exerciseName}
                    </h3>
                    {!exercise.exerciseId && (
                      <span className="px-2 py-0.5 text-[11px] rounded bg-yellow-900/30 border border-yellow-700 text-yellow-200">
                        unresolved
                      </span>
                    )}
                  </div>
                  <button
                    onClick={() => deleteExercise(exIdx)}
                    className="p-2 hover:bg-zinc-800 rounded text-zinc-400 hover:text-red-400 transition-colors"
                  >
                    <Trash2 className="w-5 h-5" />
                  </button>
                </div>

                {/* Sets Table */}
                <div className="overflow-x-auto">
                  <table className="w-full text-sm">
                    <thead>
                      <tr className="border-b border-zinc-700">
                        <th className="text-left py-2 px-3 text-zinc-400 font-medium">
                          Set
                        </th>
                        <th className="text-left py-2 px-3 text-zinc-400 font-medium">
                          Weight
                        </th>
                        <th className="text-left py-2 px-3 text-zinc-400 font-medium">
                          Unit
                        </th>
                        <th className="text-left py-2 px-3 text-zinc-400 font-medium">
                          Reps
                        </th>
                        <th className="text-left py-2 px-3 text-zinc-400 font-medium">
                          Notes
                        </th>
                        <th className="text-right py-2 px-3 text-zinc-400 font-medium">
                          Action
                        </th>
                      </tr>
                    </thead>
                    <tbody className="divide-y divide-zinc-800">
                      {exercise.sets.map((set, setIdx) => (
                        <tr key={setIdx}>
                          <td className="py-3 px-3">
                            <input
                              type="number"
                              min="1"
                              value={set.setNumber}
                              onChange={(e) =>
                                updateSet(exIdx, setIdx, "setNumber", e.target.value)
                              }
                              className="w-12 bg-zinc-800 border border-zinc-700 rounded px-2 py-1 text-white text-center"
                            />
                          </td>
                          <td className="py-3 px-3">
                            <input
                              type="number"
                              step="0.5"
                              placeholder="—"
                              value={set.weight || ""}
                              onChange={(e) =>
                                updateSet(exIdx, setIdx, "weight", e.target.value)
                              }
                              className="w-20 bg-zinc-800 border border-zinc-700 rounded px-2 py-1 text-white"
                            />
                          </td>
                          <td className="py-3 px-3">
                            <select
                              value={set.weightUnit}
                              onChange={(e) =>
                                updateSet(
                                  exIdx,
                                  setIdx,
                                  "weightUnit",
                                  e.target.value
                                )
                              }
                              className="bg-zinc-800 border border-zinc-700 rounded px-2 py-1 text-white text-sm"
                            >
                              <option>lbs</option>
                              <option>kg</option>
                            </select>
                          </td>
                          <td className="py-3 px-3">
                            <input
                              type="number"
                              min="1"
                              placeholder="—"
                              value={set.reps || ""}
                              onChange={(e) =>
                                updateSet(exIdx, setIdx, "reps", e.target.value)
                              }
                              className="w-16 bg-zinc-800 border border-zinc-700 rounded px-2 py-1 text-white"
                            />
                          </td>
                          <td className="py-3 px-3">
                            <input
                              type="text"
                              placeholder="—"
                              value={set.notes || ""}
                              onChange={(e) =>
                                updateSet(exIdx, setIdx, "notes", e.target.value)
                              }
                              className="flex-1 bg-zinc-800 border border-zinc-700 rounded px-2 py-1 text-white text-sm"
                            />
                          </td>
                          <td className="py-3 px-3 text-right">
                            <button
                              onClick={() => deleteSet(exIdx, setIdx)}
                              className="p-1 hover:bg-zinc-800 rounded text-zinc-400 hover:text-red-400 transition-colors"
                            >
                              <X className="w-4 h-4" />
                            </button>
                          </td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
              </div>
            ))}
          </div>
        </div>

        {/* Action Buttons */}
        <div className="mt-6 flex gap-3 justify-between">
          <button
            onClick={deleteWorkout}
            className="px-4 py-2 bg-red-900/20 border border-red-800 text-red-200 rounded-lg hover:bg-red-900/30 transition-colors font-medium"
          >
            Delete Workout
          </button>

          <div className="flex gap-3">
            <button
              onClick={skipWorkout}
              disabled={loading}
              className="px-6 py-2 bg-zinc-800 border border-zinc-700 text-white rounded-lg hover:bg-zinc-700 transition-colors font-medium disabled:opacity-50"
            >
              Skip
            </button>
            <button
              onClick={approveWorkout}
              disabled={
                loading ||
                currentWorkout.exercises.length === 0 ||
                getUnresolvedInWorkout(currentWorkout).length > 0
              }
              className="px-6 py-2 bg-white text-black rounded-lg hover:bg-zinc-200 transition-colors font-medium disabled:opacity-50 flex items-center gap-2"
            >
              {loading ? "Saving..." : "Approve"}
              <Check className="w-4 h-4" />
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}
