import React, { useState, useEffect } from 'react';
import { useSearchParams } from 'react-router-dom';
import { Plus, Trash2, PlayCircle, Dumbbell, Save, X, List, ArrowUp, Pencil, User, Flame, Timer as TimerIcon, Ruler, Footprints, Percent, CheckCircle, GripVertical, Bot, Loader2, ClipboardList } from 'lucide-react';
import { TopBar } from './ui/TopBar';
import {
  DndContext,
  closestCenter,
  KeyboardSensor,
  PointerSensor,
  useSensor,
  useSensors,
  DragEndEvent,
  TouchSensor,
  MouseSensor
} from '@dnd-kit/core';
import {
  arrayMove,
  SortableContext,
  sortableKeyboardCoordinates,
  verticalListSortingStrategy,
  useSortable,
} from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import { WorkoutPlan, ExerciseDef, PlannedSet, Language, ExerciseType } from '../types';
import { getExercises, saveExercise } from '../services/storage';
import { t } from '../services/i18n';
import { generateId } from '../utils/uuid';
import { useAuth } from '../context/AuthContext';
import { useSession } from '../context/SessionContext';
import { useActiveWorkout } from '../context/ActiveWorkoutContext';

import FilledInput from './FilledInput';
import { toTitleCase } from '../utils/text';
import { Button } from './ui/Button';
import { Card } from './ui/Card';
import { Modal } from './ui/Modal';
import { SideSheet } from './ui/SideSheet';
import { Checkbox } from './ui/Checkbox';
import ExerciseModal from './ExerciseModal';
import { generateWorkoutPlan } from '../services/geminiService';

interface PlansProps {
  lang: Language;
}

// Sortable Item Component
interface SortablePlanStepProps {
  step: PlannedSet;
  index: number;
  toggleWeighted: (id: string) => void;
  updateRestTime: (id: string, val: number | undefined) => void;
  removeStep: (id: string) => void;
  lang: Language;
}

const SortablePlanStep: React.FC<SortablePlanStepProps> = ({ step, index, toggleWeighted, updateRestTime, removeStep, lang }) => {
  const {
    attributes,
    listeners,
    setNodeRef,
    transform,
    transition,
    isDragging
  } = useSortable({ id: step.id });

  const style = {
    transform: CSS.Transform.toString(transform),
    transition,
    opacity: isDragging ? 0.5 : 1,
    zIndex: isDragging ? 1000 : 1,
    position: 'relative' as 'relative',
  };

  const handlePointerDown = (e: React.PointerEvent) => {
    listeners?.onPointerDown?.(e);

    // Only trigger vibration for touch input (long press logic)
    if (e.pointerType === 'touch') {
      const startTime = Date.now();

      // Use pattern [0, 300, 50] to vibrate after 300ms delay, triggered synchronously by user gesture
      // This works around Firefox Android blocking async vibrate calls
      if (typeof navigator !== 'undefined' && navigator.vibrate) {
        try {
          navigator.vibrate([0, 300, 50]);
        } catch (err) {
          // Ignore potential errors if vibrate is blocked or invalid
        }
      }

      // Cleanup / Cancel logic
      const cancelVibration = () => {
        // Only cancel if less than 300ms has passed (meaning we aborted the long press)
        // If > 300ms, the vibration (50ms) is either playing or done, we let it finish.
        if (Date.now() - startTime < 300) {
          if (typeof navigator !== 'undefined' && navigator.vibrate) {
            navigator.vibrate(0);
          }
        }
        cleanup();
      };

      const startX = e.clientX;
      const startY = e.clientY;

      const onMove = (me: PointerEvent) => {
        const diff = Math.hypot(me.clientX - startX, me.clientY - startY);
        if (diff > 10) { // 10px tolerance
          cancelVibration();
        }
      };

      const cleanup = () => {
        window.removeEventListener('pointermove', onMove);
        window.removeEventListener('pointerup', cancelVibration);
        window.removeEventListener('pointercancel', cancelVibration);
      };

      window.addEventListener('pointermove', onMove);
      window.addEventListener('pointerup', cancelVibration);
      window.addEventListener('pointercancel', cancelVibration);
    }
  };

  return (
    <div ref={setNodeRef} style={style} {...attributes} data-testid="plan-exercise-item">
      <Card
        className={`flex items-center gap-3 transition-all hover:bg-surface-container-high ${isDragging ? 'bg-surface-container-high shadow-elevation-3' : ''}`}
      >
        <div
          className="text-on-surface-variant p-1 cursor-grab touch-none"
          {...listeners}
          onPointerDown={handlePointerDown}
        >
          <GripVertical size={20} />
        </div>

        <div className="w-8 h-8 rounded-full bg-primary-container text-on-primary-container flex items-center justify-center text-xs font-bold shrink-0">
          {index + 1}
        </div>

        <div className="flex-1">
          <div className="text-base font-medium text-on-surface">{step.exerciseName}</div>
          <div className="flex items-center gap-4 mt-1">
            <label className="flex items-center gap-2 cursor-pointer w-fit">
              <div className={`w-4 h-4 border rounded flex items-center justify-center ${step.isWeighted ? 'bg-primary border-primary' : 'border-outline'}`}>
                {step.isWeighted && <Dumbbell size={10} className="text-on-primary" />}
              </div>
              <input
                type="checkbox"
                checked={step.isWeighted}
                onChange={() => toggleWeighted(step.id)}
                className="hidden"
              />
              <span className="text-xs text-on-surface-variant">{t('weighted', lang)}</span>
            </label>

            <div className="flex items-center gap-2">
              <TimerIcon size={14} className="text-on-surface-variant" />
              <input
                type="number"
                placeholder="Rest (s)"
                className="w-16 bg-transparent border-b border-outline-variant text-xs text-on-surface focus:border-primary focus:outline-none text-center"
                value={step.restTimeSeconds || ''}
                onChange={(e) => {
                  const val = parseInt(e.target.value);
                  updateRestTime(step.id, isNaN(val) ? undefined : val);
                }}
              />
              <span className="text-xs text-on-surface-variant">s</span>
            </div>
          </div>
        </div>
        <Button onClick={() => removeStep(step.id)} variant="ghost" size="icon" className="text-on-surface-variant hover:text-error hover:bg-error/10">
          <Trash2 size={20} />
        </Button>
      </Card>
    </div>
  );
};

