import { useState, useEffect } from 'react';
import { WorkoutSet, ExerciseDef, ExerciseType } from '../types';
import { getLastSetForExercise } from '../services/storage';

interface UseWorkoutFormProps {
    userId: string;
    onSetAdded?: (set: WorkoutSet) => void;
    onUpdateSet?: (set: WorkoutSet) => void;
}

export const useWorkoutForm = ({ userId, onSetAdded, onUpdateSet }: UseWorkoutFormProps) => {
    const [weight, setWeight] = useState<string>('');
    const [reps, setReps] = useState<string>('');
    const [duration, setDuration] = useState<string>('');
    const [distance, setDistance] = useState<string>('');
    const [height, setHeight] = useState<string>('');
    const [bwPercentage, setBwPercentage] = useState<string>('100');

    // Unilateral State
    const [unilateralSide, setUnilateralSide] = useState<'LEFT' | 'RIGHT' | 'ALTERNATELY'>('ALTERNATELY');

    // Editing State
    const [editingSetId, setEditingSetId] = useState<string | null>(null);
    const [editWeight, setEditWeight] = useState<string>('');
    const [editReps, setEditReps] = useState<string>('');
    const [editDuration, setEditDuration] = useState<string>('');
    const [editDistance, setEditDistance] = useState<string>('');
    const [editHeight, setEditHeight] = useState<string>('');
    const [editSide, setEditSide] = useState<'LEFT' | 'RIGHT' | 'ALTERNATELY' | undefined>(undefined);

    const resetForm = () => {
        setWeight('');
        setReps('');
        setDuration('');
        setDistance('');
        setHeight('');
        setEditSide(undefined);
    };

    const updateFormFromLastSet = async (exerciseId: string, exerciseType: ExerciseType, bodyWeightPercentage?: number) => {
        setBwPercentage(bodyWeightPercentage ? bodyWeightPercentage.toString() : '100');

        const set = await getLastSetForExercise(userId, exerciseId);
        if (set) {
            setWeight(set.weight?.toString() || '');
            setReps(set.reps?.toString() || '');
            setDuration(set.durationSeconds?.toString() || '');
            setDistance(set.distanceMeters?.toString() || '');
            setHeight(set.height?.toString() || '');
        } else {
            resetForm();
        }

        // Clear irrelevant fields
        if (exerciseType !== ExerciseType.STRENGTH && exerciseType !== ExerciseType.BODYWEIGHT) setWeight('');
        if (exerciseType !== ExerciseType.STRENGTH && exerciseType !== ExerciseType.BODYWEIGHT && exerciseType !== ExerciseType.PLYOMETRIC) setReps('');
        if (exerciseType !== ExerciseType.CARDIO && exerciseType !== ExerciseType.STATIC) setDuration('');
        if (exerciseType !== ExerciseType.CARDIO && exerciseType !== ExerciseType.LONG_JUMP) setDistance('');
        if (exerciseType !== ExerciseType.HIGH_JUMP) setHeight('');
    };

    const prepareSetData = (selectedExercise: ExerciseDef, isSporadic: boolean = false) => {
        const setData: Partial<WorkoutSet> = {
            exerciseId: selectedExercise.id,
        };

        if (selectedExercise.isUnilateral) {
            setData.side = unilateralSide;
        }

        switch (selectedExercise.type) {
            case ExerciseType.STRENGTH:
                if (weight) setData.weight = parseFloat(weight);
                setData.reps = reps ? parseInt(reps) : 1;
                break;
            case ExerciseType.BODYWEIGHT:
                if (weight) setData.weight = parseFloat(weight);
                setData.reps = reps ? parseInt(reps) : 1;
                setData.bodyWeightPercentage = parseFloat(bwPercentage) || 100;
                break;
            case ExerciseType.CARDIO:
                if (duration) setData.durationSeconds = parseInt(duration);
                if (distance) setData.distanceMeters = parseFloat(distance);
                break;
            case ExerciseType.STATIC:
                if (duration) setData.durationSeconds = parseInt(duration);
                setData.bodyWeightPercentage = parseFloat(bwPercentage) || 100;
                break;
            case ExerciseType.HIGH_JUMP:
                if (height) setData.height = parseFloat(height);
                break;
            case ExerciseType.LONG_JUMP:
                if (distance) setData.distanceMeters = parseFloat(distance);
                break;
            case ExerciseType.PLYOMETRIC:
                setData.reps = reps ? parseInt(reps) : 1;
                break;
        }
        return setData;
    };

    const startEditing = (set: WorkoutSet) => {
        setEditingSetId(set.id);
        setEditWeight(set.weight?.toString() || '');
        setEditReps(set.reps?.toString() || '');
        setEditDuration(set.durationSeconds?.toString() || '');
        setEditDistance(set.distanceMeters?.toString() || '');
        setEditHeight(set.height?.toString() || '');
        setEditSide(set.side);
    };

    const saveEdit = (set: WorkoutSet) => {
        const updatedSet: WorkoutSet = {
            ...set,
            ...(editWeight && { weight: parseFloat(editWeight) }),
            ...(editReps && { reps: parseInt(editReps) }),
            ...(editDuration && { durationSeconds: parseInt(editDuration) }),
            ...(editDistance && { distanceMeters: parseFloat(editDistance) }),
            ...(editHeight && { height: parseFloat(editHeight) }),
            ...(editSide && { side: editSide })
        };
        if (onUpdateSet) onUpdateSet(updatedSet);
        setEditingSetId(null);
    };

    const cancelEdit = () => {
        setEditingSetId(null);
    };

    return {
        weight, setWeight,
        reps, setReps,
        duration, setDuration,
        distance, setDistance,
        height, setHeight,
        bwPercentage, setBwPercentage,
        unilateralSide, setUnilateralSide,
        editingSetId,
        editWeight, setEditWeight,
        editReps, setEditReps,
        editDuration, setEditDuration,
        editDistance, setEditDistance,
        editHeight, setEditHeight,
        editSide, setEditSide,
        resetForm,
        updateFormFromLastSet,
        prepareSetData,
        startEditing,
        saveEdit,
        cancelEdit
    };
};
