import { useQuery } from "@tanstack/react-query";
import { Link, useSearch } from "@tanstack/react-router";
import { Badge } from "@workspace/ui/components/badge";
import { Button } from "@workspace/ui/components/button";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@workspace/ui/components/dialog";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@workspace/ui/components/dropdown-menu";
import { Input } from "@workspace/ui/components/input";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@workspace/ui/components/popover";
import { ScrollArea } from "@workspace/ui/components/scroll-area";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@workspace/ui/components/select";
import {
  Sheet,
  SheetContent,
  SheetHeader,
  SheetTitle,
  SheetTrigger,
} from "@workspace/ui/components/sheet";
import { Switch } from "@workspace/ui/components/switch";
import {
  Tabs,
  TabsContent,
  TabsList,
  TabsTrigger,
} from "@workspace/ui/components/tabs";
import { Combobox } from "@workspace/ui/composed/combobox";
// import { ConfirmButton } from "@workspace/ui/composed/confirm-button";
import {
  ProTable,
  type ProTableActions,
} from "@workspace/ui/composed/pro-table/pro-table";
import {
  // getUserGroupList,
  previewUserNodes,
} from "@workspace/ui/services/admin/group";
import {
  createUser,
  // deleteUser,
  getUserDetail,
  getUserList,
  updateUserBasicInfo,
} from "@workspace/ui/services/admin/user";
import { parseDeviceType } from "@workspace/ui/utils/device";
import { FilePenLine } from "lucide-react";
import { useCallback, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";
import { Display } from "@/components/display";
import { useSubscribe } from "@/stores/subscribe";
import { formatDate } from "@/utils/common";
import FamilyManagement from "./family";
import { RemarkForm } from "./remark-form";
import { buildUserBasicInfoPayload } from "./user-basic-info-payload";
import { UserDetail } from "./user-detail";
import UserForm from "./user-form";
import { UserInviteStatsSheet } from "./user-invite-stats-sheet";
import { AuthMethodsForm } from "./user-profile/auth-methods-form";
import { BasicInfoForm } from "./user-profile/basic-info-form";
import { NotifySettingsForm } from "./user-profile/notify-settings-form";
import UserSubscription from "./user-subscription";

// import EditUserGroupDialog from "./edit-user-group-dialog";

type UserDeviceWithDeviceNo = API.UserDevice & {
  device_no?: string;
};

export default function User() {
  const { t } = useTranslation("user");
  const [loading, setLoading] = useState(false);
  const ref = useRef<ProTableActions>(null);
  const sp = useSearch({ strict: false }) as Record<string, string | undefined>;

  const { subscribes } = useSubscribe();

  const searchRef = useRef({
    type: sp.user_id ? "user_id" : "email",
    value: sp.search || sp.user_id || "",
  });

  const handleSearch = useCallback((type: string, value: string) => {
    searchRef.current = { type, value };
    ref.current?.refresh();
  }, []);

  const buildSearchParams = () => {
    const { type, value } = searchRef.current;
    if (!value) return {};
    switch (type) {
      case "user_id":
        return { user_id: Number(value) };
      case "device":
        return { search: value };
      case "subscribe_id":
        return { subscribe_id: Number(value) };
      default:
        return { search: value };
    }
  };

  // const { data: userGroupsData } = useQuery({
  //   queryKey: ["userGroups"],
  //   queryFn: async () => {
  //     const { data } = await getUserGroupList({ page: 1, size: 1000 });
  //     return data.data?.list || [];
  //   },
  // });

  const initialFilters = {
    search: sp.search || undefined,
    user_id: sp.user_id || undefined,
    subscribe_id: sp.subscribe_id || undefined,
    user_subscribe_id: sp.user_subscribe_id || undefined,
    short_code: sp.short_code || undefined,
    // user_group_id: sp.user_group_id || undefined,
  };

  return (
    <ProTable<API.User, API.GetUserListParams>
      action={ref}
      actions={{
        render: (row) => [
          <ProfileSheet
            key="profile"
            onUpdated={() => ref.current?.refresh()}
            userId={row.id}
          />,
          <SubscriptionSheet key="subscription" userId={row.id} />,
          <DeviceGroupSheet
            key="device-group"
            onChanged={() => ref.current?.refresh()}
            userId={row.id}
          />,
          <PreviewNodesDialog key="preview-nodes" userId={row.id} />,
          /* <ConfirmButton
            cancelText={t("cancel", "Cancel")}
            confirmText={t("confirm", "Confirm")}
            description={t(
              "deleteDescription",
              "This action cannot be undone."
            )}
            key="edit"
            onConfirm={async () => {
              await deleteUser({ id: row.id });
              toast.success(t("deleteSuccess", "Deleted successfully"));
              ref.current?.refresh();
            }}
            title={t("confirmDelete", "Confirm Delete")}
            trigger={
              <Button variant="destructive">{t("delete", "Delete")}</Button>
            }
          />,*/
          <DropdownMenu key="more" modal={false}>
            <DropdownMenuTrigger asChild>
              <Button variant="outline">{t("more", "More")}</Button>
            </DropdownMenuTrigger>
            <DropdownMenuContent align="end">
              <InviteStatsMenuItem userId={row.id} />
              <DropdownMenuItem asChild>
                <Link search={{ user_id: row.id }} to="/dashboard/order">
                  {t("orderList", "Order List")}
                </Link>
              </DropdownMenuItem>
              <DropdownMenuItem asChild>
                <Link search={{ user_id: row.id }} to="/dashboard/log/login">
                  {t("loginLogs", "Login Logs")}
                </Link>
              </DropdownMenuItem>
              <DropdownMenuItem asChild>
                <Link search={{ user_id: row.id }} to="/dashboard/log/balance">
                  {t("balanceLogs", "Balance Logs")}
                </Link>
              </DropdownMenuItem>
              <DropdownMenuItem asChild>
                <Link
                  search={{ user_id: row.id }}
                  to="/dashboard/log/commission"
                >
                  {t("commissionLogs", "Commission Logs")}
                </Link>
              </DropdownMenuItem>
              <DropdownMenuItem asChild>
                <Link search={{ user_id: row.id }} to="/dashboard/log/gift">
                  {t("giftLogs", "Gift Logs")}
                </Link>
              </DropdownMenuItem>
            </DropdownMenuContent>
          </DropdownMenu>,
        ],
      }}
      columns={[
        {
          id: "enable",
          accessorKey: "enable",
          header: t("enable", "Enable"),
          cell: ({ row }) => (
            <Switch
              defaultChecked={row.getValue("enable")}
              onCheckedChange={async (checked) => {
                const {
                  auth_methods: _auth_methods,
                  user_devices: _user_devices,
                  enable_balance_notify: _enable_balance_notify,
                  enable_login_notify: _enable_login_notify,
                  enable_subscribe_notify: _enable_subscribe_notify,
                  enable_trade_notify: _enable_trade_notify,
                  updated_at: _updated_at,
                  created_at: _created_at,
                  id,
                  ...rest
                } = row.original;
                await updateUserBasicInfo({
                  user_id: id,
                  ...rest,
                  enable: checked,
                } as unknown as API.UpdateUserBasiceInfoRequest);
                toast.success(t("updateSuccess", "Updated successfully"));
                ref.current?.refresh();
              }}
            />
          ),
        },
        {
          id: "id",
          accessorKey: "id",
          header: "ID",
        },
        /*{
          id: "deleted_at",
          accessorKey: "deleted_at",
          header: t("isDeleted", "Deleted"),
          cell: ({ row }) => {
            const deletedAt = row.getValue("deleted_at") as number | undefined;
            return deletedAt ? (
              <Badge variant="destructive">{t("deleted", "Deleted")}</Badge>
            ) : (
              <Badge variant="outline">{t("normal", "Normal")}</Badge>
            );
          },
        },*/
        {
          id: "auth_methods",
          accessorKey: "auth_methods",
          header: "设备码/邮箱",
          cell: ({ row }) => {
            const method = row.original.auth_methods?.[0];
            const identifier = method?.auth_identifier || "";
            const isDevice = method?.auth_type === "device";
            const firstDevice = row.original.user_devices?.[0] as
              | UserDeviceWithDeviceNo
              | undefined;
            const deviceNo = firstDevice?.device_no;
            const deviceType = parseDeviceType(firstDevice?.user_agent || "");
            const display = isDevice ? deviceNo || identifier : identifier;
            return (
              <div className="flex items-center">
                {/* <Badge
                  className="mr-1 uppercase"
                  title={method?.verified ? t("verified", "Verified") : ""}
                >
                  {method?.auth_type}
                </Badge>*/}
                {deviceType && (
                  <Badge className="mr-1" variant="secondary">
                    {deviceType}
                  </Badge>
                )}
                <span title={isDevice ? display : undefined}>{display}</span>
                <Popover>
                  <PopoverTrigger>
                    <div className={"flex items-center"}>
                      {row.original?.remark ? `（${row.original.remark}）` : ""}
                      <FilePenLine className={"ml-2 text-primary"} size={14} />
                    </div>
                  </PopoverTrigger>
                  <PopoverContent className={"w-64"}>
                    <RemarkForm
                      initialRemark={row.original.remark}
                      onSave={async (remark) => {
                        const { data } = await getUserDetail({
                          id: row.original.id,
                        });
                        const user = data.data;

                        if (!user) {
                          throw new Error("User detail not found");
                        }

                        await updateUserBasicInfo(
                          buildUserBasicInfoPayload(user, remark)
                        );
                        toast.success(t("updateSuccess"));
                        ref.current?.refresh();
                      }}
                    />
                  </PopoverContent>
                </Popover>
              </div>
            );
          },
        },
        /* {
          id: "balance",
          accessorKey: "balance",
          header: t("balance", "Balance"),
          cell: ({ row }) => (
            <Display type="currency" value={row.getValue("balance")} />
          ),
        },
        {
          id: "gift_amount",
          accessorKey: "gift_amount",
          header: t("giftAmount", "Gift Amount"),
          cell: ({ row }) => (
            <Display type="currency" value={row.getValue("gift_amount")} />
          ),
        },*/
        {
          id: "commission",
          accessorKey: "commission",
          header: t("commission", "Commission"),
          cell: ({ row }) => (
            <Display type="currency" value={row.getValue("commission")} />
          ),
        },
        {
          id: "refer_code",
          accessorKey: "refer_code",
          header: t("inviteCode", "Invite Code"),
          cell: ({ row }) => row.getValue("refer_code") || "--",
        },
        {
          id: "referer_id",
          accessorKey: "referer_id",
          header: t("referer", "Referer"),
          cell: ({ row }) => <UserDetail id={row.original.referer_id} />,
        },
        {
          id: "created_at",
          accessorKey: "created_at",
          header: t("createdAt", "Created At"),
          cell: ({ row }) => formatDate(row.getValue("created_at")),
        },
      ]}
      header={{
        title: (
          <UserSearchBar
            initialType={searchRef.current.type}
            initialValue={searchRef.current.value}
            onSearch={handleSearch}
            subscribes={subscribes}
          />
        ),
        toolbar: (
          <UserForm<API.CreateUserRequest>
            key="create"
            loading={loading}
            onSubmit={async (values) => {
              setLoading(true);
              try {
                await createUser(values);
                toast.success(t("createSuccess", "Created successfully"));
                ref.current?.refresh();
                setLoading(false);

                return true;
              } catch {
                setLoading(false);

                return false;
              }
            }}
            title={t("createUser", "Create User")}
            trigger={t("create", "Create")}
          />
        ),
      }}
      initialFilters={initialFilters}
      key={initialFilters.user_id}
      request={async (pagination) => {
        const { data } = await getUserList({
          ...pagination,
          ...buildSearchParams(),
        });
        return {
          list: data.data?.list || [],
          total: data.data?.total || 0,
        };
      }}
    />
  );
}

function ProfileSheet({
  userId,
  onUpdated,
}: {
  userId: number;
  onUpdated?: () => void;
}) {
  const { t } = useTranslation("user");
  const [open, setOpen] = useState(false);
  const { data: user, refetch } = useQuery({
    enabled: open,
    queryKey: ["user", userId],
    queryFn: async () => {
      const { data } = await getUserDetail({ id: userId });
      return data.data as API.User;
    },
  });

  const refetchAll = async () => {
    await refetch();
    onUpdated?.();
    return Promise.resolve();
  };
  return (
    <Sheet onOpenChange={setOpen} open={open}>
      <SheetTrigger asChild>
        <Button variant="default">{t("edit", "Edit")}</Button>
      </SheetTrigger>
      <SheetContent
        className="w-[700px] max-w-full md:max-w-screen-lg"
        side="right"
      >
        <SheetHeader>
          <SheetTitle>
            {t("userProfile", "User Profile")} · ID: {userId}
          </SheetTitle>
        </SheetHeader>
        {user && (
          <ScrollArea className="h-[calc(100dvh-140px)] p-2">
            <Tabs defaultValue="basic">
              <TabsList className="mb-3">
                <TabsTrigger value="basic">
                  {t("basicInfoTitle", "Basic Info")}
                </TabsTrigger>
                <TabsTrigger value="notify">
                  {t("notifySettingsTitle", "Notify Settings")}
                </TabsTrigger>
                <TabsTrigger value="auth">
                  {t("authMethodsTitle", "Auth Methods")}
                </TabsTrigger>
              </TabsList>
              <TabsContent className="mt-0" value="basic">
                <BasicInfoForm refetch={refetchAll} user={user} />
              </TabsContent>
              <TabsContent className="mt-0" value="notify">
                <NotifySettingsForm refetch={refetchAll} user={user} />
              </TabsContent>
              <TabsContent className="mt-0" value="auth">
                <AuthMethodsForm refetch={refetchAll} user={user} />
              </TabsContent>
            </Tabs>
          </ScrollArea>
        )}
      </SheetContent>
    </Sheet>
  );
}

function SubscriptionSheet({ userId }: { userId: number }) {
  const { t } = useTranslation("user");
  const [open, setOpen] = useState(false);
  return (
    <Sheet onOpenChange={setOpen} open={open}>
      <SheetTrigger asChild>
        <Button variant="secondary">{t("subscription", "Subscription")}</Button>
      </SheetTrigger>
      <SheetContent className="w-[1000px] max-w-full md:max-w-7xl" side="right">
        <SheetHeader>
          <SheetTitle>
            {t("subscriptionList", "Subscription List")} · ID: {userId}
          </SheetTitle>
        </SheetHeader>
        <div className="mt-2 px-4">
          <UserSubscription userId={userId} />
        </div>
      </SheetContent>
    </Sheet>
  );
}

function InviteStatsMenuItem({ userId }: { userId: number }) {
  const { t } = useTranslation("user");
  const [open, setOpen] = useState(false);
  return (
    <>
      <DropdownMenuItem
        onSelect={(e) => {
          e.preventDefault();
          setOpen(true);
        }}
      >
        {t("inviteStats", "Invite Statistics")}
      </DropdownMenuItem>
      <UserInviteStatsSheet
        onOpenChange={setOpen}
        open={open}
        userId={userId}
      />
    </>
  );
}

function DeviceGroupSheet({
  userId,
  onChanged,
}: {
  userId: number;
  onChanged?: () => void;
}) {
  const { t } = useTranslation("user");
  const [open, setOpen] = useState(false);
  return (
    <Sheet onOpenChange={setOpen} open={open}>
      <SheetTrigger asChild>
        <Button variant="outline">{t("deviceGroup", "Device Group")}</Button>
      </SheetTrigger>
      <SheetContent className="w-[1000px] max-w-full md:max-w-7xl" side="right">
        <SheetHeader>
          <SheetTitle>
            {t("deviceGroup", "Device Group")} · ID: {userId}
          </SheetTitle>
        </SheetHeader>
        <div className="mt-2 px-4">
          <FamilyManagement initialUserId={userId} onChanged={onChanged} />
        </div>
      </SheetContent>
    </Sheet>
  );
}

function UserSearchBar({
  initialType,
  initialValue,
  onSearch,
  subscribes,
}: {
  initialType: string;
  initialValue: string;
  onSearch: (type: string, value: string) => void;
  subscribes?: API.SubscribeItem[];
}) {
  const { t } = useTranslation("user");
  const [searchType, setSearchType] = useState(initialType);
  const [searchValue, setSearchValue] = useState(initialValue);

  return (
    <div className="flex items-center gap-2">
      <Select
        onValueChange={(v) => {
          setSearchType(v);
          setSearchValue("");
        }}
        value={searchType}
      >
        <SelectTrigger className="w-48">
          <SelectValue />
        </SelectTrigger>
        <SelectContent>
          <SelectItem value="email">设备码/邮箱</SelectItem>
          <SelectItem value="user_id">{t("userId", "User ID")}</SelectItem>
          <SelectItem value="subscribe_id">
            {t("subscription", "Subscription")}
          </SelectItem>
        </SelectContent>
      </Select>
      {searchType === "subscribe_id" ? (
        <Combobox
          className="w-48"
          onChange={(value) => {
            setSearchValue(value);
            onSearch("subscribe_id", value);
          }}
          options={subscribes?.map((item) => ({
            label: item.name!,
            value: String(item.id!),
          }))}
          placeholder={t("subscription", "Subscription")}
          value={searchValue}
        />
      ) : (
        <>
          <Input
            className="w-48"
            onChange={(e) => setSearchValue(e.target.value)}
            onKeyDown={(e) =>
              e.key === "Enter" && onSearch(searchType, searchValue)
            }
            placeholder={t("searchInputPlaceholder", "Enter search term")}
            value={searchValue}
          />
          <Button
            onClick={() => onSearch(searchType, searchValue)}
            variant="default"
          >
            {t("search", "Search")}
          </Button>
          {searchValue && (
            <Button
              onClick={() => {
                setSearchValue("");
                onSearch(searchType, "");
              }}
              variant="outline"
            >
              {t("resetSearch", "Reset")}
            </Button>
          )}
        </>
      )}
    </div>
  );
}

function PreviewNodesDialog({ userId }: { userId: number }) {
  const { t } = useTranslation("user");
  const [open, setOpen] = useState(false);
  const { data: previewData, isLoading } = useQuery({
    enabled: open,
    queryKey: ["previewUserNodes", userId],
    queryFn: async () => {
      const { data } = await previewUserNodes({ user_id: userId });
      return data.data;
    },
  });

  return (
    <Dialog onOpenChange={setOpen} open={open}>
      <DialogTrigger asChild>
        <Button variant="outline">{t("previewNodes", "Preview Nodes")}</Button>
      </DialogTrigger>
      <DialogContent className="max-w-2xl">
        <DialogHeader>
          <DialogTitle>
            {t("previewNodes", "Preview Nodes")} · ID: {userId}
          </DialogTitle>
        </DialogHeader>
        {isLoading ? (
          <div className="py-8 text-center text-muted-foreground">
            {t("loading", "Loading...")}
          </div>
        ) : previewData ? (
          <div className="space-y-4">
            <div>
              <span className="font-medium text-muted-foreground text-sm">
                {t("availableNodes", "Available Nodes")}:
              </span>{" "}
              {previewData.node_groups?.reduce(
                (sum, group) => sum + (group.nodes?.length || 0),
                0
              ) || 0}
            </div>
            {previewData.node_groups && previewData.node_groups.length > 0 ? (
              <div className="max-h-[400px] space-y-4 overflow-y-auto">
                {previewData.node_groups.map((group) => (
                  <div key={group.id}>
                    <h4 className="mb-2 font-semibold text-sm">
                      {group.name ||
                        (group.id === -1
                          ? t("subscriptionNodes", "Subscription Nodes")
                          : group.id === 0
                            ? t("publicNodes", "Public Nodes")
                            : `${t("nodeGroup", "Node Group")} ${group.id}`)}
                    </h4>
                    {group.nodes && group.nodes.length > 0 ? (
                      <table className="w-full text-sm">
                        <thead>
                          <tr className="border-b">
                            <th className="p-2 text-left font-medium">ID</th>
                            <th className="p-2 text-left font-medium">
                              {t("name", "Name")}
                            </th>
                            <th className="p-2 text-left font-medium">
                              {t("address", "Address")}
                            </th>
                          </tr>
                        </thead>
                        <tbody>
                          {group.nodes.map((node) => (
                            <tr className="border-b" key={node.id}>
                              <td className="p-2">{node.id}</td>
                              <td className="p-2">{node.name}</td>
                              <td className="p-2">
                                {node.address}:{node.port}
                              </td>
                            </tr>
                          ))}
                        </tbody>
                      </table>
                    ) : null}
                  </div>
                ))}
              </div>
            ) : (
              <div className="py-4 text-center text-muted-foreground">
                {t("noNodesAvailable", "No nodes available")}
              </div>
            )}
          </div>
        ) : null}
      </DialogContent>
    </Dialog>
  );
}
