"use client";

import { Trash2, Check, Pencil, CornerDownLeft } from "lucide-react";
import { useState, useCallback } from "react";

export type InputField =
  | "sets"
  | "reps"
  | "weight"
  | "duration"
  | "distance"
  | "calories"
  | "notes"
  | string;

export interface SetRowProps {
  setNumber: number;
  inputFields?: InputField[];
  weightUnit?: string;
  initialReps?: number;
  initialWeight?: number;
  initialRpe?: number;
  initialNotes?: string;
  initialDuration?: number;
  initialDistance?: number;
  initialCalories?: number;
  initialCustomMetrics?: Record<string, string>;
  initialLocked?: boolean;
  autoFocus?: boolean;
  onUpdate: (data: {
    reps?: number;
    weight?: number;
    rpe?: number;
    notes?: string;
    durationSeconds?: number;
    distance?: number;
    calories?: number;
    customMetrics?: Record<string, string>;
  }) => void;
  onConfirm?: () => void;
  onNextSet?: (currentValues: {
    weight?: string;
    reps?: string;
    rpe?: string;
    notes?: string;
    duration?: string;
    distance?: string;
    calories?: string;
  }) => void;
  onDelete: () => void;
}

export default function SetRow({
  setNumber,
  inputFields = ["sets", "reps", "weight"],
  weightUnit = "lbs",
  initialReps,
  initialWeight,
  initialRpe,
  initialNotes,
  initialDuration,
  initialDistance,
  initialCalories,
  initialCustomMetrics,
  initialLocked = false,
  autoFocus = false,
  onUpdate,
  onConfirm,
  onNextSet,
  onDelete,
}: SetRowProps) {
  const secondsToMinuteString = (seconds?: number) => {
    if (seconds === undefined || seconds === null) return "";
    const minutes = seconds / 60;
    const rounded = Math.round(minutes * 10) / 10;
    return Number.isInteger(rounded) ? String(Math.trunc(rounded)) : String(rounded);
  };

  const minuteStringToSeconds = (minutes: string) => {
    if (!minutes) return undefined;
    const parsed = parseFloat(minutes);
    if (!Number.isFinite(parsed) || parsed <= 0) return undefined;
    return Math.round(parsed * 60);
  };

  const [reps, setReps] = useState(initialReps?.toString() || "");
  const [weight, setWeight] = useState(initialWeight?.toString() || "");
  const [rpe, setRpe] = useState(initialRpe?.toString() || "");
  const [notes, setNotes] = useState(initialNotes || "");
  const [duration, setDuration] = useState(secondsToMinuteString(initialDuration));
  const [distance, setDistance] = useState(initialDistance?.toString() || "");
  const [calories, setCalories] = useState(initialCalories?.toString() || "");
  const [customValues, setCustomValues] = useState<Record<string, string>>(
    initialCustomMetrics || {}
  );
  const [showNotes, setShowNotes] = useState(!!initialNotes);
  const [locked, setLocked] = useState(initialLocked);

  const showReps = inputFields.includes("reps");
  const showWeight = inputFields.includes("weight");
  const showDuration = inputFields.includes("duration");
  const showDistance = inputFields.includes("distance");
  const showCalories = inputFields.includes("calories");
  const showNotesField = inputFields.includes("notes");
  const customFields = inputFields.filter(
    (f) =>
      ![
        "sets",
        "reps",
        "weight",
        "duration",
        "distance",
        "calories",
        "notes",
      ].includes(f)
  );

  const emitUpdate = useCallback(
    (overrides: {
      reps?: string;
      weight?: string;
      rpe?: string;
      notes?: string;
      duration?: string;
      distance?: string;
      calories?: string;
      customMetrics?: Record<string, string>;
    }) => {
      const r = overrides.reps ?? reps;
      const w = overrides.weight ?? weight;
      const p = overrides.rpe ?? rpe;
      const n = overrides.notes ?? notes;
      const dur = overrides.duration ?? duration;
      const dist = overrides.distance ?? distance;
      const cal = overrides.calories ?? calories;
      const cm = overrides.customMetrics ?? customValues;
      const cleanedCustomMetrics = Object.fromEntries(
        Object.entries(cm).filter(([, value]) => value !== "")
      );

      onUpdate({
        reps: r ? parseInt(r) : undefined,
        weight: w ? parseFloat(w) : undefined,
        rpe: p ? parseInt(p) : undefined,
        notes: n || undefined,
        durationSeconds: minuteStringToSeconds(dur),
        distance: dist ? parseFloat(dist) : undefined,
        calories: cal ? parseInt(cal) : undefined,
        customMetrics:
          Object.keys(cleanedCustomMetrics).length > 0
            ? cleanedCustomMetrics
            : undefined,
      });
    },
    [reps, weight, rpe, notes, duration, distance, calories, customValues, onUpdate]
  );

  const handleConfirm = () => {
    emitUpdate({});
    setLocked(true);
    onConfirm?.();
  };

  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === "Enter") {
      e.preventDefault();
      handleConfirm();
    }
  };

  const handleUnlock = () => {
    setLocked(false);
  };

  const handleNextSet = () => {
    emitUpdate({});
    setLocked(true);
    onNextSet?.({ weight, reps, rpe, notes, duration, distance, calories });
  };

  // Build a summary string for the locked view
  const buildSummary = () => {
    const parts: string[] = [];
    if (showWeight && weight) parts.push(`${weight} ${weightUnit}`);
    if (showReps && reps) parts.push(`${reps} reps`);
    if (showDuration && duration) parts.push(`${duration} min`);
    if (showDistance && distance) parts.push(`${distance} mi`);
    if (showCalories && calories) parts.push(`${calories} cal`);
    for (const field of customFields) {
      const value = customValues[field];
      if (value) parts.push(`${field}: ${value}`);
    }
    if (rpe) parts.push(`RPE ${rpe}`);
    if (showNotesField && notes) parts.push(notes);
    return parts.length > 0 ? parts.join(" · ") : "No data";
  };

  // ---------- LOCKED VIEW ----------
  if (locked) {
    return (
      <div className="space-y-1.5">
        <div className="flex items-center gap-1.5">
          {/* Set number badge */}
          <div className="bg-white text-black rounded-full w-6 h-6 flex items-center justify-center font-semibold text-xs flex-shrink-0">
            {setNumber}
          </div>

          {/* Summary text */}
          <div className="flex-1 min-w-0">
            <p className="text-sm text-zinc-300 truncate">{buildSummary()}</p>
            {!showNotesField && notes && (
              <p className="text-[10px] text-zinc-500 truncate mt-0.5">{notes}</p>
            )}
          </div>

          {/* Edit (unlock) button */}
          <button
            type="button"
            onClick={handleUnlock}
            className="p-1.5 rounded-md flex-shrink-0 transition-colors text-zinc-400 hover:text-white hover:bg-zinc-800"
            aria-label="Edit set"
          >
            <Pencil className="w-4 h-4" />
          </button>

          {/* Delete button */}
          <button
            type="button"
            onClick={onDelete}
            className="p-1.5 text-red-500 hover:bg-red-950/30 rounded-md flex-shrink-0 active:bg-red-900/30"
            aria-label="Delete set"
          >
            <Trash2 className="w-4 h-4" />
          </button>
        </div>
      </div>
    );
  }

  // Determine which field gets autoFocus
  const firstField = showWeight ? "weight" : showReps ? "reps" : showDuration ? "duration" : showDistance ? "distance" : showCalories ? "calories" : null;

  // ---------- EDIT VIEW ----------
  return (
    <div className="space-y-1.5" onKeyDown={handleKeyDown}>
      <div className="flex items-end gap-1.5">
        {/* Set number badge */}
        <div className="bg-white text-black rounded-full w-6 h-6 flex items-center justify-center font-semibold text-xs flex-shrink-0 mb-0.5">
          {setNumber}
        </div>

        {/* Weight input */}
        {showWeight && (
          <div className="flex-1 min-w-[55px]">
            <label className="block text-[10px] font-medium text-zinc-500 mb-0.5">
              Weight
            </label>
            <input
              type="number"
              step="0.5"
              autoFocus={autoFocus && firstField === "weight"}
              value={weight}
              onChange={(e) => {
                const val = e.target.value;
                setWeight(val);
                emitUpdate({ weight: val });
              }}
              placeholder="0"
              className="w-full px-2 py-1.5 border border-zinc-700 rounded-md text-sm bg-zinc-800 text-white focus:outline-none focus:ring-2 focus:ring-white/20 placeholder:text-zinc-600"
            />
          </div>
        )}

        {/* Reps input */}
        {showReps && (
          <div className="flex-1 min-w-[55px]">
            <label className="block text-[10px] font-medium text-zinc-500 mb-0.5">
              Reps
            </label>
            <input
              type="number"
              autoFocus={autoFocus && firstField === "reps"}
              value={reps}
              onChange={(e) => {
                const val = e.target.value;
                setReps(val);
                emitUpdate({ reps: val });
              }}
              placeholder="0"
              className="w-full px-2 py-1.5 border border-zinc-700 rounded-md text-sm bg-zinc-800 text-white focus:outline-none focus:ring-2 focus:ring-white/20 placeholder:text-zinc-600"
            />
          </div>
        )}

        {/* Duration input (seconds) */}
        {showDuration && (
          <div className="flex-1 min-w-[55px]">
            <label className="block text-[10px] font-medium text-zinc-500 mb-0.5">
              Time (min)
            </label>
            <input
              type="number"
              step="0.1"
              autoFocus={autoFocus && firstField === "duration"}
              value={duration}
              onChange={(e) => {
                const val = e.target.value;
                setDuration(val);
                emitUpdate({ duration: val });
              }}
              placeholder="0"
              className="w-full px-2 py-1.5 border border-zinc-700 rounded-md text-sm bg-zinc-800 text-white focus:outline-none focus:ring-2 focus:ring-white/20 placeholder:text-zinc-600"
            />
          </div>
        )}

        {/* Distance input */}
        {showDistance && (
          <div className="flex-1 min-w-[55px]">
            <label className="block text-[10px] font-medium text-zinc-500 mb-0.5">
              Dist (mi)
            </label>
            <input
              type="number"
              step="0.1"
              autoFocus={autoFocus && firstField === "distance"}
              value={distance}
              onChange={(e) => {
                const val = e.target.value;
                setDistance(val);
                emitUpdate({ distance: val });
              }}
              placeholder="0"
              className="w-full px-2 py-1.5 border border-zinc-700 rounded-md text-sm bg-zinc-800 text-white focus:outline-none focus:ring-2 focus:ring-white/20 placeholder:text-zinc-600"
            />
          </div>
        )}

        {/* Calories input */}
        {showCalories && (
          <div className="flex-1 min-w-[55px]">
            <label className="block text-[10px] font-medium text-zinc-500 mb-0.5">
              Cals
            </label>
            <input
              type="number"
              autoFocus={autoFocus && firstField === "calories"}
              value={calories}
              onChange={(e) => {
                const val = e.target.value;
                setCalories(val);
                emitUpdate({ calories: val });
              }}
              placeholder="0"
              className="w-full px-2 py-1.5 border border-zinc-700 rounded-md text-sm bg-zinc-800 text-white focus:outline-none focus:ring-2 focus:ring-white/20 placeholder:text-zinc-600"
            />
          </div>
        )}

        {/* RPE select — always shown */}
        <div className="flex-1 min-w-[50px] max-w-[60px]">
          <label className="block text-[10px] font-medium text-zinc-500 mb-0.5">
            RPE
          </label>
          <select
            value={rpe}
            onChange={(e) => {
              const val = e.target.value;
              setRpe(val);
              emitUpdate({ rpe: val });
            }}
            className="w-full px-1.5 py-1.5 border border-zinc-700 rounded-md text-sm bg-zinc-800 text-white focus:outline-none focus:ring-2 focus:ring-white/20"
          >
            <option value="">-</option>
            <option value="6">6</option>
            <option value="7">7</option>
            <option value="8">8</option>
            <option value="9">9</option>
            <option value="10">10</option>
          </select>
        </div>

        {/* Next set button — confirm + add new pre-filled set */}
        {onNextSet && (
          <button
            type="button"
            onClick={handleNextSet}
            className="p-1.5 rounded-md flex-shrink-0 transition-colors text-zinc-400 hover:text-blue-400 hover:bg-blue-950/30"
            aria-label="Save and start next set"
          >
            <CornerDownLeft className="w-4 h-4" />
          </button>
        )}

        {/* Confirm button */}
        <button
          type="button"
          onClick={handleConfirm}
          className="p-1.5 rounded-md flex-shrink-0 transition-colors text-zinc-400 hover:text-green-400 hover:bg-green-950/30"
          aria-label="Confirm set"
        >
          <Check className="w-4 h-4" />
        </button>

        {/* Delete button */}
        <button
          type="button"
          onClick={onDelete}
          className="p-1.5 text-red-500 hover:bg-red-950/30 rounded-md flex-shrink-0 active:bg-red-900/30"
          aria-label="Delete set"
        >
          <Trash2 className="w-4 h-4" />
        </button>
      </div>

      {/* Dynamic custom metrics configured on the exercise (e.g., watts) */}
      {customFields.length > 0 && (
        <div className="ml-8 grid grid-cols-2 gap-1.5">
          {customFields.map((field) => (
            <div key={field}>
              <label className="block text-[10px] font-medium text-zinc-500 mb-0.5">
                {field.charAt(0).toUpperCase() + field.slice(1)}
              </label>
              <input
                type="text"
                value={customValues[field] || ""}
                onChange={(e) => {
                  const val = e.target.value;
                  setCustomValues((prev) => {
                    const next = { ...prev, [field]: val };
                    emitUpdate({ customMetrics: next });
                    return next;
                  });
                }}
                placeholder="-"
                className="w-full px-2 py-1.5 border border-zinc-700 rounded-md text-sm bg-zinc-800 text-white focus:outline-none focus:ring-2 focus:ring-white/20 placeholder:text-zinc-600"
              />
            </div>
          ))}
        </div>
      )}

      {/* Notes — always visible when configured as input field */}
      {showNotesField && (
        <div className="ml-8">
          <input
            type="text"
            value={notes}
            onChange={(e) => {
              const val = e.target.value;
              setNotes(val);
              emitUpdate({ notes: val });
            }}
            placeholder="e.g. weighted vest, ankle weights..."
            className="w-full px-2 py-1 border border-zinc-700 rounded-md text-xs bg-zinc-800 text-white focus:outline-none focus:ring-2 focus:ring-white/20 placeholder:text-zinc-600"
          />
        </div>
      )}

      {/* Toggle notes button (fallback when notes is not a configured input field) */}
      {!showNotesField && showNotes && (
        <div className="ml-8">
          <input
            type="text"
            value={notes}
            onChange={(e) => {
              const val = e.target.value;
              setNotes(val);
              emitUpdate({ notes: val });
            }}
            placeholder="Add notes (optional)"
            className="w-full px-2 py-1 border border-zinc-700 rounded-md text-xs bg-zinc-800 text-white focus:outline-none focus:ring-2 focus:ring-white/20 placeholder:text-zinc-600"
          />
        </div>
      )}
      {!showNotesField && !showNotes && (
        <button
          type="button"
          onClick={() => setShowNotes(true)}
          className="text-[10px] text-zinc-500 hover:text-zinc-300 ml-8"
        >
          + Add notes
        </button>
      )}
    </div>
  );
}
