import { useState, ReactNode } from "react";
import { Head } from '@inertiajs/react';
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import AdminLayout from '@/layouts/AdminLayout';
import { useAuth } from "@/hooks/useAuth";
import { format } from "date-fns";
import { Plus, Trash2, AlertTriangle } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Badge } from "@/components/ui/badge";
import { Calendar } from "@/components/ui/calendar";
import {
  Select, SelectContent, SelectItem, SelectTrigger, SelectValue,
} from "@/components/ui/select";
import {
  Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter,
} from "@/components/ui/dialog";
import {
  Table, TableBody, TableCell, TableHead, TableHeader, TableRow,
} from "@/components/ui/table";
import { toast } from "sonner";

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

interface Block {
  id: string;
  venue_id: string;
  resource_type: string;
  resource_id: string;
  blocked_date: string;
  reason: string | null;
  created_at: string;
}

interface Venue { id: string; name: string; }
interface SubItem { id: string; venue_id: string; name: string; }

const LocationOverrides = () => {
  const { isSysLevel } = useAuth();
  const queryClient = useQueryClient();
  const [showAdd, setShowAdd] = useState(false);
  const [selectedVenue, setSelectedVenue] = useState<string>("");
  const [selectedResourceType, setSelectedResourceType] = useState<"room" | "yard">("room");
  const [selectedResource, setSelectedResource] = useState<string>("");
  const [selectedDates, setSelectedDates] = useState<Date[]>([]);
  const [reason, setReason] = useState("");
  const [filterVenue, setFilterVenue] = useState<string>("all");

  const { data: venues } = useQuery({
    queryKey: ["venues-list"],
    queryFn: async () => {
      const res = await fetch('/api/admin/venues?status=active');
      if (!res.ok) return [] as Venue[];
      return res.json() as Promise<Venue[]>;
    },
  });

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

  const { data: blocks, isLoading } = useQuery({
    queryKey: ["location-resource-blocks"],
    queryFn: async () => {
      const res = await fetch('/api/admin/location-resource-blocks');
      if (!res.ok) return [] as Block[];
      return res.json() as Promise<Block[]>;
    },
  });

  const addBlocksMut = useMutation({
    mutationFn: async () => {
      const rows = selectedDates.map((d) => ({
        venue_id: selectedVenue,
        resource_type: selectedResourceType,
        resource_id: selectedResource,
        blocked_date: format(d, "yyyy-MM-dd"),
        reason: reason || null,
      }));
      const res = await fetch('/api/admin/location-resource-blocks', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken() },
        body: JSON.stringify({ rows }),
      });
      if (!res.ok) {
        const err = await res.json().catch(() => ({ message: 'Failed' }));
        throw new Error(err.message || 'Failed to save blocks');
      }
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["location-resource-blocks"] });
      toast.success(`${selectedDates.length} date(s) blocked`);
      resetForm();
    },
    onError: (e: any) => toast.error(e.message),
  });

  const deleteBlockMut = useMutation({
    mutationFn: async (id: string) => {
      const res = await fetch(`/api/admin/location-resource-blocks/${id}`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken() },
        body: JSON.stringify({ _method: 'DELETE' }),
      });
      if (!res.ok) throw new Error('Failed to remove block');
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["location-resource-blocks"] });
      toast.success("Block removed");
    },
    onError: (e: any) => toast.error(e.message),
  });

  const resetForm = () => {
    setShowAdd(false);
    setSelectedVenue("");
    setSelectedResourceType("room");
    setSelectedResource("");
    setSelectedDates([]);
    setReason("");
  };

  const availableResources = selectedResourceType === "room"
    ? (rooms || []).filter((r) => r.venue_id === selectedVenue)
    : (yards || []).filter((y) => y.venue_id === selectedVenue);

  const getResourceName = (type: string, resourceId: string) => {
    const list = type === "room" ? rooms : yards;
    return list?.find((r) => r.id === resourceId)?.name || "Unknown";
  };

  const getVenueName = (venueId: string) => venues?.find((v) => v.id === venueId)?.name || "Unknown";

  const filteredBlocks = filterVenue === "all"
    ? blocks
    : blocks?.filter((b) => b.venue_id === filterVenue);

  const upcomingBlocks = filteredBlocks?.filter((b) => b.blocked_date >= format(new Date(), "yyyy-MM-dd"));

  if (!isSysLevel()) {
    return (
      <>
        <Head title="Location Overrides" />
        <div className="p-6 text-center text-muted-foreground">Access restricted to system administrators.</div>
      </>
    );
  }

  return (
    <>
      <Head title="Location Overrides" />
      <div className="space-y-6">
        <div className="flex items-center justify-between">
          <div>
            <h1 className="text-2xl font-bold text-foreground flex items-center gap-2">
              <AlertTriangle className="h-6 w-6 text-orange-500" />
              Location Overrides
            </h1>
            <p className="text-sm text-muted-foreground mt-1">
              Block rooms or yards from being scheduled on specific dates
            </p>
          </div>
          <Button onClick={() => setShowAdd(true)} className="gap-2">
            <Plus className="h-4 w-4" /> Add Override
          </Button>
        </div>

        {/* Filter */}
        <div className="flex items-center gap-3">
          <Label className="text-sm">Filter by Location:</Label>
          <Select value={filterVenue} onValueChange={setFilterVenue}>
            <SelectTrigger className="w-[220px]">
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="all">All Locations</SelectItem>
              {venues?.map((v) => (
                <SelectItem key={v.id} value={v.id}>{v.name}</SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>

        {/* Blocks table */}
        <div className="rounded-lg border border-border bg-card">
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead>Location</TableHead>
                <TableHead>Type</TableHead>
                <TableHead>Resource</TableHead>
                <TableHead>Blocked Date</TableHead>
                <TableHead>Reason</TableHead>
                <TableHead className="w-[60px]" />
              </TableRow>
            </TableHeader>
            <TableBody>
              {isLoading ? (
                <TableRow><TableCell colSpan={6} className="text-center py-8 text-muted-foreground">Loading...</TableCell></TableRow>
              ) : !upcomingBlocks?.length ? (
                <TableRow><TableCell colSpan={6} className="text-center py-8 text-muted-foreground">No upcoming overrides</TableCell></TableRow>
              ) : (
                upcomingBlocks.map((b) => (
                  <TableRow key={b.id}>
                    <TableCell className="font-medium">{getVenueName(b.venue_id)}</TableCell>
                    <TableCell>
                      <Badge variant="outline" className="capitalize">{b.resource_type}</Badge>
                    </TableCell>
                    <TableCell>{getResourceName(b.resource_type, b.resource_id)}</TableCell>
                    <TableCell>{format(new Date(b.blocked_date + "T00:00:00"), "EEE dd MMM yyyy")}</TableCell>
                    <TableCell className="text-muted-foreground">{b.reason || "—"}</TableCell>
                    <TableCell>
                      <Button variant="ghost" size="icon" className="h-7 w-7 text-destructive" onClick={() => deleteBlockMut.mutate(b.id)}>
                        <Trash2 className="h-3.5 w-3.5" />
                      </Button>
                    </TableCell>
                  </TableRow>
                ))
              )}
            </TableBody>
          </Table>
        </div>

        {/* Add dialog */}
        <Dialog open={showAdd} onOpenChange={(o) => { if (!o) resetForm(); }}>
          <DialogContent className="sm:max-w-lg">
            <DialogHeader>
              <DialogTitle>Block Resource Dates</DialogTitle>
            </DialogHeader>
            <div className="space-y-4">
              <div className="grid grid-cols-2 gap-3">
                <div>
                  <Label>Location</Label>
                  <Select value={selectedVenue} onValueChange={(v) => { setSelectedVenue(v); setSelectedResource(""); }}>
                    <SelectTrigger><SelectValue placeholder="Select location" /></SelectTrigger>
                    <SelectContent>
                      {venues?.map((v) => (
                        <SelectItem key={v.id} value={v.id}>{v.name}</SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
                <div>
                  <Label>Resource Type</Label>
                  <Select value={selectedResourceType} onValueChange={(v) => { setSelectedResourceType(v as "room" | "yard"); setSelectedResource(""); }}>
                    <SelectTrigger><SelectValue /></SelectTrigger>
                    <SelectContent>
                      <SelectItem value="room">Room</SelectItem>
                      <SelectItem value="yard">Yard</SelectItem>
                    </SelectContent>
                  </Select>
                </div>
              </div>

              {selectedVenue && (
                <div>
                  <Label>Resource</Label>
                  <Select value={selectedResource} onValueChange={setSelectedResource}>
                    <SelectTrigger><SelectValue placeholder="Select resource" /></SelectTrigger>
                    <SelectContent>
                      {availableResources.map((r) => (
                        <SelectItem key={r.id} value={r.id}>{r.name}</SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
              )}

              {selectedResource && (
                <div>
                  <Label>Select Dates (click to toggle)</Label>
                  <div className="border rounded-md p-2 flex justify-center">
                    <Calendar
                      mode="multiple"
                      selected={selectedDates}
                      onSelect={(dates) => setSelectedDates(dates || [])}
                      disabled={(date) => date < new Date(new Date().setHours(0, 0, 0, 0))}
                      className="pointer-events-auto"
                    />
                  </div>
                  {selectedDates.length > 0 && (
                    <p className="text-xs text-muted-foreground mt-1">{selectedDates.length} date(s) selected</p>
                  )}
                </div>
              )}

              <div>
                <Label>Reason</Label>
                <Input placeholder="e.g. Internal training, Maintenance" value={reason} onChange={(e) => setReason(e.target.value)} />
              </div>
            </div>
            <DialogFooter>
              <Button variant="outline" onClick={resetForm}>Cancel</Button>
              <Button
                disabled={!selectedVenue || !selectedResource || selectedDates.length === 0 || addBlocksMut.isPending}
                onClick={() => addBlocksMut.mutate()}
              >
                {addBlocksMut.isPending ? "Saving..." : `Block ${selectedDates.length} Date(s)`}
              </Button>
            </DialogFooter>
          </DialogContent>
        </Dialog>
      </div>
    </>
  );
};

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

export default LocationOverrides;
