import { useState, ReactNode } from "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 { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import { Badge } from "@/components/ui/badge";
import { toast } from "sonner";
import { Plus, Pencil, Trash2, X, DoorOpen, TreePine } from "lucide-react";
import AdminLayout from "@/layouts/AdminLayout";
import { useAuth } from "@/hooks/useAuth";

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

// ─── Types ────────────────────────────────────────
interface Venue {
  id: string;
  name: string;
  address: string | null;
  city: string | null;
  state: string | null;
  postcode: string | null;
  country: string | null;
  capacity: number | null;
  company_id: string | null;
  status: string;
}

interface SubItem {
  id: string;
  venue_id: string;
  name: string;
  capacity: number | null;
  status: string;
}

const emptyVenueForm = {
  name: "",
  address: "",
  city: "",
  state: "",
  postcode: "",
  country: "GB",
  capacity: "",
  company_id: "",
  status: "active",
};

const emptySubForm = { name: "", capacity: "", status: "active" };

// ─── Component ────────────────────────────────────
const Venues = () => {
  const qc = useQueryClient();
  // Company managers manage only their own venues (backend-enforced); the
  // company is set automatically, so no picker is shown.
  const { hasRole, isSysLevel } = useAuth();
  const isManager = hasRole("company_manager") && !isSysLevel();

  // Venue form
  const [showForm, setShowForm] = useState(false);
  const [editingVenue, setEditingVenue] = useState<Venue | null>(null);
  const [venueForm, setVenueForm] = useState(emptyVenueForm);

  // Sub-item dialogs
  const [roomDialog, setRoomDialog] = useState<string | null>(null);
  const [yardDialog, setYardDialog] = useState<string | null>(null);
  const [subForm, setSubForm] = useState(emptySubForm);
  const [editingSub, setEditingSub] = useState<SubItem | null>(null);

  // ─── Queries ──────────────────────────────────
  const { data: venues, isLoading } = useQuery({
    queryKey: ["venues"],
    queryFn: async () => {
      const res = await fetch("/api/admin/venues");
      if (!res.ok) return [] as Venue[];
      return (await res.json()) as Venue[];
    },
  });

  const { data: companies } = useQuery({
    queryKey: ["training_companies"],
    enabled: !isManager,
    queryFn: async () => {
      const res = await fetch("/api/admin/training-companies?company_type=training_company,hybrid&fields=id,name");
      if (!res.ok) return [];
      return res.json();
    },
  });

  const { data: rooms } = useQuery({
    queryKey: ["venue_rooms"],
    queryFn: async () => {
      const res = await fetch("/api/admin/venue-rooms");
      if (!res.ok) return [] as SubItem[];
      return (await res.json()) as SubItem[];
    },
  });

  const { data: yards } = useQuery({
    queryKey: ["venue_yards"],
    queryFn: async () => {
      const res = await fetch("/api/admin/venue-yards");
      if (!res.ok) return [] as SubItem[];
      return (await res.json()) as SubItem[];
    },
  });

  const getRooms = (venueId: string) => rooms?.filter((r) => r.venue_id === venueId) || [];
  const getYards = (venueId: string) => yards?.filter((y) => y.venue_id === venueId) || [];
  const getCompanyName = (id: string | null) => companies?.find((c: any) => c.id === id)?.name || "—";

  // ─── Venue mutations ──────────────────────────
  const saveVenueMutation = useMutation({
    mutationFn: async (values: typeof venueForm) => {
      const payload = {
        name: values.name,
        address: values.address || null,
        city: values.city || null,
        state: values.state || null,
        postcode: values.postcode || null,
        country: values.country || null,
        capacity: values.capacity ? parseInt(values.capacity) : null,
        company_id: values.company_id || null,
        status: values.status,
      };
      if (editingVenue) {
        const res = await fetch(`/api/admin/venues/${editingVenue.id}`, {
          method: 'PUT',
          headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken() },
          body: JSON.stringify(payload),
        });
        if (!res.ok) throw new Error('Failed to update venue');
      } else {
        const res = await fetch('/api/admin/venues', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken() },
          body: JSON.stringify(payload),
        });
        if (!res.ok) throw new Error('Failed to create venue');
      }
    },
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ["venues"] });
      toast.success(editingVenue ? "Location updated" : "Location added");
      resetVenueForm();
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const deleteVenueMutation = useMutation({
    mutationFn: async (id: string) => {
      const res = await fetch(`/api/admin/venues/${id}`, {
        method: 'DELETE',
        headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken() },
      });
      if (!res.ok) throw new Error('Failed to delete venue');
    },
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ["venues"] });
      toast.success("Location deleted");
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const resetVenueForm = () => {
    setVenueForm(emptyVenueForm);
    setEditingVenue(null);
    setShowForm(false);
  };

  const openEditVenue = (v: Venue) => {
    setEditingVenue(v);
    setVenueForm({
      name: v.name,
      address: v.address || "",
      city: v.city || "",
      state: v.state || "",
      postcode: v.postcode || "",
      country: v.country || "GB",
      capacity: v.capacity?.toString() || "",
      company_id: v.company_id || "",
      status: v.status,
    });
    setShowForm(true);
  };

  // ─── Room / Yard mutations ────────────────────
  const saveSubMutation = (endpoint: "venue-rooms" | "venue-yards", queryKey: string) =>
    useMutation({
      mutationFn: async ({ venueId, values, editId }: { venueId: string; values: typeof subForm; editId?: string }) => {
        const payload = {
          venue_id: venueId,
          name: values.name,
          capacity: values.capacity ? parseInt(values.capacity) : null,
          status: values.status,
        };
        if (editId) {
          const res = await fetch(`/api/admin/${endpoint}/${editId}`, {
            method: 'PUT',
            headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken() },
            body: JSON.stringify(payload),
          });
          if (!res.ok) throw new Error('Failed to update');
        } else {
          const res = await fetch(`/api/admin/${endpoint}`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken() },
            body: JSON.stringify(payload),
          });
          if (!res.ok) throw new Error('Failed to create');
        }
      },
      onSuccess: () => {
        qc.invalidateQueries({ queryKey: [queryKey] });
        toast.success("Saved");
        setSubForm(emptySubForm);
        setEditingSub(null);
      },
      onError: (e: Error) => toast.error(e.message),
    });

  const deleteSubMutation = (endpoint: "venue-rooms" | "venue-yards", queryKey: string) =>
    useMutation({
      mutationFn: async (id: string) => {
        const res = await fetch(`/api/admin/${endpoint}/${id}`, {
          method: 'DELETE',
          headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken() },
        });
        if (!res.ok) throw new Error('Failed to delete');
      },
      onSuccess: () => {
        qc.invalidateQueries({ queryKey: [queryKey] });
        toast.success("Deleted");
      },
      onError: (e: Error) => toast.error(e.message),
    });

  const saveRoomMut = saveSubMutation("venue-rooms", "venue_rooms");
  const deleteRoomMut = deleteSubMutation("venue-rooms", "venue_rooms");
  const saveYardMut = saveSubMutation("venue-yards", "venue_yards");
  const deleteYardMut = deleteSubMutation("venue-yards", "venue_yards");

  const openEditSub = (item: SubItem) => {
    setEditingSub(item);
    setSubForm({ name: item.name, capacity: item.capacity?.toString() || "", status: item.status });
  };

  // ─── Sub-item dialog renderer ─────────────────
  const renderSubDialog = (
    venueId: string | null,
    items: SubItem[],
    label: string,
    isOpen: boolean,
    onClose: () => void,
    saveMut: ReturnType<typeof saveSubMutation>,
    deleteMut: ReturnType<typeof deleteSubMutation>,
  ) => (
    <Dialog open={isOpen} onOpenChange={(o) => { if (!o) { onClose(); setSubForm(emptySubForm); setEditingSub(null); } }}>
      <DialogContent className="max-w-lg max-h-[90vh] flex flex-col p-0 gap-0">
        <DialogHeader className="p-6 pb-4 shrink-0">
          <DialogTitle>{label}s</DialogTitle>
        </DialogHeader>

        {/* Scrolling list — keeps the Add/Edit form below it always visible. */}
        <div className="flex-1 min-h-0 overflow-y-auto px-6">
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead>Name</TableHead>
                <TableHead>Capacity</TableHead>
                <TableHead>Status</TableHead>
                <TableHead className="w-[80px]">Actions</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {items.map((item) => (
                <TableRow key={item.id}>
                  <TableCell>{item.name}</TableCell>
                  <TableCell>{item.capacity || "—"}</TableCell>
                  <TableCell>
                    <Badge variant={item.status === "active" ? "default" : "secondary"} className="capitalize">{item.status}</Badge>
                  </TableCell>
                  <TableCell>
                    <div className="flex gap-1">
                      <Button variant="ghost" size="sm" onClick={() => openEditSub(item)}><Pencil className="h-3 w-3" /></Button>
                      <Button variant="ghost" size="sm" onClick={() => deleteMut.mutate(item.id)}><Trash2 className="h-3 w-3 text-destructive" /></Button>
                    </div>
                  </TableCell>
                </TableRow>
              ))}
              {items.length === 0 && (
                <TableRow><TableCell colSpan={4} className="text-center text-muted-foreground py-4">No {label.toLowerCase()}s yet.</TableCell></TableRow>
              )}
            </TableBody>
          </Table>
        </div>

        <div className="border-t border-border px-6 py-4 shrink-0">
          <p className="text-sm font-medium text-foreground mb-3">{editingSub ? `Edit ${label}` : `Add New ${label}`}</p>
          <div className="space-y-3">
            <div className="space-y-1">
              <Label>Name</Label>
              <Input placeholder={`Enter ${label.toLowerCase()} name`} value={subForm.name} onChange={(e) => setSubForm((f) => ({ ...f, name: e.target.value }))} />
            </div>
            <div className="space-y-1">
              <Label>Capacity</Label>
              <Input type="number" placeholder="Enter capacity" value={subForm.capacity} onChange={(e) => setSubForm((f) => ({ ...f, capacity: e.target.value }))} />
              <p className="text-xs text-muted-foreground">Leave empty for unlimited</p>
            </div>
            <div className="space-y-1">
              <Label>Status</Label>
              <Select value={subForm.status} onValueChange={(v) => setSubForm((f) => ({ ...f, status: v }))}>
                <SelectTrigger><SelectValue /></SelectTrigger>
                <SelectContent>
                  <SelectItem value="active">Active</SelectItem>
                  <SelectItem value="inactive">Inactive</SelectItem>
                </SelectContent>
              </Select>
            </div>
            <div className="flex gap-2 justify-end">
              {editingSub && (
                <Button variant="outline" size="sm" onClick={() => { setEditingSub(null); setSubForm(emptySubForm); }}>Cancel Edit</Button>
              )}
              <Button
                variant="hero"
                size="sm"
                disabled={!subForm.name}
                onClick={() => {
                  if (venueId) saveMut.mutate({ venueId, values: subForm, editId: editingSub?.id });
                }}
              >
                {editingSub ? `Save ${label}` : `Add ${label}`}
              </Button>
            </div>
          </div>
        </div>
      </DialogContent>
    </Dialog>
  );

  return (
    <div>
      <div className="flex items-center justify-between mb-6">
        <h1 className="text-2xl font-bold text-foreground">Locations</h1>
        <Button variant="hero" onClick={() => { setEditingVenue(null); setVenueForm(emptyVenueForm); setShowForm(true); }}>
          <Plus className="mr-2 h-4 w-4" /> Add New Location
        </Button>
      </div>

      {showForm && (
        <Card className="mb-6">
          <CardHeader className="flex flex-row items-center justify-between pb-2">
            <CardTitle>{editingVenue ? "Edit Location" : "Add Location"}</CardTitle>
            <Button variant="ghost" size="sm" onClick={resetVenueForm}><X className="h-4 w-4" /></Button>
          </CardHeader>
          <CardContent>
            <form onSubmit={(e) => { e.preventDefault(); saveVenueMutation.mutate(venueForm); }} className="space-y-4">
              <div className="grid grid-cols-2 gap-4">
                <div className="space-y-2">
                  <Label>Name</Label>
                  <Input value={venueForm.name} onChange={(e) => setVenueForm((f) => ({ ...f, name: e.target.value }))} required />
                </div>
                <div className="space-y-2">
                  <Label>Capacity</Label>
                  <Input type="number" placeholder="Leave empty for unlimited" value={venueForm.capacity} onChange={(e) => setVenueForm((f) => ({ ...f, capacity: e.target.value }))} />
                </div>
              </div>
              <div className="space-y-2">
                <Label>Address</Label>
                <Textarea value={venueForm.address} onChange={(e) => setVenueForm((f) => ({ ...f, address: e.target.value }))} rows={2} />
              </div>
              <div className="grid grid-cols-3 gap-4">
                <div className="space-y-2">
                  <Label>City</Label>
                  <Input value={venueForm.city} onChange={(e) => setVenueForm((f) => ({ ...f, city: e.target.value }))} />
                </div>
                <div className="space-y-2">
                  <Label>State</Label>
                  <Input placeholder="Enter state" value={venueForm.state} onChange={(e) => setVenueForm((f) => ({ ...f, state: e.target.value }))} />
                </div>
                <div className="space-y-2">
                  <Label>Postcode/ZIP</Label>
                  <Input value={venueForm.postcode} onChange={(e) => setVenueForm((f) => ({ ...f, postcode: e.target.value }))} />
                </div>
              </div>
              <div className="grid grid-cols-3 gap-4">
                <div className="space-y-2">
                  <Label>Country</Label>
                  <Input value={venueForm.country} onChange={(e) => setVenueForm((f) => ({ ...f, country: e.target.value }))} />
                </div>
                {!isManager && (
                  <div className="space-y-2">
                    <Label>Company</Label>
                    <Select value={venueForm.company_id} onValueChange={(v) => setVenueForm((f) => ({ ...f, company_id: v }))}>
                      <SelectTrigger><SelectValue placeholder="Select company" /></SelectTrigger>
                      <SelectContent>
                        {companies?.map((c: any) => (
                          <SelectItem key={c.id} value={c.id}>{c.name}</SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  </div>
                )}
                <div className="space-y-2">
                  <Label>Status</Label>
                  <Select value={venueForm.status} onValueChange={(v) => setVenueForm((f) => ({ ...f, status: v }))}>
                    <SelectTrigger><SelectValue /></SelectTrigger>
                    <SelectContent>
                      <SelectItem value="active">Active</SelectItem>
                      <SelectItem value="inactive">Inactive</SelectItem>
                    </SelectContent>
                  </Select>
                </div>
              </div>
              <div className="flex gap-2">
                <Button type="submit" variant="hero" disabled={saveVenueMutation.isPending}>
                  {saveVenueMutation.isPending ? "Saving..." : "Save Location"}
                </Button>
                <Button type="button" variant="outline" onClick={resetVenueForm}>Cancel</Button>
              </div>
            </form>
          </CardContent>
        </Card>
      )}

      {isLoading ? (
        <p className="text-muted-foreground">Loading locations...</p>
      ) : (
        <div className="bg-card border border-border rounded-xl overflow-hidden">
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead>Name</TableHead>
                <TableHead>Location</TableHead>
                <TableHead>Capacity</TableHead>
                <TableHead>Rooms</TableHead>
                <TableHead>Yards</TableHead>
                <TableHead>Company</TableHead>
                <TableHead>Status</TableHead>
                <TableHead className="w-[200px]">Actions</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {venues?.map((v) => (
                <TableRow key={v.id}>
                  <TableCell className="font-medium">{v.name}</TableCell>
                  <TableCell>{[v.city, v.country].filter(Boolean).join(", ") || "—"}</TableCell>
                  <TableCell>{v.capacity || "—"}</TableCell>
                  <TableCell>
                    <Button variant="outline" size="sm" onClick={() => setRoomDialog(v.id)}>
                      <span className="bg-primary text-primary-foreground rounded-full w-5 h-5 text-xs flex items-center justify-center mr-1.5">{getRooms(v.id).length}</span>
                      View
                    </Button>
                  </TableCell>
                  <TableCell>
                    <Button variant="outline" size="sm" onClick={() => setYardDialog(v.id)}>
                      <span className="bg-primary text-primary-foreground rounded-full w-5 h-5 text-xs flex items-center justify-center mr-1.5">{getYards(v.id).length}</span>
                      View
                    </Button>
                  </TableCell>
                  <TableCell>{getCompanyName(v.company_id)}</TableCell>
                  <TableCell>
                    <Badge variant={v.status === "active" ? "default" : "secondary"} className="capitalize">{v.status}</Badge>
                  </TableCell>
                  <TableCell>
                    <div className="flex gap-1">
                      <Button variant="ghost" size="sm" onClick={() => openEditVenue(v)}><Pencil className="h-3 w-3" /></Button>
                      <Button variant="outline" size="sm" onClick={() => { setSubForm(emptySubForm); setEditingSub(null); setRoomDialog(v.id); }}>
                        <DoorOpen className="h-3 w-3 mr-1" /> + Room
                      </Button>
                      <Button variant="outline" size="sm" onClick={() => { setSubForm(emptySubForm); setEditingSub(null); setYardDialog(v.id); }}>
                        <TreePine className="h-3 w-3 mr-1" /> + Yard
                      </Button>
                      <Button variant="ghost" size="sm" onClick={() => deleteVenueMutation.mutate(v.id)}>
                        <Trash2 className="h-3 w-3 text-destructive" />
                      </Button>
                    </div>
                  </TableCell>
                </TableRow>
              ))}
              {venues?.length === 0 && (
                <TableRow>
                  <TableCell colSpan={8} className="text-center text-muted-foreground py-8">No venues yet. Add one to get started.</TableCell>
                </TableRow>
              )}
            </TableBody>
          </Table>
        </div>
      )}

      {/* Rooms dialog */}
      {renderSubDialog(roomDialog, roomDialog ? getRooms(roomDialog) : [], "Room", !!roomDialog, () => setRoomDialog(null), saveRoomMut, deleteRoomMut)}

      {/* Yards dialog */}
      {renderSubDialog(yardDialog, yardDialog ? getYards(yardDialog) : [], "Yard", !!yardDialog, () => setYardDialog(null), saveYardMut, deleteYardMut)}
    </div>
  );
};

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

export default Venues;
