import { Link, useNavigate } from "@tanstack/react-router";
import { Alert, AlertDescription } from "@workspace/ui/components/alert";
import { Badge } from "@workspace/ui/components/badge";
import { Button } from "@workspace/ui/components/button";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@workspace/ui/components/dropdown-menu";
import { ConfirmButton } from "@workspace/ui/composed/confirm-button";
import {
  ProTable,
  type ProTableActions,
} from "@workspace/ui/composed/pro-table/pro-table";
import {
  createUserSubscribe,
  deleteUserSubscribe,
  getFamilyList,
  getUserSubscribe,
  resetUserSubscribeToken,
  toggleUserSubscribeStatus,
  updateUserSubscribe,
} from "@workspace/ui/services/admin/user";
import { Info } from "lucide-react";
import { useCallback, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";
import { Display } from "@/components/display";
import { useGlobalStore } from "@/stores/global";
import { formatDate } from "@/utils/common";
import { SubscriptionDetail } from "./subscription-detail";
import {
  SubscriptionForm,
  type SubscriptionFormValues,
} from "./subscription-form";

interface SharedInfo {
  ownerUserId: number;
  familyId: number;
}

function toUserSubscribePayload(values: SubscriptionFormValues) {
  return {
    ...values,
    expired_at: values.expired_at || 0,
    subscribe_id: values.subscribe_id || 0,
    traffic: values.traffic || 0,
    upload: values.upload || 0,
    download: values.download || 0,
    speed_limit: values.speed_limit || 0,
    device_limit: values.device_limit || 0,
    traffic_limit: values.traffic_limit || [],
  };
}

export default function UserSubscription({ userId }: { userId: number }) {
  const { t } = useTranslation("user");
  const [loading, setLoading] = useState(false);
  const ref = useRef<ProTableActions>(null);
  const [sharedInfo, setSharedInfo] = useState<SharedInfo | null>(null);
  const navigate = useNavigate();

  const request = useCallback(
    async (pagination: { page: number; size: number }) => {
      // 1. Fetch user's own subscriptions
      const { data } = await getUserSubscribe({
        user_id: userId,
        ...pagination,
      });
      const list = data.data?.list || [];
      const total = data.data?.total || 0;

      // 2. If user has own subscriptions, show them directly
      if (list.length > 0) {
        setSharedInfo(null);
        return { list, total };
      }

      // 3. Check if user belongs to a device group
      try {
        const { data: familyData } = await getFamilyList({
          user_id: userId,
          page: 1,
          size: 1,
        });
        const familyList = familyData.data?.list || [];
        const family = familyList.find(
          (f) => f.owner_user_id !== userId && f.status === "active"
        );

        if (family) {
          // 4. Fetch owner's subscriptions
          const { data: ownerData } = await getUserSubscribe({
            user_id: family.owner_user_id,
            ...pagination,
          });
          const ownerList = ownerData.data?.list || [];
          const ownerTotal = ownerData.data?.total || 0;

          if (ownerList.length > 0) {
            setSharedInfo({
              ownerUserId: family.owner_user_id,
              familyId: family.family_id,
            });
            return { list: ownerList, total: ownerTotal };
          }
        }
      } catch {
        // Silently fall through to show empty list
      }

      setSharedInfo(null);
      return { list: [], total: 0 };
    },
    [userId]
  );

  const isSharedView = !!sharedInfo;

  return (
    <div className="space-y-3">
      {isSharedView && (
        <Alert>
          <Info className="h-4 w-4" />
          <AlertDescription className="flex items-center justify-between">
            <span>
              {t("sharedSubscriptionInfo", {
                defaultValue:
                  "This user is a device group member. Showing shared subscriptions from owner (ID: {{ownerId}})",
                ownerId: sharedInfo.ownerUserId,
              })}
            </span>
            <span className="flex gap-2">
              <Button asChild size="sm" variant="outline">
                <Link
                  search={{ user_id: sharedInfo.ownerUserId }}
                  to="/dashboard/family"
                >
                  {t("viewDeviceGroup", "View Device Group")}
                </Link>
              </Button>
              <Button
                onClick={() => {
                  navigate({
                    to: "/dashboard/user",
                    search: { user_id: sharedInfo.ownerUserId },
                  });
                }}
                size="sm"
                variant="outline"
              >
                {t("viewOwner", "View Owner")}
              </Button>
            </span>
          </AlertDescription>
        </Alert>
      )}
      <ProTable<API.UserSubscribe, Record<string, unknown>>
        action={ref}
        actions={{
          render: (row) =>
            isSharedView
              ? [
                  <Badge key="shared" variant="secondary">
                    {t("sharedSubscription", "Shared")}
                  </Badge>,
                  <RowReadOnlyActions
                    key="more"
                    refresh={() => ref.current?.refresh()}
                    row={row}
                    token={row.token}
                    userId={sharedInfo!.ownerUserId}
                  />,
                ]
              : [
                  <SubscriptionForm
                    initialData={row}
                    key="edit"
                    loading={loading}
                    onSubmit={async (values) => {
                      setLoading(true);
                      await updateUserSubscribe({
                        user_id: Number(userId),
                        user_subscribe_id: row.id,
                        ...toUserSubscribePayload(values),
                      });
                      toast.success(t("updateSuccess", "Updated successfully"));
                      ref.current?.refresh();
                      setLoading(false);
                      return true;
                    }}
                    title={t("editSubscription", "Edit Subscription")}
                    trigger={t("edit", "Edit")}
                  />,
                  <RowMoreActions
                    key="more"
                    refresh={() => ref.current?.refresh()}
                    row={row}
                    token={row.token}
                    userId={userId}
                  />,
                ],
        }}
        columns={[
          {
            accessorKey: "id",
            header: "ID",
          },
          {
            accessorKey: "name",
            header: t("subscriptionName", "Subscription Name"),
            cell: ({ row }) => (
              <span className="flex items-center gap-2">
                {row.original.subscribe.name}
                {isSharedView && (
                  <Badge variant="secondary">
                    {t("sharedSubscription", "Shared")}
                  </Badge>
                )}
              </span>
            ),
          },
          {
            accessorKey: "status",
            header: t("status", "Status"),
            cell: ({ row }) => {
              const status = row.getValue("status") as number;
              const expireTime = row.original.expire_time;

              // 如果过期时间为0，说明是永久订阅，应该显示为激活状态
              const displayStatus =
                status === 3 && expireTime === 0 ? 1 : status;

              const statusMap: Record<
                number,
                {
                  label: string;
                  variant: "default" | "secondary" | "destructive" | "outline";
                }
              > = {
                0: {
                  label: t("statusPending", "Pending"),
                  variant: "outline",
                },
                1: { label: t("statusActive", "Active"), variant: "default" },
                2: {
                  label: t("statusFinished", "Finished"),
                  variant: "secondary",
                },
                3: {
                  label: t("statusExpired", "Expired"),
                  variant: "destructive",
                },
                4: {
                  label: t("statusDeducted", "Deducted"),
                  variant: "secondary",
                },
                5: {
                  label: t("statusStopped", "Stopped"),
                  variant: "destructive",
                },
              };
              const statusInfo = statusMap[displayStatus] || {
                label: "Unknown",
                variant: "outline",
              };
              return (
                <Badge variant={statusInfo.variant}>{statusInfo.label}</Badge>
              );
            },
          },
          {
            accessorKey: "upload",
            header: t("upload", "Upload"),
            cell: ({ row }) => (
              <Display type="traffic" value={row.getValue("upload")} />
            ),
          },
          {
            accessorKey: "download",
            header: t("download", "Download"),
            cell: ({ row }) => (
              <Display type="traffic" value={row.getValue("download")} />
            ),
          },
          {
            accessorKey: "traffic",
            header: t("totalTraffic", "Total Traffic"),
            cell: ({ row }) => (
              <Display
                type="traffic"
                unlimited
                value={row.getValue("traffic")}
              />
            ),
          },
          {
            id: "remaining_traffic",
            header: t("remainingTraffic", "Remaining Traffic"),
            cell: ({ row }) => {
              const upload = row.original.upload || 0;
              const download = row.original.download || 0;
              const totalTraffic = row.original.traffic || 0;
              const remainingTraffic =
                totalTraffic > 0 ? totalTraffic - upload - download : 0;
              return (
                <Display type="traffic" unlimited value={remainingTraffic} />
              );
            },
          },
          {
            accessorKey: "speed_limit",
            header: t("speedLimit", "Speed Limit"),
            cell: ({ row }) => {
              const userSpeed = row.original.speed_limit ?? 0;
              const effectiveSpeed = row.original.effective_speed ?? 0;
              const planSpeed = row.original.subscribe?.speed_limit ?? 0;
              const speed = effectiveSpeed || userSpeed || planSpeed;
              const source =
                userSpeed > 0
                  ? t("userOverride", "User Override")
                  : t("subscriptionDefault", "Subscription Default");

              return (
                <div className="flex flex-col gap-1">
                  <div className="flex items-center gap-2">
                    <Display type="trafficSpeed" value={speed} />
                    {row.original.is_throttled && (
                      <Badge variant="destructive">
                        {t("throttled", "Throttled")}
                      </Badge>
                    )}
                  </div>
                  <span className="text-muted-foreground text-xs">
                    {source}
                  </span>
                </div>
              );
            },
          },
          {
            accessorKey: "device_limit",
            header: t("deviceLimit", "Device Limit"),
            cell: ({ row }) => {
              const limit =
                row.original.device_limit ||
                row.original?.subscribe?.device_limit;
              return <Display type="number" unlimited value={limit} />;
            },
          },
          {
            accessorKey: "reset_time",
            header: t("resetTime", "Reset Time"),
            cell: ({ row }) => (
              <Display
                type="number"
                unlimited
                value={row.getValue("reset_time")}
              />
            ),
          },
          {
            accessorKey: "expire_time",
            header: t("expireTime", "Expire Time"),
            cell: ({ row }) => {
              const expireTime = row.getValue("expire_time") as number;
              return expireTime && expireTime !== 0
                ? formatDate(expireTime)
                : t("permanent", "Permanent");
            },
          },
          {
            accessorKey: "node_group_name",
            header: t("nodeGroup", "Node Group"),
            cell: ({ row }) => row.original.node_group_name || "-",
          },
          {
            accessorKey: "created_at",
            header: t("createdAt", "Created At"),
            cell: ({ row }) => formatDate(row.getValue("created_at")),
          },
        ]}
        header={{
          title: isSharedView
            ? t("sharedSubscriptionList", "Shared Subscription List")
            : t("subscriptionList", "Subscription List"),
          toolbar: isSharedView ? undefined : (
            <SubscriptionForm
              key="create"
              loading={loading}
              onSubmit={async (values) => {
                setLoading(true);
                await createUserSubscribe({
                  user_id: Number(userId),
                  ...toUserSubscribePayload(values),
                });
                toast.success(t("createSuccess", "Created successfully"));
                ref.current?.refresh();
                setLoading(false);
                return true;
              }}
              title={t("createSubscription", "Create Subscription")}
              trigger={t("add", "Add")}
            />
          ),
        }}
        request={request}
      />
    </div>
  );
}

function RowReadOnlyActions({
  userId,
  row,
  token,
  refresh,
}: {
  userId: number;
  row: API.UserSubscribe;
  token: string;
  refresh?: () => void;
}) {
  const { t } = useTranslation("user");
  const triggerRef = useRef<HTMLButtonElement>(null);
  const deleteRef = useRef<HTMLButtonElement>(null);
  const { getUserSubscribe: getUserSubscribeUrls } = useGlobalStore();

  return (
    <div className="inline-flex">
      <DropdownMenu modal={false}>
        <DropdownMenuTrigger asChild>
          <Button variant="outline">{t("more", "More")}</Button>
        </DropdownMenuTrigger>
        <DropdownMenuContent align="end">
          <DropdownMenuItem
            onSelect={async (e) => {
              e.preventDefault();
              await navigator.clipboard.writeText(
                getUserSubscribeUrls(row.short, token)[0] || ""
              );
              toast.success(t("copySuccess", "Copied successfully"));
            }}
          >
            {t("copySubscription", "Copy Subscription")}
          </DropdownMenuItem>
          <DropdownMenuItem asChild>
            <Link
              search={{ user_id: userId, user_subscribe_id: row.id }}
              to="/dashboard/log/subscribe"
            >
              {t("subscriptionLogs", "Subscription Logs")}
            </Link>
          </DropdownMenuItem>
          <DropdownMenuItem asChild>
            <Link
              search={{ user_id: userId, user_subscribe_id: row.id }}
              to="/dashboard/log/subscribe-traffic"
            >
              {t("trafficStats", "Traffic Stats")}
            </Link>
          </DropdownMenuItem>
          <DropdownMenuItem asChild>
            <Link
              search={{ user_id: userId, subscribe_id: row.id }}
              to="/dashboard/log/traffic-details"
            >
              {t("trafficDetails", "Traffic Details")}
            </Link>
          </DropdownMenuItem>
          <DropdownMenuItem
            onSelect={(e) => {
              e.preventDefault();
              triggerRef.current?.click();
            }}
          >
            {t("onlineDevices", "Online Devices")}
          </DropdownMenuItem>
          <DropdownMenuItem
            className="text-destructive"
            onSelect={(e) => {
              e.preventDefault();
              deleteRef.current?.click();
            }}
          >
            {t("delete", "Delete")}
          </DropdownMenuItem>
        </DropdownMenuContent>
      </DropdownMenu>

      <ConfirmButton
        cancelText={t("cancel", "Cancel")}
        confirmText={t("confirm", "Confirm")}
        description={t(
          "deleteSubscriptionDescription",
          "This action cannot be undone."
        )}
        onConfirm={async () => {
          await deleteUserSubscribe({ user_subscribe_id: row.id });
          toast.success(t("deleteSuccess", "Deleted successfully"));
          refresh?.();
        }}
        title={t("confirmDelete", "Confirm Delete")}
        trigger={<Button className="hidden" ref={deleteRef} />}
      />

      <SubscriptionDetail
        subscriptionId={row.id}
        trigger={<Button className="hidden" ref={triggerRef} />}
        userId={userId}
      />
    </div>
  );
}

function RowMoreActions({
  userId,
  row,
  token,
  refresh,
}: {
  userId: number;
  row: API.UserSubscribe;
  token: string;
  refresh: () => void;
}) {
  const triggerRef = useRef<HTMLButtonElement>(null);
  const resetTokenRef = useRef<HTMLButtonElement>(null);
  const toggleStatusRef = useRef<HTMLButtonElement>(null);
  const deleteRef = useRef<HTMLButtonElement>(null);
  const { t } = useTranslation("user");
  const { getUserSubscribe: getUserSubscribeUrls } = useGlobalStore();

  return (
    <div className="inline-flex">
      <DropdownMenu modal={false}>
        <DropdownMenuTrigger asChild>
          <Button variant="outline">{t("more", "More")}</Button>
        </DropdownMenuTrigger>
        <DropdownMenuContent align="end">
          <DropdownMenuItem
            onSelect={async (e) => {
              e.preventDefault();
              await navigator.clipboard.writeText(
                getUserSubscribeUrls(row.short, token)[0] || ""
              );
              toast.success(t("copySuccess", "Copied successfully"));
            }}
          >
            {t("copySubscription", "Copy Subscription")}
          </DropdownMenuItem>
          <DropdownMenuItem
            onSelect={(e) => {
              e.preventDefault();
              resetTokenRef.current?.click();
            }}
          >
            {t("resetToken", "Reset Subscription Address")}
          </DropdownMenuItem>
          <DropdownMenuItem
            onSelect={(e) => {
              e.preventDefault();
              toggleStatusRef.current?.click();
            }}
          >
            {row.status === 5
              ? t("resumeSubscribe", "Resume Subscription")
              : t("stopSubscribe", "Stop Subscription")}
          </DropdownMenuItem>
          <DropdownMenuItem
            className="text-destructive"
            onSelect={(e) => {
              e.preventDefault();
              deleteRef.current?.click();
            }}
          >
            {t("delete", "Delete")}
          </DropdownMenuItem>
          <DropdownMenuItem asChild>
            <Link
              search={{ user_id: userId, user_subscribe_id: row.id }}
              to="/dashboard/log/subscribe"
            >
              {t("subscriptionLogs", "Subscription Logs")}
            </Link>
          </DropdownMenuItem>
          <DropdownMenuItem asChild>
            <Link
              search={{ user_id: userId, user_subscribe_id: row.id }}
              to="/dashboard/log/reset-subscribe"
            >
              {t("resetLogs", "Reset Logs")}
            </Link>
          </DropdownMenuItem>
          <DropdownMenuItem asChild>
            <Link
              search={{ user_id: userId, user_subscribe_id: row.id }}
              to="/dashboard/log/subscribe-traffic"
            >
              {t("trafficStats", "Traffic Stats")}
            </Link>
          </DropdownMenuItem>
          <DropdownMenuItem asChild>
            <Link
              search={{ user_id: userId, subscribe_id: row.id }}
              to="/dashboard/log/traffic-details"
            >
              {t("trafficDetails", "Traffic Details")}
            </Link>
          </DropdownMenuItem>
          <DropdownMenuItem
            onSelect={(e) => {
              e.preventDefault();
              triggerRef.current?.click();
            }}
          >
            {t("onlineDevices", "Online Devices")}
          </DropdownMenuItem>
        </DropdownMenuContent>
      </DropdownMenu>

      {/* Hidden triggers for confirm dialogs */}
      <ConfirmButton
        cancelText={t("cancel", "Cancel")}
        confirmText={t("confirm", "Confirm")}
        description={t(
          "resetTokenDescription",
          "This will reset the subscription address and regenerate a new token."
        )}
        onConfirm={async () => {
          await resetUserSubscribeToken({
            user_subscribe_id: row.id,
          });
          toast.success(
            t("resetTokenSuccess", "Subscription address reset successfully")
          );
          refresh();
        }}
        title={t("confirmResetToken", "Confirm Reset Subscription Address")}
        trigger={<Button className="hidden" ref={resetTokenRef} />}
      />

      <ConfirmButton
        cancelText={t("cancel", "Cancel")}
        confirmText={t("confirm", "Confirm")}
        description={
          row.status === 5
            ? t(
                "resumeSubscribeDescription",
                "This will resume the subscription and allow the user to use it."
              )
            : t(
                "stopSubscribeDescription",
                "This will stop the subscription temporarily. User will not be able to use it."
              )
        }
        onConfirm={async () => {
          await toggleUserSubscribeStatus({
            user_subscribe_id: row.id,
          });
          toast.success(
            row.status === 5
              ? t("resumeSubscribeSuccess", "Subscription resumed successfully")
              : t("stopSubscribeSuccess", "Subscription stopped successfully")
          );
          refresh();
        }}
        title={
          row.status === 5
            ? t("confirmResumeSubscribe", "Confirm Resume Subscription")
            : t("confirmStopSubscribe", "Confirm Stop Subscription")
        }
        trigger={<Button className="hidden" ref={toggleStatusRef} />}
      />

      <ConfirmButton
        cancelText={t("cancel", "Cancel")}
        confirmText={t("confirm", "Confirm")}
        description={t(
          "deleteSubscriptionDescription",
          "This action cannot be undone."
        )}
        onConfirm={async () => {
          await deleteUserSubscribe({ user_subscribe_id: row.id });
          toast.success(t("deleteSuccess", "Deleted successfully"));
          refresh();
        }}
        title={t("confirmDelete", "Confirm Delete")}
        trigger={<Button className="hidden" ref={deleteRef} />}
      />

      <SubscriptionDetail
        subscriptionId={row.id}
        trigger={<Button className="hidden" ref={triggerRef} />}
        userId={userId}
      />
    </div>
  );
}
