import React, { useState, useEffect } from 'react';
import { Plus, Trash2, PlayCircle, Dumbbell, Save, X, ChevronRight, List, ArrowUp, ArrowDown, Edit2, User, Flame, Timer as TimerIcon, Ruler, Footprints, Activity, Percent, CheckCircle, GripVertical, Scale, Search } from 'lucide-react';
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';

interface PlansProps {
  lang: Language;
}

const Plans: React.FC<PlansProps> = ({ lang }) => {
  const { currentUser } = useAuth();
  const userId = currentUser?.id || '';
  const { plans, 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[]>([]);

  const [availableExercises, setAvailableExercises] = useState<ExerciseDef[]>([]);
  const [showExerciseSelector, setShowExerciseSelector] = useState(false);

  // Drag and Drop Refs
  const dragItem = React.useRef<number | null>(null);
  const [draggingIndex, setDraggingIndex] = useState<number | null>(null);

  // Create Exercise State
  const [isCreatingExercise, setIsCreatingExercise] = useState(false);
  const [newExName, setNewExName] = useState('');
  const [newExType, setNewExType] = useState<ExerciseType>(ExerciseType.STRENGTH);
  const [newExBwPercentage, setNewExBwPercentage] = useState<string>('100');

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

  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);
  };

  const handleSave = async () => {
    if (!name.trim() || !editId) return;
    const newPlan: WorkoutPlan = { id: editId, name, description, steps };
    await savePlan(newPlan);
    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 handleCreateExercise = async () => {
    if (!newExName.trim()) return;
    const newEx: ExerciseDef = {
      id: generateId(),
      name: newExName.trim(),
      type: newExType,
      ...(newExType === ExerciseType.BODYWEIGHT && { bodyWeightPercentage: parseFloat(newExBwPercentage) || 100 })
    };
    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);

    setNewExName('');
    setNewExType(ExerciseType.STRENGTH);
    setNewExBwPercentage('100');
    setIsCreatingExercise(false);
  };

  const exerciseTypeLabels: Record<ExerciseType, string> = {
    [ExerciseType.STRENGTH]: t('type_strength', lang),
    [ExerciseType.BODYWEIGHT]: t('type_bodyweight', lang),
    [ExerciseType.CARDIO]: t('type_cardio', lang),
    [ExerciseType.STATIC]: t('type_static', lang),
    [ExerciseType.HIGH_JUMP]: t('type_height', lang),
    [ExerciseType.LONG_JUMP]: t('type_dist', lang),
    [ExerciseType.PLYOMETRIC]: t('type_jump', lang),
  };

  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));
  };

  const onDragStart = (index: number) => {
    console.log('Drag Start:', index);
    dragItem.current = index;
    setDraggingIndex(index);
  };
  const onDragEnter = (index: number) => {
    console.log('Drag Enter:', index);
    if (dragItem.current === null) return;
    if (dragItem.current === index) return;

    const newSteps = [...steps];
    const draggedItemContent = newSteps.splice(dragItem.current, 1)[0];
    newSteps.splice(index, 0, draggedItemContent);

    setSteps(newSteps);
    dragItem.current = index;
    setDraggingIndex(index);
    console.log(`Swapped ${draggedItemContent.id} to ${index}`);
  };

  const onDragEnd = () => {
    dragItem.current = null;
    setDraggingIndex(null);
  };

  if (isEditing) {
    return (
      <div className="h-full flex flex-col bg-surface">
        <div className="px-4 py-3 bg-surface-container border-b border-outline-variant flex justify-between items-center shrink-0">
          <Button onClick={() => setIsEditing(false)} variant="ghost" size="icon">
            <X size={20} />
          </Button>
          <h2 className="text-title-medium font-medium text-on-surface">{t('plan_editor', lang)}</h2>
          <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))}
          />

          <div className="bg-surface-container-high rounded-t-lg border-b border-outline-variant px-4 py-2">
            <label className="text-[10px] text-on-surface-variant font-medium">{t('prep_title', lang)}</label>
            <textarea
              className="w-full bg-transparent text-base text-on-surface focus:outline-none pt-1 pb-2 min-h-[80px]"
              placeholder={t('plan_desc_ph', lang)}
              value={description}
              onChange={(e) => setDescription(e.target.value)}
            />
          </div>

          <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">
              {steps.map((step, idx) => (
                <Card
                  key={step.id}
                  className={`flex items-center gap-3 transition-all hover:bg-surface-container-high ${draggingIndex === idx ? 'opacity-50 ring-2 ring-primary bg-surface-container-high' : ''}`}
                  draggable
                  onDragStart={() => onDragStart(idx)}
                  onDragEnter={() => onDragEnter(idx)}
                  onDragOver={(e) => e.preventDefault()}
                  onDragEnd={onDragEnd}
                >
                  <div className={`text-on-surface-variant p-1 ${draggingIndex === idx ? 'cursor-grabbing' : 'cursor-grab'}`}>
                    <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">
                    {idx + 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">
                    <X size={20} />
                  </Button>
                </Card>
              ))}
            </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>

        <Modal
          isOpen={showExerciseSelector}
          onClose={() => setShowExerciseSelector(false)}
          title={t('select_exercise', lang)}
          maxWidth="md"
        >
          <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>
        </Modal>

        <Modal
          isOpen={isCreatingExercise}
          onClose={() => setIsCreatingExercise(false)}
          title={t('create_exercise', lang)}
          maxWidth="md"
        >
          <div className="space-y-6 pt-2">
            <FilledInput
              label={t('ex_name', lang)}
              value={newExName}
              onChange={(e: any) => setNewExName(e.target.value)}
              type="text"
              autoFocus
              autocapitalize="words"
              onBlur={() => setNewExName(toTitleCase(newExName))}
            />

            <div>
              <label className="block text-xs text-on-surface-variant font-medium mb-3">{t('ex_type', lang)}</label>
              <div className="flex flex-wrap gap-2">
                {[
                  { id: ExerciseType.STRENGTH, label: exerciseTypeLabels[ExerciseType.STRENGTH], icon: Dumbbell },
                  { id: ExerciseType.BODYWEIGHT, label: exerciseTypeLabels[ExerciseType.BODYWEIGHT], icon: User },
                  { id: ExerciseType.CARDIO, label: exerciseTypeLabels[ExerciseType.CARDIO], icon: Flame },
                  { id: ExerciseType.STATIC, label: exerciseTypeLabels[ExerciseType.STATIC], icon: TimerIcon },
                  { id: ExerciseType.HIGH_JUMP, label: exerciseTypeLabels[ExerciseType.HIGH_JUMP], icon: ArrowUp },
                  { id: ExerciseType.LONG_JUMP, label: exerciseTypeLabels[ExerciseType.LONG_JUMP], icon: Ruler },
                  { id: ExerciseType.PLYOMETRIC, label: exerciseTypeLabels[ExerciseType.PLYOMETRIC], icon: Footprints },
                ].map((type) => (
                  <button
                    key={type.id}
                    onClick={() => setNewExType(type.id)}
                    className={`px-4 py-2 rounded-lg flex items-center gap-2 text-xs font-medium border transition-all ${newExType === type.id
                      ? 'bg-secondary-container text-on-secondary-container border-transparent'
                      : 'bg-transparent text-on-surface-variant border-outline hover:border-on-surface-variant'
                      }`}
                  >
                    <type.icon size={14} /> {type.label}
                  </button>
                ))}
              </div>
            </div>

            {newExType === ExerciseType.BODYWEIGHT && (
              <FilledInput
                label={t('body_weight_percent', lang)}
                value={newExBwPercentage}
                onChange={(e: any) => setNewExBwPercentage(e.target.value)}
                icon={<Percent size={12} />}
              />
            )}

            <div className="flex justify-end mt-6">
              <Button
                onClick={handleCreateExercise}
                fullWidth
                size="lg"
              >
                <CheckCircle size={20} className="mr-2" />
                {t('create_btn', lang)}
              </Button>
            </div>
          </div>
        </Modal>
      </div>
    );
  }



  return (
    <div className="h-full flex flex-col bg-surface relative">
      <div className="p-4 bg-surface-container shadow-elevation-1 z-10 shrink-0">
        <h2 className="text-2xl font-normal text-on-surface">{t('my_plans', lang)}</h2>
      </div>

      <div className="flex-1 p-4 overflow-y-auto space-y-4 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-lg">{t('plans_empty', lang)}</p>
          </div>
        ) : (
          plans.map(plan => (
            <Card key={plan.id} className="relative overflow-hidden">
              <div className="flex justify-between items-start mb-2">
                <h3 className="text-xl font-normal text-on-surface">{plan.name}</h3>
                <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-white/5"
                >
                  <Trash2 size={20} />
                </Button>
              </div>
              <div className="absolute top-4 right-14">
                <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-white/5"
                >
                  <Edit2 size={20} />
                </Button>
              </div>
              <p className="text-on-surface-variant text-sm line-clamp-2 mb-4 min-h-[1.25rem]">
                {plan.description || t('prep_no_instructions', lang)}
              </p>
              <div className="flex items-center justify-between">
                <div className="text-xs 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>

      {/* FAB */}
      <button
        onClick={handleCreateNew}
        aria-label="Create Plan"
        className="absolute bottom-6 right-6 w-14 h-14 bg-primary-container text-on-primary-container rounded-[16px] shadow-elevation-3 flex items-center justify-center hover:bg-primary hover:text-on-primary transition-colors z-20"
      >
        <Plus size={28} />
      </button>

      {/* Preparation Modal */}
      {showPlanPrep && (
        <div className="fixed inset-0 bg-black/60 z-50 flex items-center justify-center p-6 backdrop-blur-sm">
          <div className="w-full max-w-sm bg-surface-container rounded-[28px] p-6 shadow-elevation-3">
            <h3 className="text-2xl font-normal text-on-surface mb-4">{showPlanPrep.name}</h3>
            <div className="bg-surface-container-high p-4 rounded-xl text-on-surface-variant text-sm mb-8">
              <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)} className="px-6 py-2.5 rounded-full text-primary font-medium hover:bg-white/5">{t('cancel', lang)}</button>
              <button onClick={confirmPlanStart} className="px-6 py-2.5 rounded-full bg-primary text-on-primary font-medium">{t('start', lang)}</button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
};

export default Plans;