"use client";

import { useState, useRef } from "react";
import { ChevronLeft, Upload, Trash2, Check, X } from "lucide-react";
import Link from "next/link";

interface ParsedSet {
  setNumber: number;
  weight?: number;
  weightUnit: string;
  reps?: number;
  notes?: string;
}

interface ParsedExercise {
  exerciseId: string;
  exerciseName: string;
  sets: ParsedSet[];
}

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

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

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 fileInputRef = 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 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,
        })
      );

      setWorkouts(initialWorkouts);
      setUnmapped(data.unmapped || []);
      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);

      // Transform workout to API format
      const setLogs = [];
      for (const exercise of currentWorkout.exercises) {
        for (const set of exercise.sets) {
          setLogs.push({
            exerciseId: exercise.exerciseId,
            setNumber: set.setNumber,
            weight: set.weight || null,
            weightUnit: set.weightUnit,
            reps: set.reps || null,
            notes: set.notes || null,
          });
        }
      }

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

      if (!response.ok) {
        throw new 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));
    }
  };

  // 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">
          {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, weight, reps, notes
                </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,weight,reps,notes
2025-02-15,Bench,225,5,good form
2025-02-15,Bench,225,5,
2025-02-15,Bench,225,3,
2025-02-16,Squat,315,8,30kg per leg
2025-02-16,Squat,315,6,`}
            </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 Warning */}
        {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 (not in your database):
            </p>
            <div className="flex flex-wrap gap-2">
              {unmapped.map((name) => (
                <span
                  key={name}
                  className="px-3 py-1 bg-yellow-900/30 border border-yellow-700 rounded text-sm text-yellow-200"
                >
                  {name}
                </span>
              ))}
            </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">
                  <h3 className="text-lg font-semibold text-white">
                    {exercise.exerciseName}
                  </h3>
                  <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}
              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>
  );
}
