import { useState, useEffect, ReactNode } from "react";
import { router } from "@inertiajs/react";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { RichTextEditor } from "@/components/ui/rich-text-editor";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { toast } from "sonner";
import { ArrowLeft, Upload, X as XIcon, Loader2 } from "lucide-react";
import SectionHeader from "@/components/admin/course-form/SectionHeader";
import DynamicListField from "@/components/admin/course-form/DynamicListField";
import VenueScheduleGrid, { type ScheduleEntry } from "@/components/admin/course-form/VenueScheduleGrid";
import TrainerAssignmentsDialog from "@/components/admin/course-form/TrainerAssignmentsDialog";
import AdminLayout from "@/layouts/AdminLayout";
import { useCategories } from "@/hooks/useCategories";

const csrfToken = () => (document.querySelector('meta[name="csrf-token"]') as HTMLMetaElement | null)?.content ?? '';

/**
 * Thumbnail picker — accepts either a URL paste or a file upload. Uploaded
 * files go through POST /api/admin/upload/image and the returned public URL
 * becomes the field value (so the form save is unchanged).
 */
const ThumbnailUploader = ({
  value,
  onChange,
}: {
  value: string;
  onChange: (url: string) => void;
}) => {
  const [uploading, setUploading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const handleFile = async (file: File | null) => {
    if (!file) return;
    setError(null);
    setUploading(true);
    try {
      const fd = new FormData();
      fd.append("file", file);
      fd.append("folder", "course-thumbnails");
      const res = await fetch("/api/admin/upload/image", {
        method: "POST",
        headers: {
          "Accept": "application/json",
          "X-Requested-With": "XMLHttpRequest",
          "X-CSRF-TOKEN": csrfToken(),
        },
        body: fd,
      });
      if (!res.ok) {
        const data = await res.json().catch(() => null);
        throw new Error(data?.message || data?.error || "Upload failed");
      }
      const data = await res.json();
      if (!data?.url) throw new Error("Upload did not return a URL");
      onChange(data.url);
    } catch (e: any) {
      setError(e.message || "Upload failed");
      toast.error(e.message || "Upload failed");
    } finally {
      setUploading(false);
    }
  };

  return (
    <div className="space-y-2">
      <div className="flex gap-2">
        <Input
          value={value}
          onChange={(e) => onChange(e.target.value)}
          placeholder="Upload an image or paste a URL"
          className="flex-1"
        />
        <label className="inline-flex items-center gap-1.5 h-10 px-3 rounded-md border border-input bg-background text-sm font-medium cursor-pointer hover:bg-accent hover:text-accent-foreground transition-colors">
          {uploading ? (
            <Loader2 className="w-4 h-4 animate-spin" />
          ) : (
            <Upload className="w-4 h-4" />
          )}
          {uploading ? "Uploading…" : "Upload"}
          <input
            type="file"
            accept="image/png,image/jpeg,image/webp,image/gif"
            className="hidden"
            disabled={uploading}
            onChange={(e) => {
              const file = e.target.files?.[0] ?? null;
              handleFile(file);
              // reset so re-uploading the same file fires onChange again
              e.target.value = "";
            }}
          />
        </label>
      </div>
      {error && <p className="text-xs text-destructive">{error}</p>}
      {value && (
        <div className="relative inline-block">
          <img
            src={value}
            alt="Thumbnail preview"
            className="h-24 w-auto max-w-[260px] object-cover rounded-md border border-border"
            onError={(e) => { (e.target as HTMLImageElement).style.display = "none"; }}
          />
          <button
            type="button"
            onClick={() => onChange("")}
            title="Remove image"
            className="absolute -top-2 -right-2 bg-background border border-border rounded-full p-0.5 shadow-sm hover:bg-destructive hover:text-destructive-foreground transition-colors"
          >
            <XIcon className="w-3 h-3" />
          </button>
        </div>
      )}
    </div>
  );
};

/**
 * Price field that stores cents in form state but lets the user type freely.
 * The previous inline implementation reformatted the value to `.toFixed(2)` on
 * every keystroke, which fought the cursor and made typing partial values
 * (e.g. ".5", "45.", "45.5") impossible.
 */
const PriceInput = ({
  cents,
  onCentsChange,
  placeholder,
}: {
  cents: number;
  onCentsChange: (cents: number) => void;
  placeholder?: string;
}) => {
  const [text, setText] = useState(cents > 0 ? (cents / 100).toFixed(2) : "");
  // Reflect external updates (course load, VideoTile RRP autofill) but stay
  // out of the way when the user is mid-typing — only resync if the typed
  // value doesn't already represent the same number of cents.
  useEffect(() => {
    const expected = cents > 0 ? (cents / 100).toFixed(2) : "";
    const typedCents = Math.round((parseFloat(text || "0") || 0) * 100);
    if (typedCents !== cents) setText(expected);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [cents]);

  return (
    <Input
      type="text"
      inputMode="decimal"
      value={text}
      onChange={(e) => {
        const raw = e.target.value;
        // Allow empty, digits, single decimal point, up to 2 decimal places.
        if (raw !== "" && !/^\d*\.?\d{0,2}$/.test(raw)) return;
        setText(raw);
        onCentsChange(Math.round((parseFloat(raw) || 0) * 100));
      }}
      onBlur={() => {
        if (text === "") return;
        const n = parseFloat(text);
        if (!isNaN(n)) setText(n.toFixed(2));
      }}
      placeholder={placeholder}
    />
  );
};

const emptyForm = {
  title: "",
  slug: "",
  category: "E-Learning",
  category_href: "/courses",
  sub_category: "",
  description: "",
  days: 1,
  duration_minutes: null as number | null,
  price_cents: 0,
  original_price_cents: 0,
  is_active: true,
  is_featured: false,
  has_certificate: false,
  image_url: "",
  level: "All Levels",
  language: "English",
  capacity: null as number | null,
  who_attends: "",
  course_content: "",
  certification: "",
  ppe_requirements: "" as string,
  location_name: "",
  location_details: "",
  facilities: "",
  videotile_course_id: null as number | null,
};

const levelOptions = ["All Levels", "Beginner", "Intermediate", "Advanced"];

// Parse a JSON array string or return empty array
const parseJsonArray = (val: string | null): string[] => {
  if (!val) return [];
  try {
    const parsed = JSON.parse(val);
    return Array.isArray(parsed) ? parsed : [];
  } catch {
    return val ? [val] : [];
  }
};

const toJsonString = (arr: string[]): string => {
  const filtered = arr.filter(Boolean);
  return filtered.length > 0 ? JSON.stringify(filtered) : "";
};

interface CourseFormProps {
  id?: string;
}

const CourseForm = ({ id: idProp }: CourseFormProps) => {
  // Read id from prop or URL pathname (e.g. /admin/courses/123/edit)
  const pathParts = typeof window !== 'undefined' ? window.location.pathname.split('/').filter(Boolean) : [];
  const idFromPath = pathParts.length >= 4 && pathParts[pathParts.length - 1] === 'edit' ? pathParts[pathParts.length - 2] : undefined;
  const id = idProp ?? idFromPath;
  const queryClient = useQueryClient();
  const isEditing = Boolean(id);
  const { data: mainCategories = [] } = useCategories("main");
  const { data: subCategories = [] } = useCategories("sub");
  const [form, setForm] = useState(emptyForm);
  const [instructorIds, setInstructorIds] = useState<string[]>([]);
  const [ppeItems, setPpeItems] = useState<string[]>([""]);
  const [moduleItems, setModuleItems] = useState<string[]>([""]);
  const [venueIds, setVenueIds] = useState<string[]>([]);
  const [schedules, setSchedules] = useState<ScheduleEntry[]>([]);

  const { data: course, isLoading } = useQuery({
    queryKey: ["course", id],
    queryFn: async () => {
      if (!id) return null;
      const res = await fetch(`/api/admin/courses/${id}`);
      if (!res.ok) return null;
      return res.json();
    },
    enabled: isEditing,
  });

  // Fetch existing instructors
  const { data: existingTrainers } = useQuery({
    queryKey: ["course-trainers", id],
    queryFn: async () => {
      const res = await fetch(`/api/admin/courses/${id}/trainers`);
      if (!res.ok) return [];
      const data = await res.json();
      return Array.isArray(data) ? data.map((ct: any) => ct.trainer_id) : [];
    },
    enabled: isEditing,
  });

  // Fetch existing venue schedules
  const { data: existingSchedules } = useQuery({
    queryKey: ["course-venue-schedules", id],
    queryFn: async () => {
      const res = await fetch(`/api/admin/courses/${id}/venue-schedules`);
      if (!res.ok) return [];
      return res.json();
    },
    enabled: isEditing,
  });

  useEffect(() => {
    if (course) {
      setForm({
        title: course.title,
        slug: course.slug,
        category: course.category,
        category_href: course.category_href,
        sub_category: (course as any).sub_category || "",
        description: course.description || "",
        days: course.days,
        duration_minutes: (course as any).duration_minutes || null,
        price_cents: course.price_cents,
        original_price_cents: (course as any).original_price_cents || 0,
        is_active: course.is_active,
        is_featured: (course as any).is_featured || false,
        has_certificate: (course as any).has_certificate || false,
        image_url: course.image_url || "",
        level: (course as any).level || "All Levels",
        language: (course as any).language || "English",
        capacity: (course as any).capacity || null,
        who_attends: course.who_attends || "",
        course_content: course.course_content || "",
        certification: course.certification || "",
        ppe_requirements: course.ppe_requirements || "",
        location_name: course.location_name || "",
        location_details: course.location_details || "",
        facilities: course.facilities || "",
        videotile_course_id: (course as any).videotile_course_id || null,
      });
      setPpeItems(parseJsonArray(course.ppe_requirements).length > 0 ? parseJsonArray(course.ppe_requirements) : [""]);
      setModuleItems(parseJsonArray(course.course_content).length > 0 ? parseJsonArray(course.course_content) : [""]);
    }
  }, [course]);

  // VT-picker entry path: /admin/courses/new?vt=<vt-course-id>
  // Pre-fill title / description / duration / RRP from the VT catalog so
  // admin lands in an edited-ready form instead of a blank one.
  useEffect(() => {
    if (isEditing) return;
    const sp = new URLSearchParams(window.location.search);
    const vtIdRaw = sp.get('vt');
    const vtId = vtIdRaw ? Number(vtIdRaw) : null;
    if (!vtId || Number.isNaN(vtId)) return;

    let cancelled = false;
    (async () => {
      try {
        const res = await fetch(`/api/admin/videotile/catalog/${vtId}`);
        if (!res.ok) {
          toast.error('Could not load VideoTile course details');
          return;
        }
        const vt = await res.json();
        if (cancelled) return;
        setForm((prev) => ({
          ...prev,
          title: vt.name || prev.title,
          slug: generateSlug(vt.name || ''),
          category: 'E-Learning',
          description: vt.description || prev.description,
          duration_minutes: vt.duration_minutes ?? prev.duration_minutes,
          price_cents: vt.rrp_cents ?? prev.price_cents,
          videotile_course_id: vt.id,
          // Sensible defaults for VT courses — they're online so most
          // classroom-only fields don't apply.
          days: 1,
          has_certificate: true,
        }));
      } catch (e) {
        toast.error('Failed to fetch VideoTile course');
      }
    })();
    return () => { cancelled = true; };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  // Refresh-from-VideoTile button on the edit form. Pulls fresh metadata
  // but does NOT overwrite the price — local copy is authoritative once an
  // admin has set their margin.
  const refreshFromVideoTile = async () => {
    if (!form.videotile_course_id) return;
    try {
      const res = await fetch(`/api/admin/videotile/catalog/${form.videotile_course_id}`);
      if (!res.ok) throw new Error('VideoTile returned an error');
      const vt = await res.json();
      setForm((prev) => ({
        ...prev,
        title: vt.name || prev.title,
        description: vt.description || prev.description,
        duration_minutes: vt.duration_minutes ?? prev.duration_minutes,
      }));
      toast.success('Refreshed from VideoTile (price unchanged)');
    } catch (e) {
      toast.error('Could not refresh from VideoTile');
    }
  };

  useEffect(() => {
    if (existingTrainers) setInstructorIds(existingTrainers);
  }, [existingTrainers]);

  useEffect(() => {
    if (existingSchedules && existingSchedules.length > 0) {
      const uniqueVenues = [...new Set(existingSchedules.map((s: any) => s.venue_id))] as string[];
      setVenueIds(uniqueVenues);
      setSchedules(existingSchedules.map((s: any) => ({
        venue_id: s.venue_id,
        resource_type: s.resource_type,
        resource_id: s.resource_id,
        day_number: s.day_number,
        session: s.session,
      })));
    }
  }, [existingSchedules]);

  const generateSlug = (title: string) =>
    title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "");

  const saveMutation = useMutation({
    mutationFn: async (values: typeof form) => {
      const payload = {
        title: values.title,
        slug: values.slug,
        category: values.category,
        category_href: values.category_href,
        sub_category: values.sub_category || null,
        description: values.description || null,
        days: values.days,
        duration_minutes: values.duration_minutes,
        price_cents: values.price_cents,
        original_price_cents: values.original_price_cents,
        is_active: values.is_active,
        is_featured: values.is_featured,
        has_certificate: values.has_certificate,
        image_url: values.image_url || null,
        level: values.level,
        language: values.language,
        capacity: values.capacity,
        who_attends: values.who_attends || null,
        course_content: toJsonString(moduleItems) || null,
        certification: values.certification || null,
        ppe_requirements: toJsonString(ppeItems) || null,
        location_name: values.location_name || null,
        location_details: values.location_details || null,
        facilities: values.facilities || null,
        videotile_course_id: values.videotile_course_id,
        schedules,
      };

      const jsonHeaders = {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
        'X-Requested-With': 'XMLHttpRequest',
        'X-CSRF-TOKEN': csrfToken(),
      };
      const url = isEditing ? `/api/admin/courses/${id}` : '/api/admin/courses';
      const res = await fetch(url, {
        method: isEditing ? 'PUT' : 'POST',
        headers: jsonHeaders,
        body: JSON.stringify(payload),
      });
      if (!res.ok) {
        const data = await res.json().catch(() => null);
        const firstValidation = data?.errors
          ? (Object.values(data.errors)[0] as string[] | undefined)?.[0]
          : undefined;
        throw new Error(
          firstValidation || data?.message || data?.error || `Failed to ${isEditing ? 'update' : 'create'} course`,
        );
      }
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["admin-courses"] });
      queryClient.invalidateQueries({ queryKey: ["public-courses"] });
      queryClient.invalidateQueries({ queryKey: ["nrswa-courses"] });
      toast.success(isEditing ? "Course updated" : "Course added");
      router.visit("/admin/courses");
    },
    onError: (e: Error) => toast.error(e.message),
  });

  if (isEditing && isLoading) {
    return <p className="text-muted-foreground">Loading course...</p>;
  }

  return (
    <div>
      <div className="flex items-center gap-3 mb-6">
        <Button variant="ghost" size="sm" onClick={() => router.visit("/admin/courses")}>
          <ArrowLeft className="h-4 w-4 mr-1" /> Back
        </Button>
        <h1 className="text-2xl font-bold text-foreground">
          {isEditing ? "Edit Course" : "Add Course"}
        </h1>
      </div>

      {/* The container is intentionally a <div>, not a <form>, so nothing in
          the stack (Inertia, browser, etc.) can hijack form submission and
          PUT to the current page URL. Save runs via the button's onClick. */}
      <div className="space-y-8 max-w-6xl">
        {form.videotile_course_id && (
          <div className="bg-primary/5 border border-primary/30 rounded-xl p-4 flex items-center justify-between gap-3">
            <div className="text-sm">
              <span className="font-semibold text-foreground">VideoTile course #{form.videotile_course_id}.</span>{" "}
              <span className="text-muted-foreground">
                Content is hosted on VideoTile; delegates launch into the LMS for delivery.
                Local title, description, and price are authoritative.
              </span>
            </div>
            <Button type="button" variant="outline" size="sm" onClick={refreshFromVideoTile}>
              Refresh from VideoTile
            </Button>
          </div>
        )}

        {/* Section 01: Basic Information */}
        <div className="bg-card border border-border rounded-xl p-6">
          <SectionHeader number={1} title="Basic Information" />

          <div className="grid grid-cols-3 gap-4 mb-4">
            <div className="space-y-1">
              <Label className="font-semibold">Course Title</Label>
              <Input
                value={form.title}
                onChange={(e) => {
                  const title = e.target.value;
                  setForm((f) => ({ ...f, title, slug: isEditing ? f.slug : generateSlug(title) }));
                }}
                required
              />
            </div>
            <div className="space-y-1">
              <Label className="font-semibold">Slug (URL)</Label>
              <Input value={form.slug} onChange={(e) => setForm((f) => ({ ...f, slug: e.target.value }))} required />
              <p className="text-xs text-muted-foreground">Leave empty to auto-generate from title</p>
            </div>
            <div className="space-y-1">
              <Label className="font-semibold">Status</Label>
              <Select value={form.is_active ? "published" : "draft"} onValueChange={(v) => setForm((f) => ({ ...f, is_active: v === "published" }))}>
                <SelectTrigger><SelectValue /></SelectTrigger>
                <SelectContent>
                  <SelectItem value="published">Published</SelectItem>
                  <SelectItem value="draft">Draft</SelectItem>
                </SelectContent>
              </Select>
            </div>
          </div>

          <div className="grid grid-cols-3 gap-4 mb-4">
            <div className="space-y-1">
              <Label className="font-semibold">Main Category</Label>
              <Select
                value={form.category}
                onValueChange={(v) => {
                  const opt = mainCategories.find((o) => o.name === v);
                  setForm((f) => ({ ...f, category: v, category_href: opt?.href || "/courses" }));
                }}
              >
                <SelectTrigger><SelectValue /></SelectTrigger>
                <SelectContent>
                  {mainCategories.map((o) => (
                    <SelectItem key={o.id} value={o.name}>{o.name}</SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            <div className="space-y-1">
              <Label className="font-semibold">Sub Category</Label>
              <Select value={form.sub_category || "none"} onValueChange={(v) => setForm((f) => ({ ...f, sub_category: v === "none" ? "" : v }))}>
                <SelectTrigger><SelectValue placeholder="Select..." /></SelectTrigger>
                <SelectContent>
                  <SelectItem value="none">None</SelectItem>
                  {subCategories.map((o) => (
                    <SelectItem key={o.id} value={o.name}>{o.name}</SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            <div className="space-y-1">
              <Label className="font-semibold">Course Capacity</Label>
              <Input
                type="number"
                value={form.capacity ?? ""}
                onChange={(e) => setForm((f) => ({ ...f, capacity: e.target.value ? parseInt(e.target.value) : null }))}
                placeholder="Leave blank for unlimited"
              />
              <p className="text-xs text-muted-foreground">Leave blank for unlimited</p>
            </div>
          </div>

          <div className="grid grid-cols-2 gap-4">
            <div className="space-y-1">
              <Label className="font-semibold">Course Duration (In days)</Label>
              <Input type="number" value={form.days} onChange={(e) => setForm((f) => ({ ...f, days: parseInt(e.target.value) || 1 }))} />
            </div>
            <div className="space-y-1">
              <Label className="font-semibold text-muted-foreground">Trainers</Label>
              {id ? (
                <div>
                  <TrainerAssignmentsDialog courseId={id} courseTitle={course?.title} />
                </div>
              ) : (
                <p className="text-sm text-muted-foreground">Save the course first to manage trainer ↔ venue assignments.</p>
              )}
            </div>
          </div>
        </div>

        {/* Section 02: Pricing & Details */}
        <div className="bg-card border border-border rounded-xl p-6">
          <SectionHeader number={2} title="Pricing & Details" />

          <div className="grid grid-cols-3 gap-4 mb-4">
            <div className="space-y-1">
              <Label className="font-semibold">Price (£) (Excl. VAT)</Label>
              <PriceInput
                cents={form.price_cents}
                onCentsChange={(cents) => setForm((f) => ({ ...f, price_cents: cents }))}
              />
            </div>
            <div className="space-y-1">
              <Label className="font-semibold">Original Price (£) (Excl. VAT)</Label>
              <PriceInput
                cents={form.original_price_cents}
                onCentsChange={(cents) => setForm((f) => ({ ...f, original_price_cents: cents }))}
                placeholder="0.00"
              />
              <p className="text-xs text-muted-foreground">For showing discounts</p>
            </div>
            <div className="space-y-1">
              <Label className="font-semibold">Level</Label>
              <Select value={form.level} onValueChange={(v) => setForm((f) => ({ ...f, level: v }))}>
                <SelectTrigger><SelectValue /></SelectTrigger>
                <SelectContent>
                  {levelOptions.map((o) => (
                    <SelectItem key={o} value={o}>{o}</SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
          </div>

          <div className="grid grid-cols-3 gap-4 mb-4">
            <div className="space-y-1">
              <Label className="font-semibold">Language</Label>
              <Input value={form.language} onChange={(e) => setForm((f) => ({ ...f, language: e.target.value }))} />
            </div>
            <div className="space-y-1">
              <Label className="font-semibold">Featured Course</Label>
              <Select value={form.is_featured ? "yes" : "no"} onValueChange={(v) => setForm((f) => ({ ...f, is_featured: v === "yes" }))}>
                <SelectTrigger><SelectValue /></SelectTrigger>
                <SelectContent>
                  <SelectItem value="no">No</SelectItem>
                  <SelectItem value="yes">Yes</SelectItem>
                </SelectContent>
              </Select>
            </div>
            <div className="space-y-1">
              <Label className="font-semibold">Certificate</Label>
              <Select value={form.has_certificate ? "yes" : "no"} onValueChange={(v) => setForm((f) => ({ ...f, has_certificate: v === "yes" }))}>
                <SelectTrigger><SelectValue /></SelectTrigger>
                <SelectContent>
                  <SelectItem value="no">No</SelectItem>
                  <SelectItem value="yes">Yes</SelectItem>
                </SelectContent>
              </Select>
            </div>
          </div>

          <div className="space-y-2 mb-4">
            <Label className="font-semibold">Thumbnail Image</Label>
            <ThumbnailUploader
              value={form.image_url}
              onChange={(v) => setForm((f) => ({ ...f, image_url: v }))}
            />
            <p className="text-xs text-muted-foreground">Upload an image (PNG/JPG/WebP, up to 10MB) or paste a URL.</p>
          </div>

          <div className="space-y-1">
            <Label className="font-semibold">Short Description</Label>
            <Textarea
              value={form.description}
              onChange={(e) => setForm((f) => ({ ...f, description: e.target.value }))}
              rows={4}
            />
          </div>
        </div>

        {/* Section 03: Course Content */}
        <div className="bg-card border border-border rounded-xl p-6">
          <SectionHeader number={3} title="Course Content" />

          <div className="space-y-1 mb-6">
            <Label className="font-semibold">Course Description</Label>
            <RichTextEditor
              value={form.who_attends}
              onChange={(value) => setForm((f) => ({ ...f, who_attends: value }))}
              rows={8}
              placeholder="Full course description including Who Attends, Course Content, Certification details..."
            />
          </div>

          <div className="space-y-1 mb-6">
            <Label className="font-semibold">Certification</Label>
            <Textarea
              value={form.certification}
              onChange={(e) => setForm((f) => ({ ...f, certification: e.target.value }))}
              rows={3}
            />
          </div>

          <DynamicListField
            label="Modules"
            items={moduleItems}
            onChange={setModuleItems}
            placeholder="Enter a module"
            addLabel="Add Module"
          />
        </div>

        {/* Section 04: Additional Information */}
        <div className="bg-card border border-border rounded-xl p-6">
          <SectionHeader number={4} title="Additional Information" />

          <div className="space-y-6">
            <DynamicListField
              label="PPE Requirements"
              items={ppeItems}
              onChange={setPpeItems}
              placeholder="Enter a PPE requirement"
              addLabel="Add Requirement"
            />
          </div>
        </div>

        {/* Section 05: Venue & Location */}
        <div className="bg-card border border-border rounded-xl p-6">
          <SectionHeader number={5} title="Venue & Location" />

          <VenueScheduleGrid
            venueIds={venueIds}
            onVenueIdsChange={setVenueIds}
            days={form.days}
            schedules={schedules}
            onScheduleChange={setSchedules}
          />

          <div className="mt-6 space-y-1">
            <Label className="font-semibold">Location Details</Label>
            <RichTextEditor
              value={form.location_details}
              onChange={(value) => setForm((f) => ({ ...f, location_details: value }))}
              rows={6}
              placeholder="Address, parking info, etc."
            />
          </div>
        </div>

        {/* Actions */}
        <div className="flex gap-2 pb-8">
          <Button
            type="button"
            variant="hero"
            disabled={saveMutation.isPending}
            onClick={() => saveMutation.mutate(form)}
          >
            {saveMutation.isPending ? "Saving..." : "Save Course"}
          </Button>
          <Button type="button" variant="outline" onClick={() => router.visit("/admin/courses")}>Cancel</Button>
        </div>
      </div>
    </div>
  );
};

CourseForm.layout = (page: ReactNode) => <AdminLayout>{page}</AdminLayout>;

export default CourseForm;
