import { useEffect, useRef, useState, useMemo, useCallback } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import { Space, Modal, Tooltip, message, Alert, Empty, Upload, Input, InputRef } from 'antd';
import {
  NotSaveGroupId,
  isCtrlKey,
  ctrlKeyStr,
  FeatZipSubfix,
  ProjectGroupInfo,
  GetProjecPageListQuery,
} from '@easytwin/core';
import {
  SearchOutlined,
  DragOutlined,
  DownloadOutlined,
  DeleteSquareOutlined,
  CodepenOutlined,
  CopySquareOutlined,
  RecycleOutlined,
  PlusOutlined,
  ExclamationCircleOutlined,
} from '@easyv/react-icons';
import { useRecoilState } from 'recoil';
import classnames from 'classnames';
import { useKey } from 'react-use';
import { initData } from '@/server';
import { GroupMenu, ProButton } from '@/components';
import { _globalLoadingInfo } from '@/pages/module';
import { useProjectGroup, useProjectList, useProject } from './module';
import { NameEdit, ProjectCard } from './components';

export default function ProjectManage() {
  const location = useLocation();
  const navigate = useNavigate();

  useEffect(() => {
    initData();
    if ((location.state as any)?.isClear) {
      navigate('/');
      window.location.reload();
    }
  }, [location, navigate]);

  const [, setLoadingInfo] = useRecoilState(_globalLoadingInfo);
  const [searchParams, setSearchParams] = useState<{
    name: string;
  }>({
    name: '',
  });
  const searchInputRef = useRef<InputRef>(null);
  const [searchAutoFocus, setSearchAutoFocus] = useState<boolean>(false);
  const [handleId, setHhandleId] = useState<string>();
  const { pageQuery, projectPageList, getProjectPageList } = useProjectList();

  const {
    selectGroupKey,
    setSelectGroupKey,
    getProjectGroupListReq,
    createProjectGroupReq,
    updateProjectGroupReq,
    removeProjectGroupReq,
  } = useProjectGroup();

  const beforeDataSource = useMemo(() => {
    let all = {};
    let unnamed = {};
    if (!getProjectGroupListReq.data?.length) return [];

    getProjectGroupListReq.data?.forEach((item) => {
      if (item.id === NotSaveGroupId.NOT_GROUP_FOR_PROJECT) unnamed = item;
      if (item.id === NotSaveGroupId.ALL_GROUP_FOR_PROJECT) all = item;
    });

    return [all, unnamed] as ProjectGroupInfo[];
  }, [getProjectGroupListReq.data]);

  const [, unnamed] = beforeDataSource;
  const id =
    selectGroupKey === NotSaveGroupId.ALL_GROUP_FOR_PROJECT ||
    selectGroupKey === NotSaveGroupId.NOT_GROUP_FOR_PROJECT
      ? unnamed?.dataId
      : selectGroupKey;

  const handleRemoveGroup = (id: string) => {
    Modal.confirm({
      title: '确认删除',
      icon: <ExclamationCircleOutlined className="anticon" />,
      content: '确认删除该分组？',
      async onOk() {
        removeProjectGroupReq.mutate({ ids: [id] });
      },
    });
  };

  const changeGroupData = useMemo(
    () =>
      getProjectGroupListReq.data?.filter((i) => i.id !== NotSaveGroupId.ALL_GROUP_FOR_PROJECT) ||
      [],
    [getProjectGroupListReq.data],
  );

  const {
    updateProjectReq,
    removeProjectReq,
    isRecycle,
    setIsRecycle,
    getProjectRecycleListReq,
    recycleProjectReq,
    copyProject,
    exportProject,
    importProject,
  } = useProject();

  const handleGetPageList = useCallback(() => {
    if (id) {
      let query: GetProjecPageListQuery = {
        ...searchParams,
        ...pageQuery,
        deleted: isRecycle,
      };
      if (!(selectGroupKey === NotSaveGroupId.ALL_GROUP_FOR_PROJECT || isRecycle)) {
        query = { ...query, groupId: id };
      }
      getProjectPageList(query);
    }
  }, [id, pageQuery, searchParams, getProjectPageList, isRecycle]);

  useEffect(() => {
    handleGetPageList();
  }, [handleGetPageList]);

  const handleExportProject = async (id: string) => {
    try {
      setLoadingInfo({
        loading: true,
        tip: '正在导出文件...',
      });
      await exportProject({
        id,
      });

      message.success('导出成功');
    } catch {
      message.error('导出失败');
    } finally {
      setLoadingInfo({
        loading: false,
        tip: null,
      });
    }
  };

  const handleRemoveProject = (id: string) => {
    Modal.confirm({
      title: '确认删除',
      icon: <ExclamationCircleOutlined className="anticon" />,
      content: '项目删除后可在回收站中查看，确认删除该项目？',
      async onOk() {
        await removeProjectReq.mutate(
          {
            ids: [id],
          },
          {
            onSuccess: () => {
              message.success('删除成功');
              handleGetPageList();
              getProjectGroupListReq.mutate();
            },
          },
        );
      },
    });
  };

  const handelSearchFocusChange = useCallback(() => {
    if (searchAutoFocus) {
      searchInputRef.current?.blur();
      setSearchParams((state) => ({ ...state, name: '' }));
    } else {
      searchInputRef.current?.focus();
    }

    setSearchAutoFocus(!searchAutoFocus);
  }, [searchAutoFocus]);

  const onDropProject = async (groupId: string) => {
    if (!handleId) return;
    await updateProjectReq.mutate(
      {
        id: handleId,
        groupId,
      },
      {
        onSuccess: () => {
          handleGetPageList();
          getProjectGroupListReq.mutate();
          message.success('修改成功');
        },
      },
    );
  };

  useKey((e) => isCtrlKey(e) && e.code === 'KeyF', handelSearchFocusChange, undefined, [
    handelSearchFocusChange,
  ]);

  return (
    <div className="h-full flex">
      {/* left menu */}
      <div className="w-64 h-full flex flex-col bg-bgColorLayout">
        {/* menu list */}
        <div className="flex-auto overflow-y-auto py-2">
          <GroupMenu
            title="项目分组"
            titleIcon={<CodepenOutlined className="anticon" />}
            beforeDataSource={beforeDataSource}
            afterDataSource={
              getProjectGroupListReq.data?.filter(
                (i) =>
                  i.id !== NotSaveGroupId.ALL_GROUP_FOR_PROJECT &&
                  i.id !== NotSaveGroupId.NOT_GROUP_FOR_PROJECT,
              ) || []
            }
            selectKey={selectGroupKey}
            onSelect={(key) => {
              setIsRecycle(false);
              setSelectGroupKey(key);
            }}
            onCreate={(name) =>
              createProjectGroupReq.mutate(
                { name },
                {
                  onSuccess: (data) => {
                    setIsRecycle(false);
                    setSelectGroupKey(data?.id);
                  },
                },
              )
            }
            onEditName={(id, name) => updateProjectGroupReq.mutate({ id, name })}
            onRomove={handleRemoveGroup}
            onDropProject={onDropProject}
          />
        </div>

        {/* 回收站 */}
        <div
          className={classnames(
            'h-12 px-5 flex items-center cursor-pointer hover:bg-bgColorHover hover:text-white',
            {
              'bg-primary': isRecycle,
            },
            isRecycle ? 'text-white' : 'text-textColorBase',
          )}
          onClick={() => {
            setIsRecycle(true);
            setSelectGroupKey(null);
            getProjectRecycleListReq.mutate({
              ...pageQuery,
              deleted: true,
            });
          }}>
          <Space>
            <RecycleOutlined className="anticon" />
            <span>回收站</span>
          </Space>
        </div>
      </div>

      {/* right content */}
      <div className="flex-auto flex flex-col px-10 py-5 gap-y-6 bg-bgColorMain">
        {/* top tool */}
        {!isRecycle ? (
          <div className="flex">
            {/*  */}
            <div className="flex-1 flex gap-x-2">
              <ProButton
                className="introStep1"
                type="primary"
                icon={<PlusOutlined className="anticon" />}
                onClick={() => navigate(`/project-template/${id}`)}>
                新建
              </ProButton>
              <Upload
                showUploadList={false}
                accept={FeatZipSubfix}
                beforeUpload={async (file) => {
                  if (id) {
                    await importProject({ file, groupId: id });
                    await getProjectGroupListReq.mutate();
                    await handleGetPageList();
                  }
                  return false;
                }}>
                <ProButton type="primary" proType="subPrimary">
                  导入
                </ProButton>
              </Upload>
            </div>

            {/*  */}
            <div className="flex-1 flex justify-end">
              <Input
                ref={searchInputRef}
                allowClear
                value={searchParams.name}
                className="!w-60"
                placeholder={`搜索项目（${ctrlKeyStr} F）`}
                prefix={<SearchOutlined className="anticon" />}
                onChange={(e) => setSearchParams({ ...searchParams, name: e.target.value })}
              />
            </div>
          </div>
        ) : (
          <Alert
            showIcon
            className="text-textColorBase"
            message="离线客户端版本中回收站数据会持久存储"
            type="info"
          />
        )}

        {/* main */}
        <div className="flex-auto overflow-y-auto">
          {!isRecycle ? (
            projectPageList?.length ? (
              <div className="grid gap-6 grid-cols-[repeat(auto-fill,minmax(258px,1fr))]">
                {projectPageList.map((item) => (
                  <ProjectCard
                    key={item.id}
                    dataSource={item}
                    footer={
                      <NameEdit
                        initValue={item.name}
                        onChange={(value) =>
                          updateProjectReq.mutate(
                            {
                              id: item.id,
                              name: value,
                            },
                            {
                              onSuccess: () => {
                                message.success('修改成功');
                              },
                            },
                          )
                        }
                      />
                    }
                    extendRender={
                      <div className="h-full flex flex-col justify-center items-center gap-4 text-white">
                        <Space size={20}>
                          <Tooltip title="移动分组">
                            <span
                              draggable
                              onDragStart={() => {
                                setHhandleId(item.id);
                              }}>
                              <DragOutlined className="hover:text-primary anticon" />
                            </span>
                          </Tooltip>
                          <Tooltip title="复制">
                            <CopySquareOutlined
                              className="hover:text-primary anticon"
                              onClick={async () => {
                                setLoadingInfo({
                                  loading: true,
                                  tip: '复制项目中...',
                                });
                                await copyProject({
                                  id: item.id,
                                  name: item.name,
                                });

                                setLoadingInfo({
                                  loading: false,
                                  tip: null,
                                });
                                message.success('复制成功');

                                await getProjectGroupListReq.mutate();
                                await handleGetPageList();
                              }}
                            />
                          </Tooltip>
                          <Tooltip title="导出">
                            <DownloadOutlined
                              className="hover:text-primary anticon"
                              onClick={() => handleExportProject(item.id)}
                            />
                          </Tooltip>
                          <Tooltip title="删除">
                            <DeleteSquareOutlined
                              className="hover:text-primary anticon"
                              onClick={() => handleRemoveProject(item.id)}
                            />
                          </Tooltip>
                        </Space>
                        <Space>
                          <ProButton
                            size="small"
                            type="primary"
                            proType="subPrimary"
                            onClick={() =>
                              navigate(
                                `/project-preview/${item.id}?from=${window.location.hash
                                  .split('#')
                                  .join('')}`,
                              )
                            }>
                            预览
                          </ProButton>
                          <ProButton
                            type="primary"
                            size="small"
                            onClick={() => navigate(`/project-editor/${item.id}`)}>
                            编辑
                          </ProButton>
                        </Space>
                      </div>
                    }
                  />
                ))}
              </div>
            ) : (
              <Empty description="暂无项目，请点击左上角新建按钮创建" className="py-20" />
            )
          ) : getProjectRecycleListReq.data?.length ? (
            <div className="grid gap-6 grid-cols-[repeat(auto-fill,minmax(258px,1fr))]">
              {getProjectRecycleListReq.data.map((item) => (
                <ProjectCard
                  key={item.id}
                  dataSource={item}
                  footer={<NameEdit disabledEdit initValue={item.name} />}
                  extendRender={
                    <div className="h-full flex flex-col justify-center items-center">
                      <ProButton
                        type="primary"
                        size="small"
                        onClick={() => {
                          recycleProjectReq.mutate(
                            {
                              ids: [item.id],
                            },
                            {
                              onSuccess: () => {
                                message.success('恢复成功');
                                getProjectGroupListReq.mutate();
                                getProjectRecycleListReq.mutate({
                                  ...pageQuery,
                                  deleted: true,
                                });
                              },
                            },
                          );
                        }}>
                        恢复
                      </ProButton>
                    </div>
                  }
                />
              ))}
            </div>
          ) : (
            <Empty description="回收站为空" className="py-20" />
          )}
        </div>
      </div>
    </div>
  );
}
