import { Button, Empty, Form, Input, Typography } from 'antd';
import { useWatch } from 'antd/lib/form/Form';
import Link from 'antd/lib/typography/Link';
import { Space } from 'antd5';
import _ from 'lodash';
import { useCallback, useContext, useMemo, useState } from 'react';
import { useIntl } from 'umi';
import CustomTree from '../../CustomTree';
import { leafBuildTree, treeLeafNode } from '../../utils/array';
import { relationUserCityRemove } from '../api';
import { DetailContext } from '../detail';
import { createCancelInterceptor } from '../util';

export interface CityTabProps {
  cityOptions: any[];
  oldCityList: any[];
  searchSeparator?: string;
  detailRefresh?: () => void;
  cityRefresh?: () => void;
}

const CityTab = (props: CityTabProps) => {
  const { cityOptions, oldCityList, searchSeparator = ' ', detailRefresh, cityRefresh } = props;

  const {
    id: appId,
    type,
    useType,
    currentUser,
    form,
    onSyncCitySelect,
  } = useContext(DetailContext);

  const { formatMessage } = useIntl();
  const [search, setSearch] = useState('');

  // 搜索过滤后的树
  const treeData = useMemo(() => {
    if (!search || !search.trim()) return cityOptions;
    const split = search.trim().split(searchSeparator);
    const leafKeys = treeLeafNode<any>(cityOptions, (item) => {
      return split.some((k: string) => item.name?.includes(k));
    }).map((item) => item.id);
    return leafBuildTree(leafKeys, cityOptions);
  }, [cityOptions, search, searchSeparator]);

  const cities = useWatch('cities', form);
  const { data: cityData } = cities || {};

  // 选择全部
  const selectAll = useCallback(
    (item?: any) => {
      const currSelect: any[] = cityData?.filter((v: any) => v) || [];
      const currKeys = currSelect.map((v) => String(v.id));
      const find = (id: string) => {
        return currSelect.find((v) => String(v.id) === id) ?? { id, expiredAt: undefined };
      };

      if (item) {
        const leafs = treeLeafNode([item]).map((v) => String(v.id));
        const newKeys = [...new Set([...currKeys, ...leafs])];
        const data = newKeys.map(find);
        form?.setFieldsValue({ cities: { data } });
      } else {
        // 全部选择
        const leafs = treeLeafNode(treeData).map((v) => String(v.id));
        const newKeys = [...new Set([...currKeys, ...leafs])];
        const data = newKeys.map(find);
        form?.setFieldsValue({ cities: { data } });
      }
    },
    [cityData, form, treeData],
  );

  // 取消选择
  const unSelectAll = useCallback(
    (item?: any) => {
      const currSelect: any[] = cityData?.filter((v: any) => v) || [];
      const currKeys = currSelect.map((v) => String(v.id));
      const oldKeys = oldCityList?.map((v) => String(v.cityId ?? v.id)) ?? [];
      const find = (id: string) => {
        return currSelect.find((v) => String(v.id) === id);
      };

      if (item) {
        const leafs = treeLeafNode([item]).map((v) => String(v.id));
        const data = currKeys.filter((id) => !leafs.includes(id) || oldKeys.includes(id)).map(find);
        form?.setFieldsValue({ cities: { data } });
      } else {
        // 全部取消
        const data = oldKeys.map(find);
        form?.setFieldsValue({ cities: { data } });
      }
    },
    [cityData, form, oldCityList],
  );

  return cityOptions?.length ? (
    <Form.Item name={'cities'}>
      <CustomTree
        treeData={treeData}
        isOtherUser={type === 2}
        isHaveCheckBox={useType === 'operation'}
        type={'city'}
        oldData={oldCityList?.map((item) => ({ ...item, id: item.cityId ?? item.id }))}
        onlyLeafCheckable
        toolbarSpaceSize={'large'}
        renderToolbar={() => {
          return (
            <Space align={'center'} size={'large'}>
              <label>{formatMessage({ id: 'component.AppDetail.city.search.title' })}</label>

              <Input
                style={{ width: 300 }}
                placeholder={formatMessage({ id: 'component.AppDetail.city.search.tips' })}
                allowClear
                value={search}
                onChange={(e) => setSearch(e.target.value)}
              />

              {_.isFunction(onSyncCitySelect) && (
                <>
                  <label style={{ color: '#F16622' }}>
                    {formatMessage({ id: 'component.AppDetail.city.sync.title' })}
                  </label>

                  <Button
                    type={'primary'}
                    disabled={!cityData?.length}
                    onClick={() => onSyncCitySelect(cities)}
                  >
                    {formatMessage({ id: 'component.AppDetail.city.sync' })}
                  </Button>
                </>
              )}
            </Space>
          );
        }}
        renderExpandLeft={() => {
          return (
            <Space>
              <Link onClick={() => selectAll()}>
                {formatMessage({ id: 'component.AppDetail.city.selectAll' })}
              </Link>
              <Link onClick={() => unSelectAll()}>
                {formatMessage({ id: 'component.AppDetail.city.unSelectAll' })}
              </Link>
            </Space>
          );
        }}
        customRender={(node, item: any) => {
          const { children } = item;
          return (
            <>
              {node}&nbsp;
              {Array.isArray(children) && children.length > 0 && (
                <Space>
                  <Link onClick={() => selectAll(item)}>
                    {formatMessage({ id: 'component.check.all' })}
                  </Link>
                  <Link onClick={() => unSelectAll(item)}>
                    {formatMessage({ id: 'component.AppDetail.city.unSelectAll' })}
                  </Link>
                </Space>
              )}
              {useType === 'single' &&
                type === 1 &&
                oldCityList?.find((v) => v.cityId === Number(item.id)) && (
                  <Typography.Text type={'danger'}>
                    {formatMessage({ id: 'base.common.owned' })}
                  </Typography.Text>
                )}
            </>
          );
        }}
        checkInterceptor={
          useType !== 'operation' && type === 1
            ? (__, info) => {
                const { checked, node } = info;
                return createCancelInterceptor({
                  checked,
                  formatMessage,
                  trigger() {
                    return oldCityList?.find((item) => item.cityId === Number(node?.id));
                  },
                  request() {
                    return relationUserCityRemove({
                      data: [{ appId, userId: currentUser?.id, cityId: Number(node?.id) }],
                    });
                  },
                  refresh: () => {
                    detailRefresh?.();
                    cityRefresh?.();
                  },
                });
              }
            : undefined
        }
      />
    </Form.Item>
  ) : (
    <Empty
      style={{ marginTop: '23%' }}
      description={formatMessage({
        id: 'base.common.city.no.permission',
        defaultMessage: '没有城市权限',
      })}
    />
  );
};

export default CityTab;
