"use client";

import React, { useState, useEffect, useCallback } from "react";
import { useRouter } from "next/navigation";
import Link from "next/link";
import { format, parseISO } from "date-fns";
import {
  LogOut,
  ClipboardList,
  Users,
  Settings,
  Plus,
  Pencil,
  Eye,
  AlertTriangle,
  ChevronLeft,
  ChevronRight,
  Calendar,
  UserCheck,
  UserX,
  Check,
} from "lucide-react";

import { Button } from "@/components/ui/button";
import {
  Card,
  CardContent,
  CardHeader,
  CardTitle,
  CardDescription,
} from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Progress } from "@/components/ui/progress";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import {
  Tooltip,
  TooltipContent,
  TooltipProvider,
  TooltipTrigger,
} from "@/components/ui/tooltip";
import { cn } from "@/lib/utils";

import {
  LoadingSpinner,
  StatusBadge,
  MealTypeIcon,
  StatCard,
  EmptyState,
  MealTypeSelector,
} from "@/components/caregiver";
import {
  ORDER_STATUSES,
  getMealTypeLabel,
  type MealType,
  type OrderStatus,
} from "@/lib/constants/meal";
import { useAuth } from "@/hooks/useAuth";

interface MealOrder {
  id: number;
  title: string;
  date: string;
  mealType: MealType;
  status: OrderStatus;
  mealCount: number;
  createdAt: string;
}

interface Resident {
  id: number;
  name: string;
  room: string;
}

interface Meal {
  id: number;
  resident: number | { id: number; name: string };
}

interface OrderStats {
  draft: number;
  submitted: number;
  preparing: number;
  completed: number;
  total: number;
}

interface PaginationInfo {
  totalDocs: number;
  totalPages: number;
  page: number;
  limit: number;
  hasNextPage: boolean;
  hasPrevPage: boolean;
}

const ITEMS_PER_PAGE = 10;

