import { useCallback, useEffect, useState } from "react";

import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Spinner } from "@/components/ui/spinner";
import { useAuth } from "@/context/AuthContext";
import { useAuthStore } from "@/store/authStore";
import { apiGet, apiPatch, apiPost } from "@/lib/api";
import { formatDateTime, formatMoney } from "@/lib/format";

const MENU_CATS = ["FOOD", "BEVERAGE", "EXTRA"] as const;
const OFFER_KINDS = ["SPA_SESSION", "SPA_PACKAGE", "GYM_PASS"] as const;

const RS_STATUS = [
  "PENDING",
  "PREPARING",
  "OUT_FOR_DELIVERY",
  "DELIVERED",
  "CANCELLED",
] as const;
const LAUNDRY_STATUS = [
  "REQUESTED",
  "PICKED_UP",
  "PROCESSING",
  "DELIVERED",
  "CANCELLED",
] as const;
const SPA_STATUS = ["PENDING", "CONFIRMED", "COMPLETED", "CANCELLED"] as const;

type MenuItem = {
  id: string;
  name: string;
  category: string;
  unitPrice: string;
  isAvailable: boolean;
};

type RsOrder = {
  id: string;
  status: string;
  total: string;
  currency?: string;
  createdAt: string;
  user?: { name: string; email?: string | null };
  booking?: {
    room?: { name: string };
    customer?: { firstName: string; lastName: string };
  };
};

type LaundryRow = {
  id: string;
  status: string;
  createdAt: string;
  user?: { name: string };
  booking?: { room?: { name: string } };
};

type Offering = {
  id: string;
  kind: string;
  name: string;
  price: string;
  isActive: boolean;
};

type SpaBookingRow = {
  id: string;
  status: string;
  total: string;
  createdAt: string;
  user?: { name: string };
  offering?: { name: string };
};

