"use client";

import { useState } from "react";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { useLocale, useTranslations } from "next-intl";
import { Link } from "@/i18n/routing";
import { Trash2 } from "lucide-react";
import { apiDelete, apiGet, apiPatch, apiPost } from "@/lib/api/client";
import { ConfirmDialog } from "@/components/ui/confirm-dialog";
import { notify } from "@/lib/notify";
import { useApiError } from "@/lib/use-api-error";
import { useAuthStore } from "@/lib/stores/auth.store";
import { formatNumber } from "@/lib/format";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { JalaliDateField, formatIsoDateJalali } from "@/components/ui/jalali-date-field";
import { LabeledField } from "@/components/ui/labeled-field";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { cn } from "@/lib/utils";
import type { Table } from "@/lib/api/types";
import { Can } from "@/components/auth/can";

type ReservationStatus =
  | "Pending"
  | "Confirmed"
  | "Cancelled"
  | "Seated"
  | "Completed";

interface Reservation {
  id: string;
  tableId?: string;
  tableNumber?: string;
  guestName: string;
  guestPhone: string;
  date: string;
  time: string;
  partySize: number;
  status: ReservationStatus;
  notes?: string;
}

const statusStyle: Record<ReservationStatus, string> = {
  Pending: "bg-amber-50 text-[#BA7517] border-amber-200",
  Confirmed: "bg-[#E1F5EE] text-[#0F6E56] border-[#0F6E56]/30",
  Seated: "bg-blue-50 text-blue-800 border-blue-200",
  Completed: "bg-muted text-muted-foreground border-border",
  Cancelled: "bg-red-50 text-[#A32D2D] border-red-200",
};

