import {
  Alert,
  AlertDescription,
  AlertTitle,
} from "@workspace/ui/components/alert";
import { Badge } from "@workspace/ui/components/badge";
import { Button } from "@workspace/ui/components/button";
import { Switch } from "@workspace/ui/components/switch";
import {
  Tabs,
  TabsContent,
  TabsList,
  TabsTrigger,
} from "@workspace/ui/components/tabs";
import { ConfirmButton } from "@workspace/ui/composed/confirm-button";
import Empty from "@workspace/ui/composed/empty";
import {
  ProTable,
  type ProTableActions,
} from "@workspace/ui/composed/pro-table/pro-table";
import {
  createPromoPrice,
  createPromoRule,
  deletePromoPrice,
  deletePromoRule,
  getPromoPriceList,
  getPromoRuleList,
  getPromoUsageList,
  updatePromoRule,
} from "@workspace/ui/services/admin/promo";
import { CircleAlert } from "lucide-react";
import { useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";
import { useSubscribe } from "@/stores/subscribe";
import { formatDate } from "@/utils/common";
import PriceForm from "./price-form";
import RuleDetail from "./rule-detail";
import RuleForm from "./rule-form";
import { formatCurrency, parseOptionalNumber, promoRuleTypes } from "./utils";

type RuleFilters = {
  search?: string;
  type?: API.PromoRuleType;
  enabled?: string;
};

type PriceFilters = {
  promo_rule_id?: string;
  subscribe_id?: string;
};

type UsageFilters = PriceFilters & {
  user_id?: string;
  order_no?: string;
};

function ErrorState({
  title,
  description,
}: {
  title: string;
  description: string;
}) {
  return (
    <Alert className="mx-auto max-w-md" variant="destructive">
      <CircleAlert aria-hidden="true" />
      <AlertTitle>{title}</AlertTitle>
      <AlertDescription>{description}</AlertDescription>
    </Alert>
  );
}

export default function PromoPage() {
  const { t } = useTranslation("promo");
  const { subscribes, getSubscribeName } = useSubscribe();
  const [loading, setLoading] = useState(false);
  const [rules, setRules] = useState<API.PromoRule[]>([]);
  const [detailRule, setDetailRule] = useState<API.PromoRule>();
  const [detailOpen, setDetailOpen] = useState(false);
  const ruleRef = useRef<ProTableActions>(null);
  const priceRef = useRef<ProTableActions>(null);
  const usageRef = useRef<ProTableActions>(null);

  return (
    <>
      <Tabs className="space-y-4" defaultValue="rules">
        <TabsList className="grid w-full grid-cols-3 md:w-fit">
          <TabsTrigger value="rules">{t("rules", "Rules")}</TabsTrigger>
          <TabsTrigger value="prices">{t("prices", "Prices")}</TabsTrigger>
          <TabsTrigger value="usage">{t("usage", "Usage")}</TabsTrigger>
        </TabsList>

        <TabsContent value="rules">
          <ProTable<API.PromoRule, RuleFilters>
            action={ruleRef}
            actions={{
              render: (row) => [
                <Button
                  key="detail"
                  onClick={() => {
                    setDetailRule(row);
                    setDetailOpen(true);
                  }}
                  size="sm"
                  variant="outline"
                >
                  {t("detail", "Detail")}
                </Button>,
                <RuleForm
                  initialValues={row}
                  key="edit"
                  loading={loading}
                  onSubmit={async (values) => {
                    setLoading(true);
                    try {
                      await updatePromoRule({ id: row.id }, values);
                      toast.success(t("updateSuccess", "Update Success"));
                      ruleRef.current?.refresh();
                      setLoading(false);
                      return true;
                    } catch (_error) {
                      setLoading(false);
                      return false;
                    }
                  }}
                  title={t("editRule", "Edit Rule")}
                  trigger={t("edit", "Edit")}
                />,
                <ConfirmButton
                  cancelText={t("cancel", "Cancel")}
                  confirmText={t("confirm", "Confirm")}
                  description={t(
                    "deleteWarning",
                    "Once deleted, data cannot be recovered. Please proceed with caution."
                  )}
                  key="delete"
                  onConfirm={async () => {
                    await deletePromoRule({ id: row.id });
                    toast.success(t("deleteSuccess", "Delete Success"));
                    ruleRef.current?.refresh();
                  }}
                  title={t("confirmDelete", "Are you sure you want to delete?")}
                  trigger={
                    <Button size="sm" variant="destructive">
                      {t("delete", "Delete")}
                    </Button>
                  }
                />,
              ],
            }}
            columns={[
              {
                accessorKey: "name",
                header: t("name", "Name"),
              },
              {
                accessorKey: "type",
                header: t("type", "Type"),
                cell: ({ row }) => (
                  <Badge variant="outline">
                    {t(`types.${row.original.type}`, row.original.type)}
                  </Badge>
                ),
              },
              {
                accessorKey: "priority",
                header: t("priority", "Priority"),
              },
              {
                accessorKey: "enabled",
                header: t("enabled", "Enabled"),
                cell: ({ row }) => (
                  <Switch
                    defaultChecked={row.original.enabled}
                    onCheckedChange={async (checked) => {
                      await updatePromoRule(
                        { id: row.original.id },
                        { ...row.original, enabled: checked }
                      );
                      toast.success(t("updateSuccess", "Update Success"));
                      ruleRef.current?.refresh();
                    }}
                  />
                ),
              },
              {
                accessorKey: "start_time",
                header: t("startTime", "Start Time"),
                cell: ({ row }) =>
                  row.original.start_time
                    ? formatDate(row.original.start_time)
                    : "--",
              },
              {
                accessorKey: "end_time",
                header: t("endTime", "End Time"),
                cell: ({ row }) =>
                  row.original.end_time
                    ? formatDate(row.original.end_time)
                    : "--",
              },
            ]}
            empty={<Empty description={t("emptyRules", "No promo rules")} />}
            error={
              <ErrorState
                description={t(
                  "loadErrorDescription",
                  "Refresh the table or try again later."
                )}
                title={t("loadRulesError", "Failed to load promo rules")}
              />
            }
            header={{
              toolbar: (
                <RuleForm
                  loading={loading}
                  onSubmit={async (values) => {
                    setLoading(true);
                    try {
                      await createPromoRule(values);
                      toast.success(t("createSuccess", "Create Success"));
                      ruleRef.current?.refresh();
                      setLoading(false);
                      return true;
                    } catch (_error) {
                      setLoading(false);
                      return false;
                    }
                  }}
                  title={t("createRule", "Create Rule")}
                  trigger={t("createRule", "Create Rule")}
                />
              ),
            }}
            params={[
              { key: "search", placeholder: t("searchRule", "Rule name") },
              {
                key: "type",
                placeholder: t("type", "Type"),
                options: promoRuleTypes.map((type) => ({
                  label: t(`types.${type}`, type),
                  value: type,
                })),
              },
              {
                key: "enabled",
                placeholder: t("enabled", "Enabled"),
                options: [
                  { label: t("yes", "Yes"), value: "true" },
                  { label: t("no", "No"), value: "false" },
                ],
              },
            ]}
            request={async (pagination, filters) => {
              const { data } = await getPromoRuleList({
                ...pagination,
                search: filters.search?.trim() || undefined,
                type: filters.type,
                enabled:
                  filters.enabled === undefined || filters.enabled === ""
                    ? undefined
                    : filters.enabled === "true",
              });
              const list = data.data?.list || [];
              setRules(list);
              return {
                list,
                total: data.data?.total || 0,
              };
            }}
          />
        </TabsContent>

        <TabsContent value="prices">
          <ProTable<API.PromoPrice, PriceFilters>
            action={priceRef}
            actions={{
              render: (row) => [
                <ConfirmButton
                  cancelText={t("cancel", "Cancel")}
                  confirmText={t("confirm", "Confirm")}
                  description={t(
                    "deleteWarning",
                    "Once deleted, data cannot be recovered. Please proceed with caution."
                  )}
                  key="delete"
                  onConfirm={async () => {
                    await deletePromoPrice({ id: row.id });
                    toast.success(t("deleteSuccess", "Delete Success"));
                    priceRef.current?.refresh();
                  }}
                  title={t("confirmDelete", "Are you sure you want to delete?")}
                  trigger={
                    <Button size="sm" variant="destructive">
                      {t("delete", "Delete")}
                    </Button>
                  }
                />,
              ],
            }}
            columns={[
              {
                accessorKey: "promo_rule_id",
                header: t("rule", "Rule"),
                cell: ({ row }) =>
                  row.original.promo_rule_id
                    ? rules.find(
                        (rule) => rule.id === row.original.promo_rule_id
                      )?.name || `#${row.original.promo_rule_id}`
                    : "--",
              },
              {
                accessorKey: "subscribe_id",
                header: t("subscribe", "Subscribe"),
                cell: ({ row }) =>
                  row.original.subscribe_name ||
                  getSubscribeName(row.original.subscribe_id),
              },
              {
                accessorKey: "quantity",
                header: t("quantity", "Quantity"),
                cell: ({ row }) => row.original.quantity || "--",
              },
              {
                accessorKey: "unit_price",
                header: t("unitPrice", "Unit Price"),
                cell: ({ row }) => formatCurrency(row.original.unit_price),
              },
              {
                accessorKey: "promo_price",
                header: t("promoPrice", "Promo Price"),
                cell: ({ row }) => formatCurrency(row.original.promo_price),
              },
            ]}
            empty={<Empty description={t("emptyPrices", "No promo prices")} />}
            error={
              <ErrorState
                description={t(
                  "loadErrorDescription",
                  "Refresh the table or try again later."
                )}
                title={t("loadPricesError", "Failed to load promo prices")}
              />
            }
            header={{
              toolbar: (
                <PriceForm
                  loading={loading}
                  onSubmit={async (values) => {
                    setLoading(true);
                    try {
                      await createPromoPrice(values);
                      toast.success(t("createSuccess", "Create Success"));
                      priceRef.current?.refresh();
                      setLoading(false);
                      return true;
                    } catch (_error) {
                      setLoading(false);
                      return false;
                    }
                  }}
                  rules={rules}
                  subscribes={subscribes}
                />
              ),
            }}
            params={[
              {
                key: "promo_rule_id",
                placeholder: t("rule", "Rule"),
                options: rules.map((rule) => ({
                  label: rule.name,
                  value: String(rule.id),
                })),
              },
              {
                key: "subscribe_id",
                placeholder: t("subscribe", "Subscribe"),
                options: subscribes
                  .filter((item) => typeof item.id === "number")
                  .map((item) => ({
                    label: item.name || `#${item.id}`,
                    value: String(item.id),
                  })),
              },
            ]}
            request={async (pagination, filters) => {
              const { data } = await getPromoPriceList({
                ...pagination,
                promo_rule_id: parseOptionalNumber(filters.promo_rule_id),
                subscribe_id: parseOptionalNumber(filters.subscribe_id),
              });
              return {
                list: data.data?.list || [],
                total: data.data?.total || 0,
              };
            }}
          />
        </TabsContent>

        <TabsContent value="usage">
          <ProTable<API.PromoUsage, UsageFilters>
            action={usageRef}
            columns={[
              {
                accessorKey: "promo_rule_id",
                header: t("rule", "Rule"),
                cell: ({ row }) =>
                  row.original.rule_name ||
                  rules.find((rule) => rule.id === row.original.promo_rule_id)
                    ?.name ||
                  `#${row.original.promo_rule_id}`,
              },
              {
                accessorKey: "user_id",
                header: t("userId", "User ID"),
                cell: ({ row }) => `#${row.original.user_id}`,
              },
              {
                accessorKey: "subscribe_id",
                header: t("subscribe", "Subscribe"),
                cell: ({ row }) =>
                  row.original.subscribe_name ||
                  getSubscribeName(row.original.subscribe_id),
              },
              {
                accessorKey: "quantity",
                header: t("quantity", "Quantity"),
                cell: ({ row }) => row.original.quantity || "--",
              },
              {
                accessorKey: "order_no",
                header: t("orderNo", "Order No."),
              },
              {
                accessorKey: "promo_price",
                header: t("promoPrice", "Promo Price"),
                cell: ({ row }) => formatCurrency(row.original.promo_price),
              },
              {
                accessorKey: "used_at",
                header: t("usedAt", "Used At"),
                cell: ({ row }) => formatDate(row.original.used_at),
              },
            ]}
            empty={
              <Empty description={t("emptyUsage", "No promo usage records")} />
            }
            error={
              <ErrorState
                description={t(
                  "loadErrorDescription",
                  "Refresh the table or try again later."
                )}
                title={t("loadUsageError", "Failed to load promo usage")}
              />
            }
            params={[
              {
                key: "promo_rule_id",
                placeholder: t("rule", "Rule"),
                options: rules.map((rule) => ({
                  label: rule.name,
                  value: String(rule.id),
                })),
              },
              {
                key: "subscribe_id",
                placeholder: t("subscribe", "Subscribe"),
                options: subscribes
                  .filter((item) => typeof item.id === "number")
                  .map((item) => ({
                    label: item.name || `#${item.id}`,
                    value: String(item.id),
                  })),
              },
              { key: "user_id", placeholder: t("userId", "User ID") },
              { key: "order_no", placeholder: t("orderNo", "Order No.") },
            ]}
            request={async (pagination, filters) => {
              const { data } = await getPromoUsageList({
                ...pagination,
                promo_rule_id: parseOptionalNumber(filters.promo_rule_id),
                subscribe_id: parseOptionalNumber(filters.subscribe_id),
                user_id: parseOptionalNumber(filters.user_id),
                order_no: filters.order_no?.trim() || undefined,
              });
              return {
                list: data.data?.list || [],
                total: data.data?.total || 0,
              };
            }}
          />
        </TabsContent>
      </Tabs>
      <RuleDetail
        onOpenChange={setDetailOpen}
        open={detailOpen}
        rule={detailRule}
      />
    </>
  );
}
