import { isDesktop } from '@lobechat/const';
import { HETEROGENEOUS_AGENT_CLIENT_CONFIGS } from '@lobechat/heterogeneous-agents/client';
import { Icon } from '@lobehub/ui';
import { GroupBotSquareIcon } from '@lobehub/ui/icons';
import { App } from 'antd';
import type { ItemType } from 'antd/es/menu/interface';
import { BotIcon, FileTextIcon, FolderCogIcon, FolderPlus, MonitorSmartphone } from 'lucide-react';
import { useCallback, useState } from 'react';
import { useTranslation } from 'react-i18next';
import useSWRMutation from 'swr/mutation';

import { useGroupTemplates } from '@/components/ChatGroupWizard/templates';
import { DEFAULT_CHAT_GROUP_CHAT_CONFIG } from '@/const/settings';
import { useWorkspaceAwareNavigate } from '@/features/Workspace/useWorkspaceAwareNavigate';
import { useCreateHeteroAgent } from '@/hooks/useCreateHeteroAgent';
import { usePermission } from '@/hooks/usePermission';
import { useOptionalAgentModal } from '@/routes/(main)/home/_layout/Body/Agent/ModalProvider';
import type { CreateAgentParams } from '@/services/agent';
import type { GroupMemberConfig } from '@/services/chatGroup';
import { chatGroupService } from '@/services/chatGroup';
import { useAgentStore } from '@/store/agent';
import { useAgentGroupStore } from '@/store/agentGroup';
import { useHomeStore } from '@/store/home';
import { usePageStore } from '@/store/page';
import { useUserStore } from '@/store/user';
import { labPreferSelectors } from '@/store/user/selectors';

interface CreateAgentOptions {
  groupId?: string;
  isPinned?: boolean;
  onSuccess?: () => void;
}

/**
 * Hook for generating menu items for top-level create actions
 * Used in Body/Agent/Actions.tsx and Header/AddButton.tsx
 */