export function GuestServicesPage() {
  const { canManageLoyalty, canEditBookings } = useAuth();
  const canOps = canManageLoyalty && canEditBookings;
  const selectedPropertyId = useAuthStore((s) => s.selectedPropertyId);

  const [menu, setMenu] = useState<MenuItem[]>([]);
  const [rs, setRs] = useState<RsOrder[]>([]);
  const [laundry, setLaundry] = useState<LaundryRow[]>([]);
  const [offerings, setOfferings] = useState<Offering[]>([]);
  const [spaBookings, setSpaBookings] = useState<SpaBookingRow[]>([]);
  const [tab, setTab] = useState("menu");
  const [loading, setLoading] = useState(true);

  const [mOpen, setMOpen] = useState(false);
  const [mName, setMName] = useState("");
  const [mCat, setMCat] = useState<(typeof MENU_CATS)[number]>("FOOD");
  const [mPrice, setMPrice] = useState("0");

  const [oOpen, setOOpen] = useState(false);
  const [oKind, setOKind] = useState<(typeof OFFER_KINDS)[number]>("SPA_SESSION");
  const [oName, setOName] = useState("");
  const [oPrice, setOPrice] = useState("0");

  const loadMenu = useCallback(async () => {
    const r = await apiGet<{ data: MenuItem[] }>("/menu/items");
    setMenu(r.data);
  }, [selectedPropertyId]);

  const loadRs = useCallback(async () => {
    const r = await apiGet<{ data: RsOrder[] }>("/room-service/orders");
    setRs(r.data);
  }, [selectedPropertyId]);

  const loadLaundry = useCallback(async () => {
    const r = await apiGet<{ data: LaundryRow[] }>("/laundry/requests");
    setLaundry(r.data);
  }, [selectedPropertyId]);

  const loadSpa = useCallback(async () => {
    const [o, b] = await Promise.all([
      apiGet<{ data: Offering[] }>("/spa/offerings"),
      apiGet<{ data: SpaBookingRow[] }>("/spa/bookings"),
    ]);
    setOfferings(o.data);
    setSpaBookings(b.data);
  }, [selectedPropertyId]);

  const refresh = useCallback(async () => {
    setLoading(true);
    try {
      await Promise.all([loadMenu(), loadRs(), loadLaundry(), loadSpa()]);
    } finally {
      setLoading(false);
    }
  }, [loadMenu, loadRs, loadLaundry, loadSpa]);

  useEffect(() => {
    void refresh();
  }, [refresh]);

  async function addMenu(e: React.FormEvent) {
    e.preventDefault();
    await apiPost("/menu/items", {
      name: mName,
      category: mCat,
      unitPrice: mPrice,
      isAvailable: true,
    });
    setMOpen(false);
    setMName("");
    setMPrice("0");
    void loadMenu();
  }

  async function addOffering(e: React.FormEvent) {
    e.preventDefault();
    await apiPost("/spa/offerings", {
      kind: oKind,
      name: oName,
      price: oPrice,
    });
    setOOpen(false);
    setOName("");
    setOPrice("0");
    void loadSpa();
  }

  if (loading) {
    return (
      <div className="flex min-h-[320px] items-center justify-center">
        <Spinner size={32} />
      </div>
    );
  }

  return (
    <div className="space-y-6">
      <div className="flex flex-wrap items-center justify-between gap-3">
        <div>
          <h1 className="text-2xl font-bold tracking-tight">Guest services</h1>
        </div>
        <Button variant="outline" size="sm" onClick={() => void refresh()}>
          Refresh
        </Button>
      </div>

      <Tabs value={tab} onValueChange={setTab}>
        <TabsList className="flex flex-wrap h-auto gap-1">
          <TabsTrigger value="menu">Menu</TabsTrigger>
          <TabsTrigger value="rs">Room service</TabsTrigger>
          <TabsTrigger value="laundry">Laundry</TabsTrigger>
          <TabsTrigger value="spa">Spa &amp; gym</TabsTrigger>
        </TabsList>

        <TabsContent value="menu" className="mt-4">
          <Card className="rounded-2xl">
            <CardHeader className="flex flex-row items-center justify-between">
              <CardTitle className="text-base">Menu items</CardTitle>
              {canOps && (
                <Dialog open={mOpen} onOpenChange={setMOpen}>
                  <DialogTrigger asChild>
                    <Button size="sm">Add item</Button>
                  </DialogTrigger>
                  <DialogContent>
                    <DialogHeader>
                      <DialogTitle>New menu item</DialogTitle>
                    </DialogHeader>
                    <form onSubmit={addMenu} className="grid gap-3">
                      <div className="space-y-2">
                        <Label>Name</Label>
                        <Input
                          required
                          value={mName}
                          onChange={(e) => setMName(e.target.value)}
                        />
                      </div>
                      <div className="space-y-2">
                        <Label>Category</Label>
                        <Select
                          value={mCat}
                          onValueChange={(v) => setMCat(v as (typeof MENU_CATS)[number])}
                        >
                          <SelectTrigger>
                            <SelectValue />
                          </SelectTrigger>
                          <SelectContent>
                            {MENU_CATS.map((c) => (
                              <SelectItem key={c} value={c}>
                                {c}
                              </SelectItem>
                            ))}
                          </SelectContent>
                        </Select>
                      </div>
                      <div className="space-y-2">
                        <Label>Unit price (ETB)</Label>
                        <Input
                          required
                          value={mPrice}
                          onChange={(e) => setMPrice(e.target.value)}
                        />
                      </div>
                      <Button type="submit">Save</Button>
                    </form>
                  </DialogContent>
                </Dialog>
              )}
            </CardHeader>
            <CardContent>
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead>Name</TableHead>
                    <TableHead>Category</TableHead>
                    <TableHead>Price</TableHead>
                    <TableHead>Available</TableHead>
                    {canOps && <TableHead />}
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {menu.map((it) => (
                    <TableRow key={it.id}>
                      <TableCell>{it.name}</TableCell>
                      <TableCell className="text-xs">{it.category}</TableCell>
                      <TableCell>{formatMoney(Number(it.unitPrice), "ETB")}</TableCell>
                      <TableCell>{it.isAvailable ? "Yes" : "No"}</TableCell>
                      {canOps && (
                        <TableCell>
                          <Button
                            size="sm"
                            variant="ghost"
                            onClick={() =>
                              void apiPatch(`/menu/items/${it.id}`, {
                                isAvailable: !it.isAvailable,
                              }).then(() => loadMenu())
                            }
                          >
                            Toggle
                          </Button>
                        </TableCell>
                      )}
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </CardContent>
          </Card>
        </TabsContent>

        <TabsContent value="rs" className="mt-4">
          <Card className="rounded-2xl">
            <CardHeader>
              <CardTitle className="text-base">Room service orders</CardTitle>
            </CardHeader>
            <CardContent>
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead>Guest</TableHead>
                    <TableHead>Room</TableHead>
                    <TableHead>Status</TableHead>
                    <TableHead>Total</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {rs.map((o) => (
                    <TableRow key={o.id}>
                      <TableCell className="text-sm">
                        {o.user?.name ?? "—"}
                        <div className="text-xs text-muted-foreground">
                          {formatDateTime(o.createdAt)}
                        </div>
                      </TableCell>
                      <TableCell className="text-xs">
                        {o.booking?.room?.name ?? "—"}
                      </TableCell>
                      <TableCell>
                        {canOps ? (
                          <Select
                            value={o.status}
                            onValueChange={(v) =>
                              void apiPatch(`/room-service/orders/${o.id}`, {
                                status: v,
                              }).then(() => loadRs())
                            }
                          >
                            <SelectTrigger className="h-8 w-[160px]">
                              <SelectValue />
                            </SelectTrigger>
                            <SelectContent>
                              {RS_STATUS.map((s) => (
                                <SelectItem key={s} value={s}>
                                  {s}
                                </SelectItem>
                              ))}
                            </SelectContent>
                          </Select>
                        ) : (
                          <span className="text-xs">{o.status}</span>
                        )}
                      </TableCell>
                      <TableCell>
                        {formatMoney(Number(o.total), o.currency ?? "ETB")}
                      </TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </CardContent>
          </Card>
        </TabsContent>

        <TabsContent value="laundry" className="mt-4">
          <Card className="rounded-2xl">
            <CardHeader>
              <CardTitle className="text-base">Laundry</CardTitle>
            </CardHeader>
            <CardContent>
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead>Guest</TableHead>
                    <TableHead>Room</TableHead>
                    <TableHead>Status</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {laundry.map((r) => (
                    <TableRow key={r.id}>
                      <TableCell className="text-sm">{r.user?.name ?? "—"}</TableCell>
                      <TableCell className="text-xs">{r.booking?.room?.name ?? "—"}</TableCell>
                      <TableCell>
                        {canOps ? (
                          <Select
                            value={r.status}
                            onValueChange={(v) =>
                              void apiPatch(`/laundry/requests/${r.id}`, {
                                status: v,
                              }).then(() => loadLaundry())
                            }
                          >
                            <SelectTrigger className="h-8 w-[160px]">
                              <SelectValue />
                            </SelectTrigger>
                            <SelectContent>
                              {LAUNDRY_STATUS.map((s) => (
                                <SelectItem key={s} value={s}>
                                  {s}
                                </SelectItem>
                              ))}
                            </SelectContent>
                          </Select>
                        ) : (
                          <span className="text-xs">{r.status}</span>
                        )}
                      </TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </CardContent>
          </Card>
        </TabsContent>

        <TabsContent value="spa" className="mt-4 space-y-4">
          <Card className="rounded-2xl">
            <CardHeader className="flex flex-row items-center justify-between">
              <CardTitle className="text-base">Offerings</CardTitle>
              {canOps && (
                <Dialog open={oOpen} onOpenChange={setOOpen}>
                  <DialogTrigger asChild>
                    <Button size="sm">Add offering</Button>
                  </DialogTrigger>
                  <DialogContent>
                    <DialogHeader>
                      <DialogTitle>New offering</DialogTitle>
                    </DialogHeader>
                    <form onSubmit={addOffering} className="grid gap-3">
                      <div className="space-y-2">
                        <Label>Kind</Label>
                        <Select
                          value={oKind}
                          onValueChange={(v) => setOKind(v as (typeof OFFER_KINDS)[number])}
                        >
                          <SelectTrigger>
                            <SelectValue />
                          </SelectTrigger>
                          <SelectContent>
                            {OFFER_KINDS.map((k) => (
                              <SelectItem key={k} value={k}>
                                {k}
                              </SelectItem>
                            ))}
                          </SelectContent>
                        </Select>
                      </div>
                      <div className="space-y-2">
                        <Label>Name</Label>
                        <Input
                          required
                          value={oName}
                          onChange={(e) => setOName(e.target.value)}
                        />
                      </div>
                      <div className="space-y-2">
                        <Label>Price (ETB)</Label>
                        <Input
                          required
                          value={oPrice}
                          onChange={(e) => setOPrice(e.target.value)}
                        />
                      </div>
                      <Button type="submit">Save</Button>
                    </form>
                  </DialogContent>
                </Dialog>
              )}
            </CardHeader>
            <CardContent>
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead>Name</TableHead>
                    <TableHead>Kind</TableHead>
                    <TableHead>Price</TableHead>
                    <TableHead>Active</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {offerings.map((x) => (
                    <TableRow key={x.id}>
                      <TableCell>{x.name}</TableCell>
                      <TableCell className="text-xs">{x.kind}</TableCell>
                      <TableCell>{formatMoney(Number(x.price), "ETB")}</TableCell>
                      <TableCell>{x.isActive ? "Yes" : "No"}</TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </CardContent>
          </Card>

          <Card className="rounded-2xl">
            <CardHeader>
              <CardTitle className="text-base">Bookings</CardTitle>
            </CardHeader>
            <CardContent>
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead>Guest</TableHead>
                    <TableHead>Offering</TableHead>
                    <TableHead>Status</TableHead>
                    <TableHead>Total</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {spaBookings.map((b) => (
                    <TableRow key={b.id}>
                      <TableCell className="text-sm">{b.user?.name ?? "—"}</TableCell>
                      <TableCell className="text-xs">{b.offering?.name ?? "—"}</TableCell>
                      <TableCell>
                        {canOps ? (
                          <Select
                            value={b.status}
                            onValueChange={(v) =>
                              void apiPatch(`/spa/bookings/${b.id}`, {
                                status: v,
                              }).then(() => loadSpa())
                            }
                          >
                            <SelectTrigger className="h-8 w-[160px]">
                              <SelectValue />
                            </SelectTrigger>
                            <SelectContent>
                              {SPA_STATUS.map((s) => (
                                <SelectItem key={s} value={s}>
                                  {s}
                                </SelectItem>
                              ))}
                            </SelectContent>
                          </Select>
                        ) : (
                          <span className="text-xs">{b.status}</span>
                        )}
                      </TableCell>
                      <TableCell>{formatMoney(Number(b.total), "ETB")}</TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </CardContent>
          </Card>
        </TabsContent>
      </Tabs>
    </div>
  );
}
