import { useEffect, useState } from "react";

import { Badge } from "@/components/ui/badge";
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 { FileUploadField } from "@/components/ui/file-upload-field";
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 { apiGet, apiPatch, apiPost } from "@/lib/api";
import { Spinner } from "@/components/ui/spinner";
import {
  isLikelyApiHotelRoom,
  mapApiRoomToRoom,
} from "@/lib/hotel-adapters";
import { ROOM_CATALOGUE } from "@/lib/constants";
import type { Room } from "@/lib/types";
import { formatMoney } from "@/lib/format";
import { useAuthStore } from "@/store/authStore";

export function RoomsPage() {
  const selectedPropertyId = useAuthStore((s) => s.selectedPropertyId);
  const [rooms, setRooms] = useState<Room[]>([]);
  const [loading, setLoading] = useState(true);
  const [submitting, setSubmitting] = useState(false);
  const [open, setOpen] = useState(false);
  const [editOpen, setEditOpen] = useState(false);
  const [editingRoomId, setEditingRoomId] = useState<string | null>(null);
  const [name, setName] = useState("");
  const [slug, setSlug] = useState(ROOM_CATALOGUE[0].slug);
  const [maxGuests, setMaxGuests] = useState("2");
  const [baseRate, setBaseRate] = useState("120");
  const [imageFiles, setImageFiles] = useState<File[]>([]);

  function load() {
    setLoading(true);
    apiGet<{ data: unknown[] }>("/rooms")
      .then((r) => {
        const mapped = r.data.map((row) =>
          isLikelyApiHotelRoom(row) ? mapApiRoomToRoom(row) : (row as Room)
        );
        setRooms(mapped);
      })
      .finally(() => setLoading(false));
  }

  useEffect(() => {
    load();
  }, [selectedPropertyId]);

  function resetForm() {
    setEditingRoomId(null);
    setName("");
    setSlug(ROOM_CATALOGUE[0].slug);
    setMaxGuests("2");
    setBaseRate("120");
    setImageFiles([]);
  }

  async function addRoom(e: React.FormEvent) {
    e.preventDefault();
    setSubmitting(true);
    try {
      const formData = new FormData();
      formData.append("name", name);
      formData.append("roomType", slug);
      formData.append("maxGuests", maxGuests);
      formData.append("baseRate", baseRate);
      imageFiles.forEach((file) => formData.append("images", file));

      await apiPost<Room>("/rooms", formData);
      setOpen(false);
      resetForm();
      load();
    } finally {
      setSubmitting(false);
    }
  }

  function startEdit(room: Room) {
    setEditingRoomId(room.id);
    setName(room.name);
    setSlug(room.roomTypeSlug);
    setMaxGuests(String(room.maxGuests));
    setBaseRate(String(room.baseRate));
    setImageFiles([]);
    setEditOpen(true);
  }

  async function updateRoom(e: React.FormEvent) {
    e.preventDefault();
    if (!editingRoomId) return;

    setSubmitting(true);
    try {
      const formData = new FormData();
      formData.append("name", name);
      formData.append("roomType", slug);
      formData.append("maxGuests", maxGuests);
      formData.append("baseRate", baseRate);
      imageFiles.forEach((file) => formData.append("images", file));

      await apiPatch<Room>(`/rooms/${editingRoomId}`, formData);
      setEditOpen(false);
      resetForm();
      load();
    } finally {
      setSubmitting(false);
    }
  }

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

  return (
    <div className="space-y-6">
      <div className="flex items-center justify-between">
        <h1 className="text-2xl font-bold">Rooms</h1>
        <div className="flex items-center gap-2">
          <Dialog
            open={open}
            onOpenChange={(next) => {
              setOpen(next);
              if (!next) resetForm();
            }}
          >
            <DialogTrigger asChild>
              <Button>+ Add room</Button>
            </DialogTrigger>
            <DialogContent>
              <DialogHeader>
                <DialogTitle>Add room</DialogTitle>
              </DialogHeader>
              <form onSubmit={addRoom} className="grid gap-3">
                <div className="space-y-2">
                  <Label>Unit name</Label>
                  <Input
                    required
                    placeholder="Room 104"
                    value={name}
                    onChange={(e) => setName(e.target.value)}
                  />
                </div>
                <div className="space-y-2">
                  <Label>Type</Label>
                  <Select value={slug} onValueChange={setSlug}>
                    <SelectTrigger>
                      <SelectValue />
                    </SelectTrigger>
                    <SelectContent>
                      {ROOM_CATALOGUE.map((r) => (
                        <SelectItem key={r.slug} value={r.slug}>
                          {r.name}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
                <div className="grid grid-cols-2 gap-3">
                  <div className="space-y-2">
                    <Label>Max guests</Label>
                    <Input
                      type="number"
                      value={maxGuests}
                      onChange={(e) => setMaxGuests(e.target.value)}
                    />
                  </div>
                  <div className="space-y-2">
                    <Label>Base rate</Label>
                    <Input
                      type="number"
                      value={baseRate}
                      onChange={(e) => setBaseRate(e.target.value)}
                    />
                  </div>
                </div>
                <FileUploadField
                  id="room-images"
                  label="Images"
                  multiple
                  required
                  files={imageFiles}
                  buttonLabel="Upload images"
                  emptyLabel="Select room images"
                  helperText="Add one or more room photos. This is required when creating a room."
                  onChange={(e) => setImageFiles(Array.from(e.target.files ?? []))}
                />
                <Button type="submit" loading={submitting}>
                  Save
                </Button>
              </form>
            </DialogContent>
          </Dialog>

          <Dialog
            open={editOpen}
            onOpenChange={(next) => {
              setEditOpen(next);
              if (!next) resetForm();
            }}
          >
            <DialogContent>
              <DialogHeader>
                <DialogTitle>Edit room</DialogTitle>
              </DialogHeader>
              <form onSubmit={updateRoom} className="grid gap-3">
                <div className="space-y-2">
                  <Label>Unit name</Label>
                  <Input
                    required
                    placeholder="Room 104"
                    value={name}
                    onChange={(e) => setName(e.target.value)}
                  />
                </div>
                <div className="space-y-2">
                  <Label>Type</Label>
                  <Select value={slug} onValueChange={setSlug}>
                    <SelectTrigger>
                      <SelectValue />
                    </SelectTrigger>
                    <SelectContent>
                      {ROOM_CATALOGUE.map((r) => (
                        <SelectItem key={r.slug} value={r.slug}>
                          {r.name}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
                <div className="grid grid-cols-2 gap-3">
                  <div className="space-y-2">
                    <Label>Max guests</Label>
                    <Input
                      type="number"
                      value={maxGuests}
                      onChange={(e) => setMaxGuests(e.target.value)}
                    />
                  </div>
                  <div className="space-y-2">
                    <Label>Base rate</Label>
                    <Input
                      type="number"
                      value={baseRate}
                      onChange={(e) => setBaseRate(e.target.value)}
                    />
                  </div>
                </div>
                <FileUploadField
                  id="room-images-edit"
                  label="Replace images"
                  multiple
                  files={imageFiles}
                  buttonLabel="Choose replacements"
                  emptyLabel="Keep current room images"
                  helperText="Leave this empty to keep the current images, or upload new files to replace them."
                  onChange={(e) => setImageFiles(Array.from(e.target.files ?? []))}
                />
                <Button type="submit" loading={submitting}>
                  Update
                </Button>
              </form>
            </DialogContent>
          </Dialog>
        </div>
      </div>

      <Card className="rounded-2xl">
        <CardHeader>
          <CardTitle className="text-base">List</CardTitle>
        </CardHeader>
        <CardContent className="hidden md:block">
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead>Name</TableHead>
                <TableHead>Type</TableHead>
                <TableHead>Guests</TableHead>
                <TableHead>Rate</TableHead>
                <TableHead>Status</TableHead>
                <TableHead />
              </TableRow>
            </TableHeader>
            <TableBody>
              {rooms.map((r) => (
                <TableRow key={r.id}>
                  <TableCell>
                    {r.imageKeys?.length > 0 ? (
                      <img
                        src={r.imageKeys[0]}
                        alt={r.name}
                        width={48}
                        height={48}
                        className="object-cover rounded"
                      />
                    ) : (
                      <div className="w-12 h-12 flex items-center justify-center text-xs text-gray-400 border rounded">
                        No Image
                      </div>
                    )}
                  </TableCell>
                  <TableCell className="font-medium">{r.name}</TableCell>
                  <TableCell className="text-sm text-muted-foreground">
                    {r.roomTypeSlug}
                  </TableCell>
                  <TableCell>{r.maxGuests}</TableCell>
                  <TableCell>{formatMoney(r.baseRate)}</TableCell>
                  <TableCell>
                    <Badge variant="secondary">{r.status}</Badge>
                  </TableCell>
                  <TableCell className="text-right">
                    <Button size="sm" variant="ghost" onClick={() => startEdit(r)}>
                      Edit
                    </Button>
                  </TableCell>
                </TableRow>
              ))}
            </TableBody>
          </Table>
        </CardContent>
        <CardContent className="space-y-2 md:hidden">
          {rooms.map((r) => (
            <div key={r.id} className="rounded-xl border p-3 text-sm">
              <p className="font-medium">{r.name}</p>
              <p className="text-muted-foreground">
                {r.roomTypeSlug} · {formatMoney(r.baseRate)}
              </p>
              <div className="mt-2 flex items-center justify-between gap-2">
                <Badge>{r.status}</Badge>
                <Button size="sm" variant="ghost" onClick={() => startEdit(r)}>
                  Edit
                </Button>
              </div>
            </div>
          ))}
        </CardContent>
      </Card>
    </div>
  );
}