export const useCreateMenuItems = () => {
  const { t } = useTranslation('chat');
  const { t: tFile } = useTranslation('file');
  const { message } = App.useApp();
  const navigate = useWorkspaceAwareNavigate();
  const groupTemplates = useGroupTemplates();
  const { allowed: canCreate } = usePermission('create_content');

  const [storeCreateAgent] = useAgentStore((s) => [s.createAgent]);
  const [addGroup, refreshAgentList, switchToGroup] = useHomeStore((s) => [
    s.addGroup,
    s.refreshAgentList,
    s.switchToGroup,
  ]);
  const [createGroup, loadGroups] = useAgentGroupStore((s) => [s.createGroup, s.loadGroups]);
  const createNewPage = usePageStore((s) => s.createNewPage);
  const createHeterogeneousAgent = useCreateHeteroAgent();

  const [isCreatingGroup, setIsCreatingGroup] = useState(false);
  const [isCreatingSessionGroup, setIsCreatingSessionGroup] = useState(false);

  // SWR-based agent creation with auto navigation to profile
  const { trigger: mutateAgent, isMutating: isMutatingAgent } = useSWRMutation(
    'agent.createAgent',
    async (_key: string, { arg }: { arg?: CreateAgentParams }) => {
      const result = await storeCreateAgent(arg ?? {});
      return result;
    },
    {
      onSuccess: async (result) => {
        navigate(`/agent/${result.agentId}/profile`);
        await refreshAgentList();
      },
    },
  );

  // SWR-based group creation with auto navigation to profile
  const { trigger: mutateGroup, isMutating: isMutatingGroup } = useSWRMutation(
    'group.createGroup',
    async (_key: string, { arg }: { arg?: CreateAgentOptions & { title?: string } }) => {
      const groupId = await createGroup(
        {
          config: DEFAULT_CHAT_GROUP_CHAT_CONFIG,
          groupId: arg?.groupId,
          title: arg?.title || t('defaultGroupChat'),
        },
        [],
        true, // silent mode - don't switch session, we'll navigate instead
      );
      return groupId;
    },
    {
      onSuccess: async (groupId) => {
        navigate(`/group/${groupId}/profile`);
        await refreshAgentList();
        await loadGroups();
      },
    },
  );

  /**
   * Create agent action (optionally with a prompt as systemRole)
   */
  const createAgent = useCallback(
    async (options?: CreateAgentOptions & { prompt?: string }) => {
      if (!canCreate) return;

      const config = options?.prompt ? { systemRole: options.prompt } : undefined;
      await mutateAgent({ config, groupId: options?.groupId });
      options?.onSuccess?.();
    },
    [canCreate, mutateAgent],
  );

  /**
   * Create group from template
   * Uses backend batch creation for better performance and consistency
   */
  const createGroupFromTemplate = useCallback(
    async (templateId: string, selectedMemberTitles?: string[]) => {
      if (!canCreate) return false;

      setIsCreatingGroup(true);
      try {
        const template = groupTemplates.find((t) => t.id === templateId);
        if (!template) {
          throw new Error(`Template ${templateId} not found`);
        }

        const membersToCreate =
          typeof selectedMemberTitles === 'undefined'
            ? template.members
            : template.members.filter((m) => selectedMemberTitles.includes(m.title));

        // Prepare member configs for batch creation
        const memberConfigs: GroupMemberConfig[] = membersToCreate.map((member) => ({
          avatar: member.avatar,
          backgroundColor: member.backgroundColor,
          plugins: member.plugins,
          systemRole: member.systemRole,
          title: member.title,
        }));

        // Use batch creation endpoint - creates all agents and group in one request
        const { groupId } = await chatGroupService.createGroupWithMembers(
          {
            title: template.title,
          },
          memberConfigs,
        );

        // Switch to the new group
        switchToGroup(groupId);

        // Refresh data after creation
        await refreshAgentList();
        await loadGroups();

        return true;
      } catch (error) {
        console.error('Failed to create group from template:', error);
        message.error({ content: t('sessionGroup.createGroupFailed') });
        return false;
      } finally {
        setIsCreatingGroup(false);
      }
    },
    [canCreate, groupTemplates, refreshAgentList, loadGroups, switchToGroup, message, t],
  );

  /**
   * Create group with members
   */
  const createGroupWithMembers = useCallback(
    async (selectedAgents: string[], groupTitle?: string) => {
      if (!canCreate) return false;

      setIsCreatingGroup(true);
      try {
        const title = groupTitle || t('defaultGroupChat');

        await createGroup(
          {
            config: DEFAULT_CHAT_GROUP_CHAT_CONFIG,
            title,
          },
          selectedAgents,
        );

        return true;
      } catch (error) {
        console.error('Failed to create group:', error);
        message.error({ content: t('sessionGroup.createGroupFailed') });
        return false;
      } finally {
        setIsCreatingGroup(false);
      }
    },
    [canCreate, createGroup, message, t],
  );

  /**
   * Create empty group and navigate to profile
   */
  const createEmptyGroup = useCallback(
    async (options?: CreateAgentOptions & { title?: string }) => {
      if (!canCreate) return;

      await mutateGroup(options);
    },
    [canCreate, mutateGroup],
  );

  const agentModal = useOptionalAgentModal();
  const openCreateModal = agentModal?.openCreateModal;
  const enablePlatformAgent = useUserStore(labPreferSelectors.enablePlatformAgent);

  /**
   * Create agent menu item
   */
  const createAgentMenuItem = useCallback(
    (options?: CreateAgentOptions): ItemType => ({
      icon: <Icon icon={BotIcon} />,
      disabled: !canCreate,
      key: 'newAgent',
      label: t('newAgent'),
      onClick: async (info) => {
        info.domEvent?.stopPropagation();
        if (!canCreate) return;

        if (openCreateModal) {
          openCreateModal('agent', options?.groupId ? { groupId: options.groupId } : undefined);
        } else {
          await createAgent(options);
        }
      },
    }),
    [canCreate, t, createAgent, openCreateModal],
  );

  /**
   * Create heterogeneous agent menu items (Desktop only)
   */
  const createHeterogeneousAgentMenuItems = useCallback(
    (options?: CreateAgentOptions): ItemType[] => {
      if (!isDesktop) return [];

      return HETEROGENEOUS_AGENT_CLIENT_CONFIGS.map((definition) => {
        const AgentIcon = definition.icon;

        return {
          icon: <AgentIcon size={'1em'} />,
          disabled: !canCreate,
          key: definition.menuKey,
          label: t(definition.menuLabelKey),
          onClick: async (info) => {
            info.domEvent?.stopPropagation();
            if (!canCreate) return;

            await createHeterogeneousAgent(definition, options);
          },
        };
      });
    },
    [canCreate, t, createHeterogeneousAgent],
  );

  /**
   * Create platform agent menu item (openclaw / hermes — remote device agents)
   * Opens the 3-step creation modal
   */
  const createPlatformAgentMenuItem = useCallback(
    (options?: CreateAgentOptions): ItemType => {
      if (!enablePlatformAgent) return null;
      return {
        icon: <Icon icon={MonitorSmartphone} />,
        key: 'newPlatformAgent',
        label: t('newPlatformAgent'),
        onClick: (info) => {
          info.domEvent?.stopPropagation();
          agentModal?.openCreatePlatformAgentModal(
            options?.groupId ? { groupId: options.groupId } : undefined,
          );
        },
      };
    },
    [t, agentModal, enablePlatformAgent],
  );

  /**
   * Create group chat menu item
   * Creates an empty group and navigates to its profile page
   */
  const createGroupChatMenuItem = useCallback(
    (options?: CreateAgentOptions): ItemType => ({
      icon: <Icon icon={GroupBotSquareIcon} />,
      disabled: !canCreate,
      key: 'newGroupChat',
      label: t('newGroupChat'),
      onClick: async (info) => {
        info.domEvent?.stopPropagation();
        if (!canCreate) return;

        if (openCreateModal) {
          openCreateModal('group', options?.groupId ? { groupId: options.groupId } : undefined);
        } else {
          await createEmptyGroup(options);
        }
      },
    }),
    [canCreate, t, createEmptyGroup, openCreateModal],
  );

  /**
   * Add session group menu item
   */
  const createSessionGroupMenuItem = useCallback(
    (): ItemType => ({
      icon: <Icon icon={FolderPlus} />,
      disabled: !canCreate,
      key: 'addSessionGroup',
      label: t('sessionGroup.createGroup'),
      onClick: async (info) => {
        info.domEvent?.stopPropagation();
        if (!canCreate) return;

        setIsCreatingSessionGroup(true);
        await addGroup(t('sessionGroup.newGroup'));
        setIsCreatingSessionGroup(false);
      },
    }),
    [canCreate, t, addGroup],
  );

  /**
   * Config menu item
   */
  const configMenuItem = useCallback(
    (onOpenConfig: () => void): ItemType => ({
      icon: <Icon icon={FolderCogIcon} />,
      key: 'config',
      label: t('sessionGroup.config'),
      onClick: (info) => {
        info.domEvent?.stopPropagation();
        onOpenConfig();
      },
    }),
    [t],
  );

  /**
   * Create page action
   */
  const createPage = useCallback(async () => {
    if (!canCreate) return;

    const untitledTitle = tFile('pageList.untitled');
    try {
      const newPageId = await createNewPage(untitledTitle);
      navigate(`/page/${newPageId}`);
    } catch (error) {
      console.error('Failed to create page:', error);
      message.error('Failed to create page');
    }
  }, [canCreate, createNewPage, tFile, navigate, message]);

  /**
   * Create page menu item
   */
  const createPageMenuItem = useCallback(
    (): ItemType => ({
      icon: <Icon icon={FileTextIcon} />,
      disabled: !canCreate,
      key: 'newPage',
      label: t('newPage'),
      onClick: async (info) => {
        info.domEvent?.stopPropagation();
        if (!canCreate) return;

        await createPage();
      },
    }),
    [canCreate, t, createPage],
  );

  return {
    configMenuItem,
    createAgent,
    createAgentMenuItem,
    createEmptyGroup,
    createGroupChatMenuItem,
    createGroupFromTemplate,
    createHeterogeneousAgent,
    createHeterogeneousAgentMenuItems,
    createGroupWithMembers,
    createPage,
    createPageMenuItem,
    createPlatformAgentMenuItem,
    createSessionGroupMenuItem,
    openCreateModal,

    // Loading states
    isCreatingGroup,
    isCreatingSessionGroup,
    isLoading: isMutatingAgent || isMutatingGroup || isCreatingGroup || isCreatingSessionGroup,
    isMutatingAgent,
  };
};
