import { useEffect, useMemo, useState } from "react";

import type { WorkoutItem, WorkoutSetInput } from "../../types";
import { measurementLabels } from "../catalog/meta";
import { formatSet, volumeForSet } from "./setFormat";
import { WorkoutSetRow } from "./WorkoutSetRow";

function initialDraft(item: WorkoutItem) {
  const last = item.sets[item.sets.length - 1];
  return {
    weight: last?.weight ?? item.planned_working_weight ?? 0,
    reps: last?.reps ?? 8,
    durationSeconds: last?.duration_seconds ?? 60,
    distanceKm: last?.distance_km ?? 1,
    calories: last?.calories ?? 100,
  };
}

export function WorkoutExerciseCard({
  item,
  onRecordSet,
  onRecordBatch,
  onRemoveItem,
  onRemoveSet,
  onUpdateSet,
  pending,
}: {
  item: WorkoutItem;
  onRecordSet: (payload: WorkoutSetInput) => void;
  onRecordBatch: (sets: WorkoutSetInput[]) => void;
  onRemoveItem: () => void;
  onRemoveSet: (setId: string) => void;
  onUpdateSet: (setId: string, payload: Partial<WorkoutSetInput>) => void;
  pending?: boolean;
}) {
  const measurementType = item.measurement_type_snapshot;
  const seed = useMemo(() => initialDraft(item), [item]);
  const [weight, setWeight] = useState(seed.weight);
  const [reps, setReps] = useState(seed.reps);
  const [durationSeconds, setDurationSeconds] = useState(seed.durationSeconds);
  const [distanceKm, setDistanceKm] = useState(seed.distanceKm);
  const [calories, setCalories] = useState(seed.calories);
  const [showBatch, setShowBatch] = useState(false);
  const [batchCount, setBatchCount] = useState(3);

  useEffect(() => {
    setWeight(seed.weight);
    setReps(seed.reps);
    setDurationSeconds(seed.durationSeconds);
    setDistanceKm(seed.distanceKm);
    setCalories(seed.calories);
  }, [item.id, seed.weight, seed.reps, seed.durationSeconds, seed.distanceKm, seed.calories]);

  const volume = item.sets.reduce((sum, set) => sum + volumeForSet(set, measurementType), 0);
  const lastSet = item.sets[item.sets.length - 1];
  const volumeLabel = measurementType === "distance_duration" ? `${volume.toFixed(1)} км` : measurementType === "duration" || measurementType === "duration_calories" ? `${Math.round(volume / 60)} мин` : `${Math.round(volume)} кг объема`;

  function stepWeight(delta: number) {
    setWeight((value) => Math.max(0, Number((value + delta).toFixed(1))));
  }

  function stepReps(delta: number) {
    setReps((value) => Math.max(0, value + delta));
  }

  function currentPayload(): WorkoutSetInput {
    if (measurementType === "reps_only") return { weight: 0, reps };
    if (measurementType === "duration") return { weight: 0, reps: 0, duration_seconds: durationSeconds };
    if (measurementType === "distance_duration") return { weight: 0, reps: 0, distance_km: distanceKm, duration_seconds: durationSeconds };
    if (measurementType === "duration_calories") return { weight: 0, reps: 0, duration_seconds: durationSeconds, calories };
    return { weight, reps };
  }

  function recordBatch() {
    onRecordBatch(Array.from({ length: batchCount }, () => currentPayload()));
    setShowBatch(false);
  }

  return (
    <article className="workout-exercise-card card">
      <div className="exercise-card-media">
        {item.image_s3_url_snapshot ? <img src={item.image_s3_url_snapshot} alt="" /> : <span>{item.source_kind === "exercise" ? "EX" : "MC"}</span>}
      </div>
      <div className="exercise-card-body">
        <header className="exercise-card-header">
          <div>
            <span className="source-pill">{item.source_kind === "exercise" ? "упражнение" : "тренажер"}</span>
            <h3>{item.title_snapshot}</h3>
            <p>{lastSet ? `Последний раз: ${formatSet(lastSet, measurementType)}` : "Подходов еще нет"}</p>
          </div>
          <button className="danger-ghost" disabled={pending} onClick={onRemoveItem}>Удалить</button>
        </header>

        <div className="exercise-microstats">
          <span>{item.sets.length} подх.</span>
          <span>{volumeLabel}</span>
          <span>{measurementLabels[measurementType]}</span>
        </div>

        <div className="sets-list">
          {item.sets.map((set) => (
            <WorkoutSetRow
              key={set.id}
              set={set}
              measurementType={measurementType}
              disabled={pending}
              onRemove={() => onRemoveSet(set.id)}
              onUpdate={(payload) => onUpdateSet(set.id, payload)}
            />
          ))}
        </div>

        <div className="single-set-console dynamic-console">
          {measurementType === "weight_reps" && (
            <div className="stepper-field">
              <span>Вес</span>
              <div>
                <button onClick={() => stepWeight(-2.5)}>-</button>
                <input aria-label="Вес" type="number" min="0" step="0.5" value={weight} onChange={(event) => setWeight(Number(event.target.value))} />
                <button onClick={() => stepWeight(2.5)}>+</button>
              </div>
            </div>
          )}
          {(measurementType === "weight_reps" || measurementType === "reps_only") && (
            <div className="stepper-field">
              <span>Повторы</span>
              <div>
                <button onClick={() => stepReps(-1)}>-</button>
                <input aria-label="Повторы" type="number" min="0" step="1" value={reps} onChange={(event) => setReps(Number(event.target.value))} />
                <button onClick={() => stepReps(1)}>+</button>
              </div>
            </div>
          )}
          {(measurementType === "duration" || measurementType === "distance_duration" || measurementType === "duration_calories") && (
            <label className="stepper-field compact-input"><span>Секунды</span><input aria-label="Секунды" type="number" min="0" step="5" value={durationSeconds} onChange={(event) => setDurationSeconds(Number(event.target.value))} /></label>
          )}
          {measurementType === "distance_duration" && <label className="stepper-field compact-input"><span>Км</span><input aria-label="Километры" type="number" min="0" step="0.1" value={distanceKm} onChange={(event) => setDistanceKm(Number(event.target.value))} /></label>}
          {measurementType === "duration_calories" && <label className="stepper-field compact-input"><span>Ккал</span><input aria-label="Калории" type="number" min="0" step="1" value={calories} onChange={(event) => setCalories(Number(event.target.value))} /></label>}
          <button className="primary record-set" disabled={pending} onClick={() => onRecordSet(currentPayload())}>
            {pending ? "Запись..." : "Записать подход"}
          </button>
        </div>

        <button className="ghost batch-link" onClick={() => setShowBatch(true)}>Добавить несколько подходов</button>
      </div>

      {showBatch && (
        <div className="dialog-backdrop" onClick={() => setShowBatch(false)}>
          <div className="modal-card batch-dialog card" onClick={(event) => event.stopPropagation()}>
            <p className="eyebrow">Batch sets</p>
            <h2>Добавить несколько подходов</h2>
            <div className="batch-grid">
              <label>Кол-во<input type="number" min="1" max="12" value={batchCount} onChange={(event) => setBatchCount(Number(event.target.value))} /></label>
            </div>
            <p className="muted">Будет записан текущий шаблон: {measurementLabels[measurementType]}.</p>
            <div className="modal-actions">
              <button className="ghost" onClick={() => setShowBatch(false)}>Отмена</button>
              <button className="primary" disabled={pending} onClick={recordBatch}>Добавить</button>
            </div>
          </div>
        </div>
      )}
    </article>
  );
}
