import { useState, useEffect, type FormEvent } from "react";
import { useNavigate, useParams, Link } from "react-router";
import { ProtectedRoute } from "~/components/ProtectedRoute";
import { Button } from "~/components/Button";
import { Input } from "~/components/Input";
import { GradingCategorySelector } from "~/components/GradingCategorySelector";
import { LoadingSpinner } from "~/components/LoadingSpinner";
import { api } from "~/api/client";
import type { Subject, GradingCategory } from "~/types/api";
import { GRADE_SYSTEMS, type GradeSystem } from "~/utils/gradeSystems";

const getMaxGradeForSystem = (system: GradeSystem): string => {
  switch (system) {
    case "german":
      return "6";
    case "us-letter":
    case "percentage":
    default:
      return "100";
  }
};

export default function EditSubject() {
  const navigate = useNavigate();
  const params = useParams();
  const subjectId = params.subjectId;

  const [subject, setSubject] = useState<Subject | null>(null);
  const [name, setName] = useState("");
  const [teacher, setTeacher] = useState("");
  const [color, setColor] = useState("#3b82f6");
  const [gradeSystem, setGradeSystem] = useState<GradeSystem>("percentage");
  const [targetGrade, setTargetGrade] = useState("");
  const [targetMaxGrade, setTargetMaxGrade] = useState("");
  const [categories, setCategories] = useState<GradingCategory[]>([]);
  const [error, setError] = useState("");
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);

  useEffect(() => {
    const fetchSubject = async () => {
      if (!subjectId) {
        setError("Invalid subject ID");
        setLoading(false);
        return;
      }

      try {
        const subjects = await api.getSubjects();
        const foundSubject = subjects.find((s) => s._id === subjectId);

        if (!foundSubject) {
          setError("Subject not found");
          setLoading(false);
          return;
        }

        setSubject(foundSubject);
        setName(foundSubject.name);
        setTeacher(foundSubject.teacher || "");
        setColor(foundSubject.color ?? "#3b82f6");
        setGradeSystem((foundSubject.grade_system as GradeSystem) || "percentage");
        setTargetGrade(foundSubject.target_grade?.toString() || "");
        setTargetMaxGrade(foundSubject.target_grade_max?.toString() || "");
        setCategories(foundSubject.grading_categories);
        setLoading(false);
      } catch (err) {
        setError(err instanceof Error ? err.message : "Failed to fetch subject");
        setLoading(false);
      }
    };

    fetchSubject();
  }, [subjectId]);
  
  // Auto-update max grade when grade system changes
  useEffect(() => {
    setTargetMaxGrade(getMaxGradeForSystem(gradeSystem));
  }, [gradeSystem]);

  const handleSubmit = async (e: FormEvent) => {
    e.preventDefault();
    setError("");

    if (!name.trim()) {
      setError("Subject name is required");
      return;
    }

    if (categories.length === 0) {
      setError("Add at least one grading category");
      return;
    }

    const totalWeight = categories.reduce((sum, cat) => sum + cat.weight, 0);
    if (Math.abs(totalWeight - 100) > 0.01) {
      setError("Category weights must sum to 100%");
      return;
    }

    if (categories.some((cat) => !cat.name.trim())) {
      setError("All categories must have a name");
      return;
    }

    if (!subjectId) {
      setError("Invalid subject ID");
      return;
    }

    setSaving(true);

    try {
      await api.updateSubject(subjectId, {
        name: name.trim(),
        teacher: teacher.trim() || undefined,
        color,
        grade_system: gradeSystem,
        grading_categories: categories,
        target_grade: targetGrade ? parseFloat(targetGrade) : undefined,
        target_grade_max: targetMaxGrade ? parseFloat(targetMaxGrade) : undefined,
      });
      navigate(`/subjects/${subjectId}`);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to update subject");
    } finally {
      setSaving(false);
    }
  };

  if (loading) {
    return (
      <ProtectedRoute>
        <div className="min-h-screen bg-gray-50 flex items-center justify-center">
          <LoadingSpinner />
        </div>
      </ProtectedRoute>
    );
  }

  if (error && !subject) {
    return (
      <ProtectedRoute>
        <div className="min-h-screen bg-gray-50 flex items-center justify-center">
          <div className="bg-red-50 border border-red-200 text-red-700 px-6 py-4 rounded-lg">
            {error}
          </div>
        </div>
      </ProtectedRoute>
    );
  }

  return (
    <ProtectedRoute>
      <div className="min-h-screen bg-gray-50">
        <header className="bg-white shadow-sm border-b">
          <div className="max-w-3xl mx-auto px-4 sm:px-6 lg:px-8 py-4">
            <Link
              to={`/subjects/${subjectId}`}
              className="text-blue-600 hover:text-blue-700 text-sm"
            >
              ← Back to {subject?.name || "Subject"}
            </Link>
            <h1 className="text-2xl font-bold text-gray-900 mt-1">Edit Subject</h1>
          </div>
        </header>

        <main className="max-w-3xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
          <div className="bg-white rounded-lg shadow p-6">
            <form onSubmit={handleSubmit} className="space-y-6">
              <Input
                label="Subject Name"
                value={name}
                onChange={(e) => setName(e.target.value)}
                placeholder="e.g., Mathematics, English, Biology"
                required
              />

              <Input
                label="Teacher (Optional)"
                value={teacher}
                onChange={(e) => setTeacher(e.target.value)}
                placeholder="e.g., Mrs. Smith"
              />

              <div>
                <label className="block text-sm font-medium text-gray-700 mb-2">
                  Subject Color
                </label>
                <input
                  type="color"
                  value={color}
                  onChange={(e) => setColor(e.target.value)}
                  className="w-20 h-10 rounded cursor-pointer border border-gray-300"
                />
              </div>

              <div>
                <label className="block text-sm font-medium text-gray-700 mb-2">
                  Grade Display System
                </label>
                <select
                  value={gradeSystem}
                  onChange={(e) => setGradeSystem(e.target.value as GradeSystem)}
                  className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500"
                >
                  {Object.entries(GRADE_SYSTEMS).map(([key, system]) => (
                    <option key={key} value={key}>
                      {system.displayName} - {system.description}
                    </option>
                  ))}
                </select>
                <p className="text-xs text-gray-500 mt-1">
                  Choose how grades will be displayed for this subject
                </p>
              </div>

              <GradingCategorySelector
                categories={categories}
                onChange={setCategories}
              />

              <div className="border-t pt-6">
                <h3 className="text-sm font-medium text-gray-700 mb-4">
                  Target Grade (Optional)
                </h3>
                <div className="grid grid-cols-2 gap-4">
                  <Input
                    label="Target Grade"
                    type="number"
                    step="0.01"
                    value={targetGrade}
                    onChange={(e) => setTargetGrade(e.target.value)}
                    placeholder={gradeSystem === "german" ? "e.g., 2.0" : "e.g., 85"}
                  />
                  <div>
                    <label className="block text-sm font-medium text-gray-700 mb-2">
                      Max Grade
                    </label>
                    <div className="px-3 py-2 border border-gray-300 rounded-lg bg-gray-50 text-gray-700">
                      {targetMaxGrade}
                    </div>
                    <p className="text-xs text-gray-500 mt-1">
                      Auto-set by grade system
                    </p>
                  </div>
                </div>
                <p className="text-xs text-gray-500 mt-2">
                  Set a target grade to track your progress. Leave empty if not needed.
                </p>
              </div>

              <div>
                <label className="block text-sm font-medium text-gray-700 mb-2">
                  Grade Display System
                </label>
                <select
                  value={gradeSystem}
                  onChange={(e) => setGradeSystem(e.target.value as GradeSystem)}
                  className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500"
                >
                  {Object.entries(GRADE_SYSTEMS).map(([key, system]) => (
                    <option key={key} value={key}>
                      {system.displayName} - {system.description}
                    </option>
                  ))}
                </select>
                <p className="text-xs text-gray-500 mt-1">
                  Choose how grades will be displayed for this subject
                </p>
              </div>

              <div>
                <GradingCategorySelector
                  categories={categories}
                  onChange={setCategories}
                />
                <p className="text-xs text-gray-500 mt-2">
                  ⚠️ Changing categories may affect how existing grades are calculated
                </p>
              </div>

              {error && (
                <div className="bg-red-50 border border-red-200 text-red-700 px-4 py-3 rounded">
                  {error}
                </div>
              )}

              <div className="flex gap-3">
                <Button type="submit" disabled={saving} className="flex-1">
                  {saving ? "Saving..." : "Save Changes"}
                </Button>
                <Link to={`/subjects/${subjectId}`} className="flex-1">
                  <Button type="button" variant="secondary" className="w-full">
                    Cancel
                  </Button>
                </Link>
              </div>
            </form>
          </div>
        </main>
      </div>
    </ProtectedRoute>
  );
}