const Plans: React.FC<PlansProps> = ({ lang }) => {
  const { currentUser } = useAuth();
  const userId = currentUser?.id || '';
  const { plans, sessions, savePlan, deletePlan, refreshData } = useSession();
  const { startSession } = useActiveWorkout();

  const [isEditing, setIsEditing] = useState(false);

  const [editId, setEditId] = useState<string | null>(null);
  const [name, setName] = useState('');
  const [description, setDescription] = useState('');
  const [steps, setSteps] = useState<PlannedSet[]>([]);

  // Dnd Sensors
  const sensors = useSensors(
    useSensor(MouseSensor, {
      activationConstraint: {
        distance: 10,
      },
    }),
    useSensor(TouchSensor, {
      activationConstraint: {
        delay: 300,
        tolerance: 5,
      },
    }),
    useSensor(KeyboardSensor, {
      coordinateGetter: sortableKeyboardCoordinates,
    })
  );

  // Create Exercise State
  const [availableExercises, setAvailableExercises] = useState<ExerciseDef[]>([]);
  const [showExerciseSelector, setShowExerciseSelector] = useState(false);
  const [isCreatingExercise, setIsCreatingExercise] = useState(false);

  // Preparation Modal State
  const [showPlanPrep, setShowPlanPrep] = useState<WorkoutPlan | null>(null);

  // FAB Menu State
  const [fabMenuOpen, setFabMenuOpen] = useState(false);

  // AI Plan Creation State
  const [showAISheet, setShowAISheet] = useState(false);
  const [aiPrompt, setAIPrompt] = useState('');
  const [aiLoading, setAILoading] = useState(false);
  const [aiError, setAIError] = useState<string | null>(null);
  const [aiDuration, setAIDuration] = useState(60); // Default 1 hour in minutes
  const [aiEquipment, setAIEquipment] = useState<'none' | 'essentials' | 'free_weights' | 'full_gym'>('none');
  const [aiLevel, setAILevel] = useState<'beginner' | 'intermediate' | 'advanced'>('intermediate');
  const [aiIntensity, setAIIntensity] = useState<'low' | 'moderate' | 'high'>('moderate');
  const [generatedPlanPreview, setGeneratedPlanPreview] = useState<{
    name: string;
    description: string;
    exercises: Array<{
      name: string;
      isWeighted: boolean;
      restTimeSeconds: number;
      type?: string;
      unilateral?: boolean;
    }>;
  } | null>(null);

  // URL params handling
  const [searchParams, setSearchParams] = useSearchParams();

  useEffect(() => {
    if (searchParams.get('create') === 'true') {
      handleCreateNew();
      setSearchParams({});
    }
    if (searchParams.get('aiPrompt') === 'true') {
      setShowAISheet(true);
      setSearchParams({});
    }

    const sourceSessionId = searchParams.get('createFromSessionId');
    if (sourceSessionId && sessions.length > 0) {
      const sourceSession = sessions.find(s => s.id === sourceSessionId);
      if (sourceSession) {
        handleCreateNew();

        // Generate name
        const dateStr = new Date(sourceSession.startTime).toLocaleDateString();
        setName(sourceSession.planName || (lang === 'ru' ? `План от ${dateStr}` : `Plan from ${dateStr}`));
        if (sourceSession.note) setDescription(sourceSession.note);

        // Generate steps from sets
        const newSteps: PlannedSet[] = [];
        let lastExerciseId: string | null = null;

        // Use default rest timer or 60s
        const defaultRest = currentUser?.profile?.restTimerDefault || 60;

        sourceSession.sets.forEach(set => {
          // Mirror every set from the session to the plan
          newSteps.push({
            id: generateId(),
            exerciseId: set.exerciseId,
            exerciseName: set.exerciseName,
            exerciseType: set.type,
            isWeighted: (set.weight || 0) > 0,
            restTimeSeconds: defaultRest
          });
        });

        setSteps(newSteps);

        // Clear param so we don't re-run
        setSearchParams({});
      }
    }
  }, [searchParams, setSearchParams, sessions, currentUser]);

  const handleStart = (plan: WorkoutPlan) => {
    if (plan.description && plan.description.trim().length > 0) {
      setShowPlanPrep(plan);
    } else {
      startSession(plan, currentUser?.profile?.weight);
    }
  };

  const confirmPlanStart = () => {
    if (showPlanPrep) {
      startSession(showPlanPrep, currentUser?.profile?.weight);
      setShowPlanPrep(null);
    }
  };

  useEffect(() => {
    const loadData = async () => {
      refreshData();
      const fetchedExercises = await getExercises(userId);
      // Filter out archived exercises
      if (Array.isArray(fetchedExercises)) {
        setAvailableExercises(fetchedExercises.filter(e => !e.isArchived));
      } else {
        setAvailableExercises([]);
      }
    };
    if (userId) loadData();
  }, [userId, refreshData]);

  const handleCreateNew = () => {
    setEditId(generateId());
    setName('');
    setDescription('');
    setSteps([]);
    setIsEditing(true);
  };

  const handleEdit = (plan: WorkoutPlan) => {
    setEditId(plan.id);
    setName(plan.name);
    setDescription(plan.description || '');
    setSteps(plan.steps);
    setIsEditing(true);
  };

  // Persist draft to localStorage
  useEffect(() => {
    if (isEditing) {
      const draft = {
        editId,
        name,
        description,
        steps
      };
      localStorage.setItem('gymflow_plan_draft', JSON.stringify(draft));
    }
  }, [isEditing, editId, name, description, steps]);

  // Restore draft on mount
  useEffect(() => {
    const draftJson = localStorage.getItem('gymflow_plan_draft');
    if (draftJson) {
      try {
        const draft = JSON.parse(draftJson);
        // Only restore if we have valid data
        if (draft.editId) {
          setEditId(draft.editId);
          setName(draft.name || '');
          setDescription(draft.description || '');
          setSteps(draft.steps || []);
          setIsEditing(true);
        }
      } catch (e) {
        console.error("Failed to parse plan draft", e);
      }
    }
  }, []);

  const handleSave = async () => {
    if (!name.trim() || !editId) return;
    const newPlan: WorkoutPlan = { id: editId, name, description, steps };
    await savePlan(newPlan);
    localStorage.removeItem('gymflow_plan_draft');
    setIsEditing(false);
  };

  const handleDelete = async (id: string, e: React.MouseEvent) => {
    e.stopPropagation();
    if (confirm(t('delete_confirm', lang))) {
      await deletePlan(id);
    }
  };

  const addStep = (ex: ExerciseDef) => {
    const newStep: PlannedSet = {
      id: generateId(),
      exerciseId: ex.id,
      exerciseName: ex.name,
      exerciseType: ex.type,
      isWeighted: false,
      restTimeSeconds: 120 // Default new step to 120s? Or leave undefined to use profile default? 
      // Requirement: "fallback to user default". So maybe undefined/null is better for "inherit".
      // But UI needs a value. Let's start with 120 or empty. 
    };
    setSteps([...steps, newStep]);
    setShowExerciseSelector(false);
  };

  const handleSaveNewExercise = async (newEx: ExerciseDef) => {
    await saveExercise(userId, newEx);
    const exList = await getExercises(userId);
    setAvailableExercises(exList.filter(e => !e.isArchived));

    // Automatically add the new exercise to the plan
    addStep(newEx);
    setIsCreatingExercise(false);
  };

  const toggleWeighted = (stepId: string) => {
    setSteps(steps.map(s => s.id === stepId ? { ...s, isWeighted: !s.isWeighted } : s));
  };

  const updateRestTime = (stepId: string, seconds: number | undefined) => {
    setSteps(steps.map(s => s.id === stepId ? { ...s, restTimeSeconds: seconds } : s));
  };

  const removeStep = (stepId: string) => {
    setSteps(steps.filter(s => s.id !== stepId));
  };

  /* Vibration handled in SortablePlanStep locally for better touch support */
  /*
  const handleDragStart = () => {
    console.log('handleDragStart called');
    if (typeof navigator !== 'undefined' && navigator.vibrate) {
      navigator.vibrate(50);
    }
  };
  */

  const handleDragEnd = (event: DragEndEvent) => {
    const { active, over } = event;

    if (active.id !== over?.id) {
      setSteps((items) => {
        const oldIndex = items.findIndex((item) => item.id === active.id);
        const newIndex = items.findIndex((item) => item.id === over?.id);
        return arrayMove(items, oldIndex, newIndex);
      });
    }
  };

  const handleGenerateAIPlan = async () => {
    if (aiLoading) return;
    setAILoading(true);
    setAIError(null);
    setGeneratedPlanPreview(null);

    try {
      const availableNames = availableExercises.map(e => e.name);
      const prompt = aiPrompt.trim()
        ? aiPrompt
        : (lang === 'ru' ? 'Создай план тренировки' : 'Create a workout plan');

      const aiPlan = await generateWorkoutPlan(
        prompt,
        availableNames,
        lang,
        aiDuration,
        aiEquipment,
        aiLevel,
        aiIntensity,
        sessions,
        currentUser?.profile
      );
      setGeneratedPlanPreview(aiPlan);
    } catch (err: any) {
      console.error('AI plan generation error:', err);
      setAIError(err.message || 'Failed to generate plan');
    } finally {
      setAILoading(false);
    }
  };

  const handleSaveAIPlan = async () => {
    if (!generatedPlanPreview || aiLoading) return;
    setAILoading(true);
    setAIError(null);

    try {
      // Build plan steps, creating new exercises as needed
      const planSteps: PlannedSet[] = [];
      for (const aiEx of generatedPlanPreview.exercises) {
        let existingEx = availableExercises.find(
          e => e.name.toLowerCase() === aiEx.name.toLowerCase()
        );

        if (!existingEx) {
          // Create new exercise - map AI type to ExerciseType enum
          const typeMap: Record<string, ExerciseType> = {
            'STRENGTH': ExerciseType.STRENGTH,
            'BODYWEIGHT': ExerciseType.BODYWEIGHT,
            'CARDIO': ExerciseType.CARDIO,
            'STATIC': ExerciseType.STATIC,
            'PLYOMETRIC': ExerciseType.PLYOMETRIC,
            'HIGH_JUMP': ExerciseType.HIGH_JUMP,
            'LONG_JUMP': ExerciseType.LONG_JUMP,
          };
          const mappedType = typeMap[aiEx.type?.toUpperCase() || 'STRENGTH'] || ExerciseType.STRENGTH;

          const newEx: ExerciseDef = {
            id: generateId(),
            name: aiEx.name,
            type: mappedType,
            isUnilateral: aiEx.unilateral || false,
            bodyWeightPercentage: undefined,
          };
          await saveExercise(userId, newEx);
          existingEx = newEx;
          // Add to local list
          setAvailableExercises(prev => [...prev, newEx]);
        }

        planSteps.push({
          id: generateId(),
          exerciseId: existingEx.id,
          exerciseName: existingEx.name,
          exerciseType: existingEx.type,
          isWeighted: aiEx.isWeighted || false,
          restTimeSeconds: aiEx.restTimeSeconds || 120,
        });
      }

      // Save the plan
      const newPlan: WorkoutPlan = {
        id: generateId(),
        name: generatedPlanPreview.name,
        description: generatedPlanPreview.description,
        steps: planSteps,
      };
      await savePlan(newPlan);

      // Reset state and close
      setAIPrompt('');
      setAIDuration(60);
      setAIEquipment('none');
      setAILevel('intermediate');
      setAIIntensity('moderate');
      setGeneratedPlanPreview(null);
      setShowAISheet(false);
      setFabMenuOpen(false);
    } catch (err: any) {
      console.error('AI plan save error:', err);
      setAIError(err.message || 'Failed to save plan');
    } finally {
      setAILoading(false);
    }
  };

  if (isEditing) {
    return (
      <div className="h-full flex flex-col bg-surface">
        <TopBar
          title={t('plan_editor', lang)}
          actions={
            <div className="flex items-center gap-1">
              <Button
                onClick={() => {
                  setIsEditing(false);
                  localStorage.removeItem('gymflow_plan_draft');
                }}
                variant="ghost" size="icon">
                <X size={20} />
              </Button>
              <Button onClick={handleSave} variant="ghost" className="text-primary font-medium hover:bg-primary-container/10">
                {t('save', lang)}
              </Button>
            </div>
          }
        />

        <div className="flex-1 overflow-y-auto p-4 space-y-6">
          <FilledInput
            label={t('ex_name', lang)}
            value={name}
            onChange={(e: any) => setName(e.target.value)}
            type="text"
            autocapitalize="words"
            onBlur={() => setName(toTitleCase(name))}
          />

          <FilledInput
            label={t('prep_title', lang)}
            value={description}
            onChange={(e: any) => setDescription(e.target.value)}
            multiline
            rows={3}
            type="text"
          />

          <div className="space-y-3">
            <div className="flex justify-between items-center px-2">
              <label className="text-sm text-primary font-medium">{t('exercises_list', lang)}</label>
            </div>

            <div className="space-y-2">
              <DndContext
                sensors={sensors}
                collisionDetection={closestCenter}
                onDragEnd={handleDragEnd}
              >
                <SortableContext
                  items={steps.map(s => s.id)}
                  strategy={verticalListSortingStrategy}
                >
                  {steps.map((step, idx) => (
                    <SortablePlanStep
                      key={step.id}
                      step={step}
                      index={idx}
                      toggleWeighted={toggleWeighted}
                      updateRestTime={updateRestTime}
                      removeStep={removeStep}
                      lang={lang}
                    />
                  ))}
                </SortableContext>
              </DndContext>
            </div>

            <Button
              onClick={() => setShowExerciseSelector(true)}
              variant="outline"
              fullWidth
              className="py-6 rounded-full border border-outline text-primary font-medium flex items-center justify-center gap-2 hover:bg-primary-container/10 transition-all h-auto"
            >
              <Plus size={20} />
              {t('add_exercise', lang)}
            </Button>
          </div>
        </div>

        <SideSheet
          isOpen={showExerciseSelector}
          onClose={() => setShowExerciseSelector(false)}
          title={t('select_exercise', lang)}
          width="lg"
        >
          <div className="flex flex-col h-[60vh]">
            <div className="flex justify-end mb-2">
              <Button onClick={() => setIsCreatingExercise(true)} variant="ghost" className="text-primary hover:bg-primary-container/20 flex gap-2">
                <Plus size={18} /> {t('create_exercise', lang)}
              </Button>
            </div>
            <div className="flex-1 overflow-y-auto -mx-6 px-6">
              {availableExercises
                .slice()
                .sort((a, b) => a.name.localeCompare(b.name))
                .map(ex => (
                  <button
                    key={ex.id}
                    onClick={() => addStep(ex)}
                    className="w-full text-left p-4 border-b border-outline-variant hover:bg-surface-container-high text-on-surface flex justify-between group"
                  >
                    <span className="group-hover:text-primary transition-colors">{ex.name}</span>
                    <span className="text-xs bg-secondary-container text-on-secondary-container px-2 py-1 rounded-full">{ex.type}</span>
                  </button>
                ))}
            </div>
          </div>
        </SideSheet>




        <ExerciseModal
          isOpen={isCreatingExercise}
          onClose={() => setIsCreatingExercise(false)}
          onSave={handleSaveNewExercise}
          lang={lang}
          existingExercises={availableExercises}
        />
      </div>
    );
  }



  return (
    <div className="h-full flex flex-col bg-surface relative">
      <TopBar title={t('my_plans', lang)} icon={ClipboardList} />

      <div className="flex-1 p-4 overflow-y-auto pb-24">
        {plans.length === 0 ? (
          <div className="text-center text-on-surface-variant mt-20 flex flex-col items-center">
            <div className="w-16 h-16 bg-surface-container-high rounded-full flex items-center justify-center mb-4">
              <List size={32} />
            </div>
            <p className="text-headline-sm">{t('plans_empty', lang)}</p>
          </div>
        ) : (
          <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
            {plans.map(plan => (
              <Card key={plan.id} className="relative overflow-hidden group">
                <div className="flex justify-between items-start mb-2">
                  <h3 className="text-title-lg font-normal text-on-surface">{plan.name}</h3>
                  <div className="flex gap-1">
                    <Button
                      onClick={(e) => { e.stopPropagation(); handleEdit(plan); }}
                      variant="ghost"
                      size="icon"
                      aria-label="Edit Plan"
                      className="text-on-surface-variant hover:text-primary hover:bg-surface-container-high"
                    >
                      <Pencil size={20} />
                    </Button>
                    <Button
                      onClick={(e) => handleDelete(plan.id, e)}
                      variant="ghost"
                      size="icon"
                      aria-label="Delete Plan"
                      className="text-on-surface-variant hover:text-error hover:bg-error-container/10"
                    >
                      <Trash2 size={20} />
                    </Button>
                  </div>
                </div>
                <p className="text-on-surface-variant text-body-md line-clamp-2 mb-4 min-h-[1.5rem]">
                  {plan.description || t('prep_no_instructions', lang)}
                </p>
                <div className="flex items-center justify-between">
                  <div className="text-label-md font-medium text-primary bg-primary-container/20 px-3 py-1 rounded-full">
                    {plan.steps.length} {t('exercises_count', lang)}
                  </div>
                  <Button
                    onClick={() => handleStart(plan)}
                    className="flex items-center gap-2"
                  >
                    <PlayCircle size={18} />
                    {t('start', lang)}
                  </Button>
                </div>
              </Card>
            ))}
          </div>
        )}
      </div>

      {/* FAB Menu */}
      <div className="absolute bottom-6 right-6 z-20">
        {/* Menu Options - shown when expanded */}
        {fabMenuOpen && (
          <div className="absolute bottom-16 right-0 flex flex-col gap-2 items-end animate-in slide-in-from-bottom-2 duration-200">
            <button
              onClick={() => { setFabMenuOpen(false); handleCreateNew(); }}
              className="flex items-center gap-2 px-4 py-2 bg-surface-container-high text-on-surface rounded-full shadow-elevation-2 hover:bg-surface-container-highest transition-colors"
            >
              <Pencil size={18} />
              <span className="font-medium text-sm whitespace-nowrap">{t('create_manually', lang)}</span>
            </button>
            <button
              onClick={() => { setFabMenuOpen(false); setShowAISheet(true); }}
              className="flex items-center gap-2 px-4 py-2 bg-secondary-container text-on-secondary-container rounded-full shadow-elevation-2 hover:opacity-90 transition-opacity"
            >
              <Bot size={18} />
              <span className="font-medium text-sm whitespace-nowrap">{t('create_with_ai', lang)}</span>
            </button>
          </div>
        )}
        {/* Main FAB */}
        <button
          onClick={() => setFabMenuOpen(!fabMenuOpen)}
          aria-label="Create Plan"
          className={`w-14 h-14 bg-primary-container text-on-primary-container shadow-elevation-3 flex items-center justify-center hover:bg-primary hover:text-on-primary transition-all duration-200 ${fabMenuOpen ? 'rotate-45 rounded-[28px]' : 'rotate-0 rounded-[16px]'}`}
        >
          <Plus size={28} />
        </button>
      </div>

      {/* Backdrop for FAB Menu */}
      {fabMenuOpen && (
        <div
          className="fixed inset-0 z-10"
          onClick={() => setFabMenuOpen(false)}
        />
      )}

      {/* AI Plan Creation Side Sheet */}
      <SideSheet
        isOpen={showAISheet}
        onClose={() => {
          setShowAISheet(false);
          setAIPrompt('');
          setAIError(null);
          setGeneratedPlanPreview(null);
          setAIDuration(60);
          setAIEquipment('full_gym');
        }}
        title={t('ai_plan_prompt_title', lang)}
        width="lg"
      >
        <div className="space-y-6">
          {/* Duration Slider */}
          <div className="space-y-2">
            <label className="text-sm font-medium text-on-surface flex items-center justify-between">
              <span>{t('duration', lang)}</span>
              <span className="text-primary font-bold">
                {aiDuration >= 120 ? t('duration_hours_plus', lang) : `${aiDuration} ${t('duration_minutes', lang)}`}
              </span>
            </label>
            <input
              type="range"
              min="5"
              max="120"
              step="5"
              value={aiDuration}
              onChange={(e) => setAIDuration(Number(e.target.value))}
              className="w-full h-2 bg-surface-container-highest rounded-lg appearance-none cursor-pointer accent-primary"
              disabled={aiLoading}
            />
            <div className="flex justify-between text-xs text-on-surface-variant">
              <span>5 {t('duration_minutes', lang)}</span>
              <span>{t('duration_hours_plus', lang)}</span>
            </div>
          </div>

          {/* Equipment Selector */}
          <div className="space-y-2">
            <label className="text-sm font-medium text-on-surface">{t('equipment', lang)}</label>
            <div className="grid grid-cols-2 gap-2">
              {(['none', 'essentials', 'free_weights', 'full_gym'] as const).map((level) => (
                <button
                  key={level}
                  onClick={() => setAIEquipment(level)}
                  disabled={aiLoading}
                  className={`p-3 rounded-xl text-sm font-medium transition-all ${aiEquipment === level
                    ? 'bg-primary text-on-primary'
                    : 'bg-surface-container-high text-on-surface hover:bg-surface-container-highest'
                    }`}
                >
                  {t(`equipment_${level}` as any, lang)}
                </button>
              ))}
            </div>
          </div>

          {/* Level Selector */}
          <div className="space-y-2">
            <label className="text-sm font-medium text-on-surface">{t('level', lang)}</label>
            <div className="flex gap-2">
              {(['beginner', 'intermediate', 'advanced'] as const).map((lvl) => (
                <button
                  key={lvl}
                  onClick={() => setAILevel(lvl)}
                  disabled={aiLoading}
                  className={`flex-1 p-2 rounded-xl text-sm font-medium transition-all ${aiLevel === lvl
                    ? 'bg-primary text-on-primary'
                    : 'bg-surface-container-high text-on-surface hover:bg-surface-container-highest'
                    }`}
                >
                  {t(`level_${lvl}` as any, lang)}
                </button>
              ))}
            </div>
          </div>

          {/* Intensity Selector */}
          <div className="space-y-2">
            <label className="text-sm font-medium text-on-surface">{t('intensity', lang)}</label>
            <div className="flex gap-2">
              {(['low', 'moderate', 'high'] as const).map((int) => (
                <button
                  key={int}
                  onClick={() => setAIIntensity(int)}
                  disabled={aiLoading}
                  className={`flex-1 p-2 rounded-xl text-sm font-medium transition-all ${aiIntensity === int
                    ? 'bg-primary text-on-primary'
                    : 'bg-surface-container-high text-on-surface hover:bg-surface-container-highest'
                    }`}
                >
                  {t(`intensity_${int}` as any, lang)}
                </button>
              ))}
            </div>
          </div>

          {/* Additional Requirements */}
          <div className="space-y-2">
            <label className="text-sm font-medium text-on-surface">
              {lang === 'ru' ? 'Дополнительные требования' : 'Additional requirements'}
            </label>
            <textarea
              className="w-full h-20 p-3 bg-surface-container-high rounded-xl text-on-surface resize-none focus:outline-none focus:ring-2 focus:ring-primary text-sm"
              placeholder={t('ai_plan_prompt_placeholder', lang)}
              value={aiPrompt}
              onChange={(e) => setAIPrompt(e.target.value)}
              disabled={aiLoading}
            />
          </div>

          {/* Error Display */}
          {aiError && (
            <div className="p-3 bg-error-container text-on-error-container rounded-lg text-sm">
              {aiError}
            </div>
          )}

          {/* Generated Plan Preview */}
          {generatedPlanPreview && (
            <div className="space-y-3 p-4 bg-surface-container rounded-xl border border-outline-variant">
              <div className="text-xs font-bold text-primary">{t('ai_generated_plan', lang)}</div>
              <h3 className="text-lg font-medium text-on-surface">{generatedPlanPreview.name}</h3>
              {generatedPlanPreview.description && (
                <p className="text-sm text-on-surface-variant">{generatedPlanPreview.description}</p>
              )}
              <div className="space-y-1">
                {generatedPlanPreview.exercises.map((ex, idx) => (
                  <div key={idx} className="flex items-center gap-2 text-sm py-1 border-b border-outline-variant/30 last:border-0">
                    <span className="w-6 h-6 flex items-center justify-center text-xs font-bold bg-primary-container text-on-primary-container rounded-full">{idx + 1}</span>
                    <span className="text-on-surface">{ex.name}</span>
                    {ex.isWeighted && <Dumbbell size={14} className="text-on-surface-variant" />}
                  </div>
                ))}
              </div>
            </div>
          )}

          {/* Action Buttons */}
          <div className="flex justify-end gap-2 pt-2">
            {!generatedPlanPreview ? (
              <>
                <Button
                  onClick={() => {
                    setShowAISheet(false);
                    setAIPrompt('');
                    setAIError(null);
                    setGeneratedPlanPreview(null);
                  }}
                  variant="ghost"
                  disabled={aiLoading}
                >
                  {t('cancel', lang)}
                </Button>
                <Button
                  onClick={handleGenerateAIPlan}
                  disabled={aiLoading}
                  className="flex items-center gap-2"
                >
                  {aiLoading && <Loader2 size={16} className="animate-spin" />}
                  {t('generate', lang)}
                </Button>
              </>
            ) : (
              <>
                <Button
                  onClick={handleGenerateAIPlan}
                  variant="ghost"
                  disabled={aiLoading}
                  className="flex items-center gap-2"
                >
                  {aiLoading && <Loader2 size={16} className="animate-spin" />}
                  {t('generate', lang)}
                </Button>
                <Button
                  onClick={handleSaveAIPlan}
                  disabled={aiLoading}
                  className="flex items-center gap-2"
                >
                  {aiLoading && <Loader2 size={16} className="animate-spin" />}
                  {t('save_plan', lang)}
                </Button>
              </>
            )}
          </div>
        </div>
      </SideSheet>

      {/* Preparation Modal */}
      {showPlanPrep && (
        <SideSheet
          isOpen={!!showPlanPrep}
          onClose={() => setShowPlanPrep(null)}
          title={showPlanPrep.name}
          width="md"
        >
          <div className="space-y-8">
            <div className="bg-surface-container-high p-4 rounded-xl text-on-surface-variant text-sm">
              <div className="text-xs font-bold text-primary mb-2">{t('prep_title', lang)}</div>
              {showPlanPrep.description || t('prep_no_instructions', lang)}
            </div>
            <div className="flex justify-end gap-2">
              <Button onClick={() => setShowPlanPrep(null)} variant="ghost">{t('cancel', lang)}</Button>
              <Button onClick={confirmPlanStart}>{t('start', lang)}</Button>
            </div>
          </div>
        </SideSheet>
      )}
    </div>
  );
};

export default Plans;