import { useMutation } from "@tanstack/react-query";
import { useSearch } from "@tanstack/react-router";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from "@workspace/ui/components/alert-dialog";
import { Badge } from "@workspace/ui/components/badge";
import { Button } from "@workspace/ui/components/button";
import {
  HoverCard,
  HoverCardContent,
  HoverCardTrigger,
} from "@workspace/ui/components/hover-card";
import { Separator } from "@workspace/ui/components/separator";
import { Combobox } from "@workspace/ui/composed/combobox";
import {
  ProTable,
  type ProTableActions,
} from "@workspace/ui/composed/pro-table/pro-table";
import { cn } from "@workspace/ui/lib/utils";
import {
  activateOrder,
  getOrderList,
  refundOrder,
  updateOrderStatus,
} from "@workspace/ui/services/admin/order";
import { useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";
import { Display } from "@/components/display";
import { useGlobalStore } from "@/stores/global";
import { useSubscribe } from "@/stores/subscribe";
import { formatDate } from "@/utils/common";
import { UserDetail } from "../user/user-detail";

const REFUNDED_ORDER_STATUS = 6;

export default function Order() {
  const { t } = useTranslation("order");
  const sp = useSearch({ strict: false }) as Record<string, string | undefined>;
  const user = useGlobalStore((state) => state.user);
  const [confirmingOrderId, setConfirmingOrderId] = useState<number | null>(
    null
  );
  const initialFilters = {
    user_id: sp.user_id ? Number(sp.user_id) : undefined,
    search: sp.search || undefined,
    status: sp.status || undefined,
    subscribe_id: sp.subscribe_id || undefined,
  };

  const statusOptions = [
    {
      value: 1,
      label: t("status.1", "Pending"),
      className: "bg-orange-500",
    },
    { value: 2, label: t("status.2", "Paid"), className: "bg-green-500" },
    {
      value: 3,
      label: t("status.3", "Cancelled"),
      className: "bg-gray-500",
    },
    { value: 4, label: t("status.4", "Closed"), className: "bg-red-500" },
    {
      value: 5,
      label: t("status.5", "Completed"),
      className: "bg-green-500",
    },
    {
      value: REFUNDED_ORDER_STATUS,
      label: t("status.6", "Refunded"),
      className: "bg-red-500",
    },
  ];

  const typeOptions = [
    { value: 1, label: t("type.1", "New Purchase") },
    { value: 2, label: t("type.2", "Renewal") },
    { value: 3, label: t("type.3", "Reset Traffic") },
    { value: 4, label: t("type.4", "Recharge") },
  ];

  const ref = useRef<ProTableActions>(null);

  const { subscribes, getSubscribeName } = useSubscribe();
  const canRefundOrders = Boolean(user?.is_admin);

  const refundMutation = useMutation({
    mutationFn: async (order: API.Order) => {
      await refundOrder({ id: order.id });
    },
    onSuccess: () => {
      toast.success(t("refundSuccess", "Refund completed."));
      setConfirmingOrderId(null);
      ref.current?.refresh();
    },
    onError: (error) => {
      console.error("Refund order failed", error);
      setConfirmingOrderId(null);
    },
  });

  const isRefundedOrder = (order: API.Order) =>
    order.status === REFUNDED_ORDER_STATUS ||
    order.status_name === t("status.6", "Refunded") ||
    order.status_name?.toLowerCase() === "refunded";

  const canRefundOrder = (order: API.Order) =>
    canRefundOrders && !isRefundedOrder(order);

  return (
    <ProTable<API.Order, any>
      action={ref}
      actions={{
        render: (order) => {
          if (!canRefundOrder(order)) return [];

          const isPending =
            refundMutation.isPending && confirmingOrderId === order.id;

          return [
            <AlertDialog
              key={`refund-${order.id}`}
              onOpenChange={(open) => {
                setConfirmingOrderId(open ? order.id : null);
              }}
              open={confirmingOrderId === order.id}
            >
              <AlertDialogTrigger asChild>
                <Button disabled={isPending} size="sm" variant="destructive">
                  {isPending
                    ? t("refundSubmitting", "Refunding...")
                    : t("refund", "Refund")}
                </Button>
              </AlertDialogTrigger>
              <AlertDialogContent>
                <AlertDialogHeader>
                  <AlertDialogTitle>
                    {t("refundConfirmTitle", "Confirm refund")}
                  </AlertDialogTitle>
                  <AlertDialogDescription asChild>
                    <div className="space-y-2">
                      <p>
                        {t(
                          "refundConfirmDescription",
                          "This refund will immediately invalidate the user's subscription and deduct the related agent commission."
                        )}
                      </p>
                      <p className="font-medium text-foreground">
                        {t(
                          "refundConfirmWarning",
                          "This action cannot be repeated after the order is refunded."
                        )}
                      </p>
                    </div>
                  </AlertDialogDescription>
                </AlertDialogHeader>
                <AlertDialogFooter>
                  <AlertDialogCancel disabled={isPending}>
                    {t("cancel", "Cancel")}
                  </AlertDialogCancel>
                  <AlertDialogAction
                    className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
                    disabled={isPending}
                    onClick={async (event) => {
                      event.preventDefault();
                      if (isPending) return;
                      await refundMutation.mutateAsync(order);
                    }}
                  >
                    {isPending
                      ? t("refundSubmitting", "Refunding...")
                      : t("confirmRefund", "Confirm refund")}
                  </AlertDialogAction>
                </AlertDialogFooter>
              </AlertDialogContent>
            </AlertDialog>,
          ];
        },
      }}
      columns={[
        {
          accessorKey: "order_no",
          header: t("orderNumber", "Order Number"),
        },
        {
          accessorKey: "type",
          header: t("type.0", "Type"),
          cell: ({ row }) => {
            const type = row.getValue("type") as number;
            return (
              typeOptions.find((opt) => opt.value === type)?.label ||
              t(`type.${type}`)
            );
          },
        },
        {
          accessorKey: "subscribe_id",
          header: t("subscribe", "Subscribe"),
          cell: ({ row }) => {
            const order = row.original as API.Order;
            if (order.type === 4) {
              const type = row.getValue("type") as number;
              return (
                typeOptions.find((opt) => opt.value === type)?.label ||
                t(`type.${type}`)
              );
            }
            const name = getSubscribeName(order.subscribe_id);
            const quantity = order.quantity;
            return name ? `${name} × ${quantity}` : "";
          },
        },
        {
          accessorKey: "amount",
          header: t("amount", "Amount"),
          cell: ({ row }) => {
            const order = row.original as API.Order;
            return (
              <HoverCard>
                <HoverCardTrigger asChild>
                  <Button className="p-0" variant="link">
                    <Display type="currency" value={order.amount} />
                  </Button>
                </HoverCardTrigger>
                <HoverCardContent>
                  <div className="grid gap-3">
                    {order.trade_no && (
                      <>
                        <div className="font-semibold">
                          {t("tradeNo", "Transaction Number")}
                        </div>
                        <span className="text-muted-foreground">
                          {order.trade_no}
                        </span>
                        <Separator className="my-2" />
                      </>
                    )}
                    <ul className="grid gap-3">
                      <li className="flex items-center justify-between">
                        <span className="text-muted-foreground">
                          {t("subscribePrice", "Subscription Price")}
                        </span>
                        <span>
                          <Display type="currency" value={order.price} />
                        </span>
                      </li>
                      <li className="flex items-center justify-between">
                        <span className="text-muted-foreground">
                          {t("discount", "Discount Amount")}
                        </span>
                        <span>
                          <Display type="currency" value={order.discount} />
                        </span>
                      </li>
                      <li className="flex items-center justify-between">
                        <span className="text-muted-foreground">
                          {t("couponDiscount", "Coupon Discount")}
                        </span>
                        <span>
                          <Display
                            type="currency"
                            value={order.coupon_discount}
                          />
                        </span>
                      </li>
                      <li className="flex items-center justify-between">
                        <span className="text-muted-foreground">
                          {t("feeAmount", "Fee Amount")}
                        </span>
                        <span>
                          <Display type="currency" value={order.fee_amount} />
                        </span>
                      </li>
                      <li className="flex items-center justify-between font-semibold">
                        <span className="text-muted-foreground">
                          {t("total", "Total")}
                        </span>
                        <span>
                          <Display type="currency" value={order.amount} />
                        </span>
                      </li>
                    </ul>
                  </div>
                  <Separator className="my-4" />
                  <ul className="grid gap-3">
                    <li className="flex items-center justify-between">
                      <span className="text-muted-foreground">
                        {t("method", "Payment Method")}
                      </span>
                      <span>
                        {order.payment?.name || order.payment?.platform}
                      </span>
                    </li>
                  </ul>
                </HoverCardContent>
              </HoverCard>
            );
          },
        },
        {
          accessorKey: "payment",
          header: t("method", "Payment Method"),
          cell: ({ row }) => {
            const order = row.original as API.Order;
            return order.payment?.name || order.payment?.platform || "--";
          },
        },
        {
          accessorKey: "user_id",
          header: t("user", "User"),
          cell: ({ row }) => {
            const order = row.original as API.Order;
            return <UserDetail id={order.user_id} />;
          },
        },
        {
          accessorKey: "updated_at",
          header: t("updateTime", "Update Time"),
          cell: ({ row }) => {
            const order = row.original as API.Order;
            return formatDate(order.updated_at);
          },
        },
        {
          accessorKey: "status",
          header: t("status.0", "Status"),
          cell: ({ row }) => {
            const order = row.original as API.Order;
            const option = statusOptions.find(
              (opt) => opt.value === order.status
            );
            if ([1, 3, 4].includes(row.getValue("status"))) {
              return (
                <div className="flex items-center gap-1">
                  <Combobox<number, false>
                    className={cn(option?.className)}
                    onChange={async (value) => {
                      await updateOrderStatus({
                        id: order.id,
                        status: value,
                      });
                      ref.current?.refresh();
                    }}
                    options={statusOptions}
                    placeholder={t("status.0", "Status")}
                    value={order.status}
                  />
                  {[1, 3].includes(order.status) && (
                    <Button
                      onClick={async () => {
                        await activateOrder({ order_no: order.order_no });
                        ref.current?.refresh();
                      }}
                      size="sm"
                      variant="outline"
                    >
                      {t("activate", "Activate")}
                    </Button>
                  )}
                </div>
              );
            }
            return (
              <Badge
                variant={isRefundedOrder(order) ? "destructive" : "default"}
              >
                {option?.label ||
                  (order.status_name
                    ? t(`status.${row.getValue("status")}`, order.status_name)
                    : t(`status.${row.getValue("status")}`))}
              </Badge>
            );
          },
        },
      ]}
      initialFilters={initialFilters}
      params={[
        {
          key: "status",
          placeholder: t("status.0", "Status"),
          options: statusOptions.map((item) => ({
            label: item.label,
            value: String(item.value),
          })),
        },
        {
          key: "subscribe_id",
          placeholder: `${t("subscribe", "Subscribe")}`,
          options: subscribes?.map((item) => ({
            label: item.name!,
            value: String(item.id),
          })),
        },
        { key: "search" },
        {
          key: "user_id",
          placeholder: `${t("user", "User")} ID`,
          options: undefined,
        },
      ]}
      request={async (pagination, filter) => {
        const { data } = await getOrderList({ ...pagination, ...filter });
        return {
          list: data.data?.list || [],
          total: data.data?.total || 0,
        };
      }}
    />
  );
}