export function ReservationsScreen() {
  const t = useTranslations("reservations");
  const tCommon = useTranslations("common");
  const locale = useLocale();
  const apiError = useApiError();
  const cafeId = useAuthStore((s) => s.user?.cafeId);
  const queryClient = useQueryClient();
  const [deleteTarget, setDeleteTarget] = useState<Reservation | null>(null);

  const [guestName, setGuestName] = useState("");
  const [guestPhone, setGuestPhone] = useState("09121234567");
  const [date, setDate] = useState(() => new Date().toISOString().slice(0, 10));
  const [time, setTime] = useState("19:00");
  const [partySize, setPartySize] = useState("2");
  const [tableId, setTableId] = useState("");
  const [notes, setNotes] = useState("");

  const { data: list = [], isLoading } = useQuery({
    queryKey: ["reservations", cafeId],
    queryFn: () => apiGet<Reservation[]>(`/api/cafes/${cafeId}/reservations`),
    enabled: !!cafeId,
  });

  const { data: tables = [] } = useQuery({
    queryKey: ["tables", cafeId],
    queryFn: () => apiGet<Table[]>(`/api/cafes/${cafeId}/tables`),
    enabled: !!cafeId,
  });

  const createReservation = useMutation({
    mutationFn: () =>
      apiPost<Reservation>(`/api/cafes/${cafeId}/reservations`, {
        guestName: guestName.trim(),
        guestPhone: guestPhone.trim(),
        date,
        time: time.length === 5 ? `${time}:00` : time,
        partySize: Number(partySize),
        tableId: tableId || null,
        notes: notes.trim() || null,
      }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["reservations", cafeId] });
      setGuestName("");
      setNotes("");
    },
  });

  const updateStatus = useMutation({
    mutationFn: ({ id, status }: { id: string; status: ReservationStatus }) =>
      apiPatch(`/api/cafes/${cafeId}/reservations/${id}/status`, { status }),
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ["reservations", cafeId] }),
  });

  const deleteReservation = useMutation({
    mutationFn: (id: string) => apiDelete(`/api/cafes/${cafeId}/reservations/${id}`),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["reservations", cafeId] });
      setDeleteTarget(null);
      notify.success(t("deleted"));
    },
    onError: (err) => notify.error(apiError(err)),
  });

  if (!cafeId) return null;

  const posHref = (r: Reservation) => {
    const params = new URLSearchParams({ reservationId: r.id });
    if (r.tableId) params.set("tableId", r.tableId);
    params.set("guestName", r.guestName);
    return `/pos?${params.toString()}`;
  };

  return (
    <div className="space-y-6">
      <h2 className="text-lg font-medium">{t("title")}</h2>

      <Card className="rounded-xl border border-border/80">
        <CardHeader>
          <CardTitle className="text-base">{t("newReservation")}</CardTitle>
          <p className="text-sm text-muted-foreground">{t("newReservationHint")}</p>
        </CardHeader>
        <CardContent className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
          <LabeledField label={t("guest")} htmlFor="res-guest">
            <Input
              id="res-guest"
              value={guestName}
              onChange={(e) => setGuestName(e.target.value)}
            />
          </LabeledField>
          <LabeledField label={t("phone")} htmlFor="res-phone">
            <Input
              id="res-phone"
              value={guestPhone}
              onChange={(e) => setGuestPhone(e.target.value)}
              dir="ltr"
              className="text-end"
            />
          </LabeledField>
          <LabeledField label={t("table")} htmlFor="res-table">
            <select
              id="res-table"
              className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm"
              value={tableId}
              onChange={(e) => setTableId(e.target.value)}
            >
              <option value="">{t("tableOptional")}</option>
              {tables.map((tbl) => (
                <option key={tbl.id} value={tbl.id}>
                  {t("tableNumber", { number: tbl.number })}
                </option>
              ))}
            </select>
          </LabeledField>
          <LabeledField label={t("date")} htmlFor="res-date">
            <JalaliDateField id="res-date" value={date} onChange={setDate} />
          </LabeledField>
          <LabeledField label={t("time")} htmlFor="res-time">
            <Input
              id="res-time"
              type="time"
              value={time}
              onChange={(e) => setTime(e.target.value)}
              dir="ltr"
              className="text-end"
            />
          </LabeledField>
          <LabeledField label={t("party")} htmlFor="res-party">
            <Input
              id="res-party"
              type="number"
              min={1}
              max={20}
              value={partySize}
              onChange={(e) => setPartySize(e.target.value)}
              dir="ltr"
              className="text-end"
            />
          </LabeledField>
          <LabeledField label={t("notes")} htmlFor="res-notes" className="sm:col-span-2 lg:col-span-3">
            <Input
              id="res-notes"
              value={notes}
              onChange={(e) => setNotes(e.target.value)}
            />
          </LabeledField>
          <div className="sm:col-span-2 lg:col-span-3">
            <Can permission="CreateReservation">
              <Button
                onClick={() => createReservation.mutate()}
                disabled={!guestName.trim() || createReservation.isPending}
              >
                {createReservation.isPending ? "..." : t("create")}
              </Button>
            </Can>
          </div>
        </CardContent>
      </Card>

      {isLoading ? (
        <p className="text-sm text-muted-foreground">...</p>
      ) : list.length === 0 ? (
        <p className="text-sm text-muted-foreground">{t("empty")}</p>
      ) : (
        <ul className="space-y-2">
          {list.map((r) => (
            <li key={r.id}>
              <Card className="rounded-xl border border-border/80">
                <CardContent className="flex flex-wrap items-center justify-between gap-3 pt-6">
                  <div>
                    <p className="font-medium">{r.guestName}</p>
                    <p className="text-[11px] text-muted-foreground">
                      {formatIsoDateJalali(r.date, locale)} {r.time.slice(0, 5)} · {formatNumber(r.partySize)} {t("party")}
                      {r.tableNumber ? ` · ${t("tableNumber", { number: r.tableNumber })}` : ""}
                    </p>
                    <p className="text-[11px] text-muted-foreground">{r.guestPhone}</p>
                  </div>
                  <Badge className={cn("border", statusStyle[r.status])}>
                    {t(`status.${r.status}`)}
                  </Badge>
                  <div className="flex flex-wrap gap-2">
                    {r.status === "Pending" && (
                      <>
                        <Can permission="EditReservation">
                          <Button
                            size="sm"
                            onClick={() => updateStatus.mutate({ id: r.id, status: "Confirmed" })}
                          >
                            {t("confirm")}
                          </Button>
                        </Can>
                        <Can permission="EditReservation">
                          <Button
                            size="sm"
                            variant="outline"
                            onClick={() => updateStatus.mutate({ id: r.id, status: "Cancelled" })}
                          >
                            {t("cancel")}
                          </Button>
                        </Can>
                      </>
                    )}
                    {(r.status === "Confirmed" || r.status === "Seated") && (
                      <Button size="sm" asChild>
                        <Link href={posHref(r)}>{t("openPos")}</Link>
                      </Button>
                    )}
                    {r.status === "Seated" && (
                      <Can permission="EditReservation">
                        <Button
                          size="sm"
                          variant="outline"
                          onClick={() => updateStatus.mutate({ id: r.id, status: "Completed" })}
                        >
                          {t("markCompleted")}
                        </Button>
                      </Can>
                    )}
                    <Can permission="DeleteReservation">
                      <Button
                        size="sm"
                        variant="ghost"
                        className="text-red-600 hover:bg-red-50 hover:text-red-700"
                        aria-label={tCommon("delete")}
                        onClick={() => setDeleteTarget(r)}
                      >
                        <Trash2 className="size-4" />
                      </Button>
                    </Can>
                  </div>
                </CardContent>
              </Card>
            </li>
          ))}
        </ul>
      )}

      <ConfirmDialog
        open={!!deleteTarget}
        onOpenChange={(o) => {
          if (!o) setDeleteTarget(null);
        }}
        title={t("deleteConfirmTitle")}
        description={
          deleteTarget ? t("deleteConfirmDesc", { name: deleteTarget.guestName }) : undefined
        }
        busy={deleteReservation.isPending}
        onConfirm={() => deleteTarget && deleteReservation.mutate(deleteTarget.id)}
      />
    </div>
  );
}
