"use client";

import { useMemo, useState } from "react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { RotateCcw, ClipboardList } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Card } from "@/components/ui/card";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { Pagination } from "@/components/shared/pagination";
import { ConfirmDialog } from "@/components/shared/confirm-dialog";
import { DebouncedSearch } from "@/components/shared/debounced-search";
import { EmptyState, ErrorState, TableSkeleton } from "@/components/shared/states";
import { PushDeliveryStatusBadge } from "@/features/push/push-badges";
import { getPushDeliveries, resendPushDelivery, type DeliveryStatusFilter } from "@/services/push";
import { queryKeys } from "@/lib/query-keys";
import { useUrlState } from "@/lib/use-url-state";
import { useI18n, useT } from "@/i18n";
import { formatDateTime, formatRelative, truncate } from "@/lib/format";
import { friendlyErrorMessage } from "@/lib/errors";
import { useCan } from "@/features/auth/use-can";
import type { PushDelivery } from "@/types/push";

const DELIVERY_STATUSES: DeliveryStatusFilter[] = ["sent", "failed", "no_device"];

export function DeliveriesTab() {
  const t = useT();
  const { locale } = useI18n();
  const { can } = useCan();
  const queryClient = useQueryClient();
  const canResend = can("push.send");

  const [page, setPage] = useUrlState("dl_page", 1, (value) => {
    const n = Number(value);
    return Number.isFinite(n) && n >= 1 ? n : null;
  });
  const [status, setStatus] = useUrlState("dl_status", "", (value) =>
    (DELIVERY_STATUSES as readonly string[]).includes(value) ? value : null,
  );
  const [notification, setNotification] = useUrlState("dl_notification", "", (value) => value);
  const [from, setFrom] = useUrlState("dl_from", "", (value) => value);
  const [to, setTo] = useUrlState("dl_to", "", (value) => value);

  const [detail, setDetail] = useState<PushDelivery | null>(null);
  const [resending, setResending] = useState<PushDelivery | null>(null);

  const filters = useMemo(
    () => ({
      page,
      rows: 10,
      status: (status || undefined) as DeliveryStatusFilter | undefined,
      notification: notification || undefined,
      from: from || undefined,
      to: to || undefined,
    }),
    [page, status, notification, from, to],
  );

  const query = useQuery({
    queryKey: queryKeys.push.deliveries(filters),
    queryFn: () => getPushDeliveries(filters),
  });

  const resendMutation = useMutation({
    mutationFn: resendPushDelivery,
    onSuccess: (response) => {
      toast.success(response.Message || t("push.resendSuccess"));
      setResending(null);
      void queryClient.invalidateQueries({ queryKey: ["push", "deliveries"] });
      void queryClient.invalidateQueries({ queryKey: queryKeys.push.stats });
    },
    onError: (error) => {
      toast.error(friendlyErrorMessage(error, t));
    },
  });

  const deliveries = query.data?.Model ?? [];
  const hasFilters = Boolean(status || notification || from || to);

  function resetPage() {
    setPage(1);
  }

  function clearFilters() {
    resetPage();
    setStatus("");
    setNotification("");
    setFrom("");
    setTo("");
  }

  return (
    <>
      <Card>
        <div className="flex flex-col gap-3 border-b p-4 lg:flex-row lg:flex-wrap lg:items-center">
          <DebouncedSearch
            value={notification}
            onChange={(value) => {
              resetPage();
              setNotification(value);
            }}
            placeholder={t("push.filterNotification")}
            className="w-full lg:max-w-xs lg:flex-1"
          />
          <div className="flex flex-wrap items-center gap-2">
            <Select
              value={status || "all"}
              onValueChange={(value) => {
                resetPage();
                setStatus(value === "all" ? "" : value);
              }}
            >
              <SelectTrigger className="w-40" aria-label={t("push.filterStatus")}>
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="all">{t("push.filterStatus")}: {t("common.all")}</SelectItem>
                {DELIVERY_STATUSES.map((option) => (
                  <SelectItem key={option} value={option}>
                    {t(`push.delivery.${option}`)}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
            <Input
              type="date"
              value={from}
              onChange={(event) => {
                resetPage();
                setFrom(event.target.value);
              }}
              aria-label={t("push.filterFrom")}
              className="w-40"
              dir="ltr"
            />
            <Input
              type="date"
              value={to}
              onChange={(event) => {
                resetPage();
                setTo(event.target.value);
              }}
              aria-label={t("push.filterTo")}
              className="w-40"
              dir="ltr"
            />
            {hasFilters ? (
              <Button variant="ghost" size="sm" onClick={clearFilters}>
                {t("common.clearFilters")}
              </Button>
            ) : null}
          </div>
        </div>

        {query.isPending ? (
          <TableSkeleton rows={8} cols={6} />
        ) : query.isError ? (
          <ErrorState message={friendlyErrorMessage(query.error, t)} onRetry={() => query.refetch()} />
        ) : deliveries.length === 0 ? (
          <EmptyState title={t("push.emptyDeliveries")} description={t("push.emptyDeliveriesHint")} icon={ClipboardList} />
        ) : (
          <>
            <div className="overflow-x-auto">
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead>{t("common.status")}</TableHead>
                    <TableHead>{t("push.recipient")}</TableHead>
                    <TableHead>{t("push.titleField")}</TableHead>
                    <TableHead>{t("common.createdAt")}</TableHead>
                    <TableHead aria-label={t("common.actions")} />
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {deliveries.map((delivery) => (
                    <TableRow key={delivery.uuid}>
                      <TableCell>
                        <PushDeliveryStatusBadge status={delivery.status} label={delivery.status_label} />
                      </TableCell>
                      <TableCell>
                        <p className="max-w-40 truncate font-medium text-foreground">
                          {delivery.recipient?.name ?? "—"}
                        </p>
                        {delivery.device ? (
                          <p className="numeric max-w-40 truncate text-xs text-muted-foreground" dir="ltr">
                            {delivery.device}
                          </p>
                        ) : null}
                      </TableCell>
                      <TableCell>
                        <p className="max-w-56 truncate font-medium text-foreground">{delivery.title}</p>
                        <p className="numeric max-w-56 truncate text-xs text-muted-foreground">
                          {truncate(delivery.body, 40)}
                        </p>
                      </TableCell>
                      <TableCell>
                        <p className="text-xs text-muted-foreground" title={formatDateTime(delivery.created_at, locale)}>
                          {formatRelative(delivery.created_at, locale)}
                        </p>
                      </TableCell>
                      <TableCell>
                        <div className="flex items-center gap-2">
                          <Button variant="outline" size="sm" onClick={() => setDetail(delivery)}>
                            {t("push.details")}
                          </Button>
                          {canResend ? (
                            <Button variant="outline" size="sm" onClick={() => setResending(delivery)}>
                              <RotateCcw className="h-3.5 w-3.5" aria-hidden />
                              {t("push.resend")}
                            </Button>
                          ) : null}
                        </div>
                      </TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </div>
            <Pagination page={query.data!.Page} totalPages={query.data!.Total} records={query.data!.Records} onPageChange={setPage} />
          </>
        )}
      </Card>

      <Dialog open={detail !== null} onOpenChange={(next) => !next && setDetail(null)}>
        <DialogContent className="max-w-lg">
          <DialogHeader>
            <DialogTitle>{detail?.title}</DialogTitle>
            <DialogDescription>
              {detail ? (
                <>
                  {detail.recipient?.name ?? "—"} · {detail.status_label}
                </>
              ) : null}
            </DialogDescription>
          </DialogHeader>
          {detail ? (
            <div className="space-y-4 text-sm">
              <div className="rounded-lg border p-3 text-xs leading-relaxed text-muted-foreground">
                {detail.body || "—"}
              </div>
              <dl className="grid grid-cols-2 gap-x-4 gap-y-3">
                <div>
                  <dt className="text-xs text-muted-foreground">{t("push.notification")}</dt>
                  <dd className="font-medium">{detail.notification}</dd>
                </div>
                <div>
                  <dt className="text-xs text-muted-foreground">{t("push.recipient")}</dt>
                  <dd className="font-medium">{detail.recipient?.name ?? "—"}</dd>
                </div>
                <div>
                  <dt className="text-xs text-muted-foreground">{t("push.device")}</dt>
                  <dd className="numeric font-medium" dir="ltr">{detail.device ?? "—"}</dd>
                </div>
                <div>
                  <dt className="text-xs text-muted-foreground">{t("common.createdAt")}</dt>
                  <dd className="font-medium">{formatDateTime(detail.created_at, locale)}</dd>
                </div>
                {detail.message_id ? (
                  <div className="col-span-2">
                    <dt className="text-xs text-muted-foreground">{t("push.messageId")}</dt>
                    <dd className="numeric break-all font-medium" dir="ltr">{detail.message_id}</dd>
                  </div>
                ) : null}
                {detail.error ? (
                  <div className="col-span-2">
                    <dt className="text-xs text-muted-foreground">{t("push.error")}</dt>
                    <dd className="break-words text-destructive">{detail.error}</dd>
                  </div>
                ) : null}
              </dl>
            </div>
          ) : null}
        </DialogContent>
      </Dialog>

      <ConfirmDialog
        open={resending !== null}
        onOpenChange={(next) => !next && setResending(null)}
        title={t("push.resendTitle")}
        description={t("push.resendBody", {
          captain: resending?.recipient?.name ?? "—",
        })}
        confirmLabel={t("push.resend")}
        loading={resendMutation.isPending}
        onConfirm={() => {
          if (resending) resendMutation.mutate(resending.uuid);
        }}
      />
    </>
  );
}