export default function CaregiverDashboardPage() {
  const router = useRouter();
  const {
    user,
    loading: authLoading,
    tenantName,
    logout,
  } = useAuth({ requiredRole: "caregiver" });

  const [orders, setOrders] = useState<MealOrder[]>([]);
  const [residents, setResidents] = useState<Resident[]>([]);
  const [stats, setStats] = useState<OrderStats>({
    draft: 0,
    submitted: 0,
    preparing: 0,
    completed: 0,
    total: 0,
  });
  const [pagination, setPagination] = useState<PaginationInfo>({
    totalDocs: 0,
    totalPages: 1,
    page: 1,
    limit: ITEMS_PER_PAGE,
    hasNextPage: false,
    hasPrevPage: false,
  });
  const [dataLoading, setDataLoading] = useState(true);
  const [ordersLoading, setOrdersLoading] = useState(false);

  const [dateFilter, setDateFilter] = useState("");
  const [statusFilter, setStatusFilter] = useState<string>("all");

  const [coverageDialogOpen, setCoverageDialogOpen] = useState(false);
  const [selectedOrder, setSelectedOrder] = useState<MealOrder | null>(null);
  const [orderMeals, setOrderMeals] = useState<Meal[]>([]);
  const [coverageLoading, setCoverageLoading] = useState(false);

  const [createDialogOpen, setCreateDialogOpen] = useState(false);
  const [newOrderDate, setNewOrderDate] = useState(() =>
    format(new Date(), "yyyy-MM-dd"),
  );
  const [newOrderMealType, setNewOrderMealType] =
    useState<MealType>("breakfast");
  const [creating, setCreating] = useState(false);

  const fetchOrders = useCallback(
    async (page: number = 1) => {
      setOrdersLoading(true);
      try {
        let url = `/api/meal-orders?sort=-date,-createdAt&limit=${ITEMS_PER_PAGE}&page=${page}&depth=0`;
        if (dateFilter) {
          url += `&where[date][equals]=${dateFilter}`;
        }
        if (statusFilter !== "all") {
          url += `&where[status][equals]=${statusFilter}`;
        }

        const res = await fetch(url, { credentials: "include" });
        if (res.ok) {
          const data = await res.json();
          setOrders(data.docs || []);
          setPagination({
            totalDocs: data.totalDocs || 0,
            totalPages: data.totalPages || 1,
            page: data.page || 1,
            limit: data.limit || ITEMS_PER_PAGE,
            hasNextPage: data.hasNextPage || false,
            hasPrevPage: data.hasPrevPage || false,
          });
        } else if (res.status === 401) {
          router.push("/login");
        }
      } catch (err) {
        console.error("Error fetching orders:", err);
      } finally {
        setOrdersLoading(false);
      }
    },
    [router, dateFilter, statusFilter],
  );

  useEffect(() => {
    const fetchInitialData = async () => {
      if (authLoading || !user) return;

      try {
        const residentsRes = await fetch(
          "/api/residents?where[active][equals]=true&limit=500",
          {
            credentials: "include",
          },
        );
        if (residentsRes.ok) {
          const residentsData = await residentsRes.json();
          setResidents(residentsData.docs || []);
        }

        const weekAgo = new Date();
        weekAgo.setDate(weekAgo.getDate() - 7);
        const statsRes = await fetch(
          `/api/meal-orders?where[date][greater_than_equal]=${weekAgo.toISOString().split("T")[0]}&limit=1000&depth=0`,
          { credentials: "include" },
        );
        if (statsRes.ok) {
          const statsData = await statsRes.json();
          const allOrders = statsData.docs || [];
          setStats({
            draft: allOrders.filter((o: MealOrder) => o.status === "draft")
              .length,
            submitted: allOrders.filter(
              (o: MealOrder) => o.status === "submitted",
            ).length,
            preparing: allOrders.filter(
              (o: MealOrder) => o.status === "preparing",
            ).length,
            completed: allOrders.filter(
              (o: MealOrder) => o.status === "completed",
            ).length,
            total: allOrders.length,
          });
        }
      } catch (error) {
        console.error("Error fetching data:", error);
      } finally {
        setDataLoading(false);
      }
    };
    fetchInitialData();
  }, [authLoading, user]);

  useEffect(() => {
    if (!authLoading && user && !dataLoading) {
      fetchOrders(1);
    }
  }, [authLoading, user, dataLoading, fetchOrders]);

  const handleCreateOrder = async () => {
    setCreating(true);
    try {
      const res = await fetch("/api/meal-orders", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          date: newOrderDate,
          mealType: newOrderMealType,
          status: "draft",
        }),
        credentials: "include",
      });

      if (res.ok) {
        const data = await res.json();
        setCreateDialogOpen(false);
        router.push(`/caregiver/orders/${data.doc.id}`);
      }
    } catch (err) {
      console.error("Error creating order:", err);
    } finally {
      setCreating(false);
    }
  };

  const handleViewCoverage = async (order: MealOrder) => {
    setSelectedOrder(order);
    setCoverageDialogOpen(true);
    setCoverageLoading(true);

    try {
      const res = await fetch(
        `/api/meals?where[order][equals]=${order.id}&depth=1&limit=500`,
        {
          credentials: "include",
        },
      );
      if (res.ok) {
        const data = await res.json();
        setOrderMeals(data.docs || []);
      }
    } catch (err) {
      console.error("Error fetching meals:", err);
    } finally {
      setCoverageLoading(false);
    }
  };

  const getCoverageInfo = (order: MealOrder) => {
    const totalResidents = residents.length;
    const coveredCount = order.mealCount;
    const percentage =
      totalResidents > 0
        ? Math.round((coveredCount / totalResidents) * 100)
        : 0;
    return { coveredCount, totalResidents, percentage };
  };

  const getCoverageColor = (percentage: number) => {
    if (percentage === 100) return "bg-green-500";
    if (percentage >= 75) return "bg-blue-500";
    if (percentage >= 50) return "bg-yellow-500";
    return "bg-red-500";
  };

  const formatDate = (dateStr: string) => {
    return format(parseISO(dateStr), "EEE, MMM d");
  };

  if (authLoading || dataLoading) {
    return <LoadingSpinner fullPage />;
  }

  const coveredResidentIds = new Set(
    orderMeals.map((m) =>
      typeof m.resident === "object" ? m.resident.id : m.resident,
    ),
  );
  const coveredResidents = residents.filter((r) =>
    coveredResidentIds.has(r.id),
  );
  const uncoveredResidents = residents.filter(
    (r) => !coveredResidentIds.has(r.id),
  );

  return (
    <div className="min-h-screen bg-muted/50">
      <header className="sticky top-0 z-50 w-full border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
        <div className="container flex h-14 sm:h-16 items-center justify-between gap-2">
          <h1 className="text-lg sm:text-xl font-semibold truncate">{tenantName}</h1>
          <div className="flex items-center gap-2 sm:gap-4">
            <span className="hidden sm:inline text-sm text-muted-foreground">
              {user?.name || user?.email}
            </span>
            <Button variant="outline" size="sm" onClick={logout}>
              <LogOut className="h-4 w-4 sm:mr-2" />
              <span className="hidden sm:inline">Logout</span>
            </Button>
          </div>
        </div>
      </header>

      <main className="container py-4 sm:py-6">
        <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4 mb-6">
          <div>
            <h2 className="text-xl sm:text-2xl font-bold tracking-tight">Dashboard</h2>
            <p className="text-sm sm:text-base text-muted-foreground">
              Manage meal orders for your care home
            </p>
          </div>
          <Button onClick={() => setCreateDialogOpen(true)} className="w-full sm:w-auto">
            <Plus className="mr-2 h-4 w-4" />
            New Meal Order
          </Button>
        </div>

        <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-5 mb-6">
          <StatCard
            title="Total Orders"
            value={stats.total}
            description="Last 7 days"
            icon={ClipboardList}
          />
          {ORDER_STATUSES.map((status) => (
            <StatCard
              key={status.value}
              title={status.label}
              value={stats[status.value as keyof OrderStats]}
              description={status.description}
              dotColor={status.dotColor}
            />
          ))}
        </div>

        <Card className="mb-6">
          <CardHeader>
            <CardTitle>Quick Actions</CardTitle>
          </CardHeader>
          <CardContent>
            <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
              <Link href="/caregiver/orders">
                <Card className="cursor-pointer transition-colors hover:bg-accent">
                  <CardContent className="flex flex-col items-center justify-center p-6">
                    <ClipboardList className="h-8 w-8 mb-2 text-muted-foreground" />
                    <span className="font-medium">All Orders</span>
                  </CardContent>
                </Card>
              </Link>
              <Link href="/caregiver/residents">
                <Card className="cursor-pointer transition-colors hover:bg-accent">
                  <CardContent className="flex flex-col items-center justify-center p-6">
                    <Users className="h-8 w-8 mb-2 text-muted-foreground" />
                    <span className="font-medium">Residents</span>
                  </CardContent>
                </Card>
              </Link>
              <Link href="/admin">
                <Card className="cursor-pointer transition-colors hover:bg-accent">
                  <CardContent className="flex flex-col items-center justify-center p-6">
                    <Settings className="h-8 w-8 mb-2 text-muted-foreground" />
                    <span className="font-medium">Admin Panel</span>
                  </CardContent>
                </Card>
              </Link>
              <Card
                className="cursor-pointer transition-colors hover:bg-accent"
                onClick={() => setCreateDialogOpen(true)}
              >
                <CardContent className="flex flex-col items-center justify-center p-6">
                  <Plus className="h-8 w-8 mb-2 text-primary" />
                  <span className="font-medium">New Order</span>
                </CardContent>
              </Card>
            </div>
          </CardContent>
        </Card>

        <Card>
          <CardHeader>
            <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
              <div>
                <CardTitle>Meal Orders</CardTitle>
                <CardDescription>
                  View and manage all meal orders. Click on coverage to see
                  resident details.
                </CardDescription>
              </div>
              <div className="flex items-center gap-2">
                <Label htmlFor="dateFilter" className="sr-only">
                  Filter by date
                </Label>
                <Input
                  type="date"
                  id="dateFilter"
                  value={dateFilter}
                  onChange={(e) => setDateFilter(e.target.value)}
                  className="w-40"
                  placeholder="Filter by date"
                />
                <Select value={statusFilter} onValueChange={setStatusFilter}>
                  <SelectTrigger className="w-36">
                    <SelectValue placeholder="Status" />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="all">All Statuses</SelectItem>
                    {ORDER_STATUSES.map((status) => (
                      <SelectItem key={status.value} value={status.value}>
                        {status.label}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
                {(dateFilter || statusFilter !== "all") && (
                  <Button
                    variant="ghost"
                    size="sm"
                    onClick={() => {
                      setDateFilter("");
                      setStatusFilter("all");
                    }}
                  >
                    Clear
                  </Button>
                )}
              </div>
            </div>
          </CardHeader>
          <CardContent className="p-0">
            {ordersLoading ? (
              <LoadingSpinner />
            ) : orders.length === 0 ? (
              <EmptyState
                icon={ClipboardList}
                title="No orders found."
                description="Create a new order to get started."
                action={
                  <Button onClick={() => setCreateDialogOpen(true)}>
                    <Plus className="mr-2 h-4 w-4" />
                    Create Order
                  </Button>
                }
              />
            ) : (
              <>
                <Table>
                  <TableHeader>
                    <TableRow>
                      <TableHead>Meal</TableHead>
                      <TableHead>Date</TableHead>
                      <TableHead>Coverage</TableHead>
                      <TableHead>Status</TableHead>
                      <TableHead className="text-right">Actions</TableHead>
                    </TableRow>
                  </TableHeader>
                  <TableBody>
                    {orders.map((order) => {
                      const coverage = getCoverageInfo(order);
                      return (
                        <TableRow key={order.id}>
                          <TableCell>
                            <MealTypeIcon type={order.mealType} showLabel />
                          </TableCell>
                          <TableCell>
                            <div className="flex items-center gap-2">
                              <Calendar className="h-4 w-4 text-muted-foreground" />
                              {formatDate(order.date)}
                            </div>
                          </TableCell>
                          <TableCell>
                            <TooltipProvider>
                              <Tooltip>
                                <TooltipTrigger asChild>
                                  <button
                                    className="w-full max-w-32 cursor-pointer"
                                    onClick={() => handleViewCoverage(order)}
                                  >
                                    <div className="flex items-center gap-2">
                                      <Progress
                                        value={coverage.percentage}
                                        className="h-2 flex-1"
                                      />
                                      <span className="text-xs text-muted-foreground whitespace-nowrap">
                                        {coverage.coveredCount}/
                                        {coverage.totalResidents}
                                      </span>
                                    </div>
                                    {coverage.percentage < 100 && (
                                      <div className="flex items-center gap-1 mt-1">
                                        <AlertTriangle className="h-3 w-3 text-yellow-500" />
                                        <span className="text-xs text-yellow-600">
                                          {coverage.totalResidents -
                                            coverage.coveredCount}{" "}
                                          missing
                                        </span>
                                      </div>
                                    )}
                                  </button>
                                </TooltipTrigger>
                                <TooltipContent>
                                  <p>Click to view coverage details</p>
                                </TooltipContent>
                              </Tooltip>
                            </TooltipProvider>
                          </TableCell>
                          <TableCell>
                            <StatusBadge status={order.status} />
                          </TableCell>
                          <TableCell className="text-right">
                            <Button variant="outline" size="sm" asChild>
                              <Link href={`/caregiver/orders/${order.id}`}>
                                {order.status === "draft" ? (
                                  <>
                                    <Pencil className="mr-1 h-3 w-3" />
                                    Edit
                                  </>
                                ) : (
                                  <>
                                    <Eye className="mr-1 h-3 w-3" />
                                    View
                                  </>
                                )}
                              </Link>
                            </Button>
                          </TableCell>
                        </TableRow>
                      );
                    })}
                  </TableBody>
                </Table>

                {pagination.totalPages > 1 && (
                  <div className="flex items-center justify-between px-4 py-4 border-t">
                    <div className="text-sm text-muted-foreground">
                      Showing {(pagination.page - 1) * pagination.limit + 1} to{" "}
                      {Math.min(
                        pagination.page * pagination.limit,
                        pagination.totalDocs,
                      )}{" "}
                      of {pagination.totalDocs} orders
                    </div>
                    <div className="flex items-center gap-2">
                      <Button
                        variant="outline"
                        size="sm"
                        onClick={() => fetchOrders(pagination.page - 1)}
                        disabled={!pagination.hasPrevPage || ordersLoading}
                      >
                        <ChevronLeft className="h-4 w-4" />
                        Previous
                      </Button>
                      <div className="flex items-center gap-1">
                        {Array.from(
                          { length: Math.min(5, pagination.totalPages) },
                          (_, i) => {
                            let pageNum: number;
                            if (pagination.totalPages <= 5) {
                              pageNum = i + 1;
                            } else if (pagination.page <= 3) {
                              pageNum = i + 1;
                            } else if (
                              pagination.page >=
                              pagination.totalPages - 2
                            ) {
                              pageNum = pagination.totalPages - 4 + i;
                            } else {
                              pageNum = pagination.page - 2 + i;
                            }
                            return (
                              <Button
                                key={pageNum}
                                variant={
                                  pagination.page === pageNum
                                    ? "default"
                                    : "outline"
                                }
                                size="sm"
                                className="w-8 h-8 p-0"
                                onClick={() => fetchOrders(pageNum)}
                                disabled={ordersLoading}
                              >
                                {pageNum}
                              </Button>
                            );
                          },
                        )}
                      </div>
                      <Button
                        variant="outline"
                        size="sm"
                        onClick={() => fetchOrders(pagination.page + 1)}
                        disabled={!pagination.hasNextPage || ordersLoading}
                      >
                        Next
                        <ChevronRight className="h-4 w-4" />
                      </Button>
                    </div>
                  </div>
                )}
              </>
            )}
          </CardContent>
        </Card>
      </main>

      <Dialog open={createDialogOpen} onOpenChange={setCreateDialogOpen}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Create New Meal Order</DialogTitle>
            <DialogDescription>
              Select a date and meal type to create a new order.
            </DialogDescription>
          </DialogHeader>
          <div className="grid gap-4 py-4">
            <div className="space-y-2">
              <Label htmlFor="newOrderDate">Date</Label>
              <Input
                type="date"
                id="newOrderDate"
                value={newOrderDate}
                onChange={(e) => setNewOrderDate(e.target.value)}
              />
            </div>
            <div className="space-y-2">
              <Label>Meal Type</Label>
              <MealTypeSelector
                value={newOrderMealType}
                onChange={setNewOrderMealType}
                variant="button"
              />
            </div>
          </div>
          <DialogFooter>
            <Button
              variant="outline"
              onClick={() => setCreateDialogOpen(false)}
            >
              Cancel
            </Button>
            <Button onClick={handleCreateOrder} disabled={creating}>
              {creating ? (
                <LoadingSpinner size="sm" className="mr-2" />
              ) : (
                <Plus className="mr-2 h-4 w-4" />
              )}
              {creating ? "Creating..." : "Create Order"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <Dialog open={coverageDialogOpen} onOpenChange={setCoverageDialogOpen}>
        <DialogContent className="max-w-2xl max-h-[80vh] overflow-y-auto">
          <DialogHeader>
            <DialogTitle className="flex items-center gap-2">
              <Users className="h-5 w-5" />
              Resident Coverage
            </DialogTitle>
            <DialogDescription>
              {selectedOrder && (
                <>
                  {getMealTypeLabel(selectedOrder.mealType)} -{" "}
                  {formatDate(selectedOrder.date)}
                </>
              )}
            </DialogDescription>
          </DialogHeader>

          {coverageLoading ? (
            <LoadingSpinner />
          ) : (
            <div className="space-y-6">
              <div className="flex items-center gap-4 p-4 bg-muted rounded-lg">
                <div className="flex-1">
                  <div className="flex items-center justify-between mb-2">
                    <span className="text-sm font-medium">
                      Coverage Progress
                    </span>
                    <span className="text-sm text-muted-foreground">
                      {coveredResidents.length}/{residents.length} residents
                    </span>
                  </div>
                  <Progress
                    value={
                      residents.length > 0
                        ? (coveredResidents.length / residents.length) * 100
                        : 0
                    }
                    className="h-3"
                  />
                </div>
                <div
                  className={cn(
                    "flex items-center justify-center w-16 h-16 rounded-full text-white font-bold",
                    getCoverageColor(
                      residents.length > 0
                        ? (coveredResidents.length / residents.length) * 100
                        : 0,
                    ),
                  )}
                >
                  {residents.length > 0
                    ? Math.round(
                        (coveredResidents.length / residents.length) * 100,
                      )
                    : 0}
                  %
                </div>
              </div>

              {uncoveredResidents.length > 0 && (
                <div>
                  <div className="flex items-center gap-2 mb-3">
                    <UserX className="h-4 w-4 text-red-500" />
                    <h4 className="font-medium text-red-700">
                      Missing Meals ({uncoveredResidents.length})
                    </h4>
                  </div>
                  <div className="grid gap-2 sm:grid-cols-2">
                    {uncoveredResidents.map((resident) => (
                      <div
                        key={resident.id}
                        className="flex items-center justify-between p-3 bg-red-50 border border-red-200 rounded-lg"
                      >
                        <div>
                          <div className="font-medium text-red-900">
                            {resident.name}
                          </div>
                          <div className="text-sm text-red-600">
                            Room {resident.room}
                          </div>
                        </div>
                        <AlertTriangle className="h-4 w-4 text-red-500" />
                      </div>
                    ))}
                  </div>
                </div>
              )}

              {coveredResidents.length > 0 && (
                <div>
                  <div className="flex items-center gap-2 mb-3">
                    <UserCheck className="h-4 w-4 text-green-500" />
                    <h4 className="font-medium text-green-700">
                      Covered Residents ({coveredResidents.length})
                    </h4>
                  </div>
                  <div className="grid gap-2 sm:grid-cols-2">
                    {coveredResidents.map((resident) => (
                      <div
                        key={resident.id}
                        className="flex items-center justify-between p-3 bg-green-50 border border-green-200 rounded-lg"
                      >
                        <div>
                          <div className="font-medium text-green-900">
                            {resident.name}
                          </div>
                          <div className="text-sm text-green-600">
                            Room {resident.room}
                          </div>
                        </div>
                        <Check className="h-4 w-4 text-green-500" />
                      </div>
                    ))}
                  </div>
                </div>
              )}
            </div>
          )}

          <DialogFooter>
            {selectedOrder?.status === "draft" && (
              <Button asChild>
                <Link href={`/caregiver/orders/${selectedOrder.id}`}>
                  <Pencil className="mr-2 h-4 w-4" />
                  Edit Order
                </Link>
              </Button>
            )}
            <Button
              variant="outline"
              onClick={() => setCoverageDialogOpen(false)}
            >
              Close
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
