import React, { Fragment, useCallback, useState, useEffect } from 'react';
import { Space } from '@easyv/antd';
import { nest } from 'd3';
import DeleteConfirmModal from 'components/DeleteConfirmModal';
import Thumb from 'components/Thumb';
import CategoryModal from '../CategoryModal/CategoryModal';
// import SortModal from './SortModal';
import EditModal from './EditModal';
import { useRequest } from 'components/easyUse/useRequest';
import { api } from 'constants/config';
import { request } from 'utils/fetch';
import { getAssetsUrl } from 'utils/utils';
import { useMemo } from 'react';
import { uploadAssets } from 'utils/upload';
import ExportContainer from './ExportContainer';
import MultiExportModal from './MultiExportModal';
import MultiImportModal from './MultiImportModal';
import PanelHeaderContainer from 'components/PanelHeaderContainer';
import EasyvButton from 'components/EasyvButton';
import EasyvTable from 'components/EasyvTable';
import { Input, ConfigProvider } from '@easyv/react-gui';
import styles from '../style.less';
import EasyvTooltip from 'components/EasyvTooltip';
import classNames from 'classnames';
import { useSelector } from 'react-redux';
import { RootState } from 'models';
import message from 'components/message';
import { getLabelsByType } from 'services/labelsResource';
import { MaterialSquare } from 'models/adminPanel.types';

const { Search } = Input;

export default function Material() {
  const transfer = useSelector<RootState>((state) => state.transfer) as RootState['transfer'];
  const { deadline } = transfer;

  const [labelsAllList, setlabelsAllList] = useState<string[]>([]);
  const [search, setSearch] = useState('');
  const [selected, setSelected] = useState([]);
  const [sorter, setSorter] = useState<any>({});
  const [filter, setFilter] = useState<any>({});
  const {
    loading,
    data = { data: [] },
    error,
    refresh,
  } = useRequest(`${api.materialListGet}?pageNum=1&pageSize=9999`);
  const { data: categorysData = [], refresh: refreshCategorys } = useRequest(
    `${api.materialCategoryListGet}?type=1`,
  );

  const groupedCategorys = useMemo(() => {
    return getGroupedCategorys(categorysData);
  }, [categorysData]);

  useEffect(() => {
    const initLabelsAllList = async () => {
      const _labelsAllList = await getLabelsByType(MaterialSquare.DESIGN_MATERIAL);
      setlabelsAllList(_labelsAllList);
    };
    initLabelsAllList();
  }, []);
  const handleAdd = useCallback(async (body) => {
    if (body.content && typeof body.content === 'object') {
      const result = await uploadAssets({
        path: `data/assets/${body.content.name}`,
        file: body.content,
      });
      if (result) {
        body.content = result;
        if (body.type === 1) {
          body.thumb = result;
          body.preview = result;
        }
      }
    }
    if (body.thumb && typeof body.thumb === 'object') {
      const result = await uploadAssets({
        path: `data/assets/${body.thumb.name}`,
        file: body.thumb,
      });
      if (result) {
        body.thumb = result;
        body.preview = result;
      }
    }

    const result = await request(api.materialCreate, undefined, undefined, JSON.stringify(body));
    refresh();
    return result;
  }, []);

  const handleUpdate = useCallback(async (body) => {
    const { id, ...rest } = body;
    const param = rest;
    if (param.content && typeof param.content === 'object') {
      const result = await uploadAssets({
        path: `data/assets/${param.content.name}`,
        file: param.content,
      });
      if (result) {
        param.content = result;
        if (param.type === 1) {
          param.thumb = result;
          param.preview = result;
        }
      }
    }
    if (param.thumb && typeof param.thumb === 'object') {
      const result = await uploadAssets({
        path: `data/assets/${param.thumb.name}`,
        file: param.thumb,
      });
      if (result) {
        param.thumb = result;
        param.preview = result;
      }
    }
    const result = await request(api.materialUpdate, { id }, undefined, JSON.stringify(param));
    refresh();
    return result;
  }, []);

  const handleDelete = async (ids) => {
    try {
      const result = await request(`${api.materialsDelete}?ids=${ids.join(',')}`);
      result && message.success('删除成功');
      refresh();
    } catch (error) {}
  };

  const handleRelease = async (ids) => {
    const result = await request(
      api.materialsRelease,
      undefined,
      undefined,
      JSON.stringify({ ids, action: 'release' }),
    );
    result && message.success('上架成功');
    refresh();
  };

  const handleUnRelease = async (ids) => {
    try {
      const result = await request(
        api.materialsUnRelease,
        undefined,
        undefined,
        JSON.stringify({ ids, action: 'unrelease' }),
      );
      result && message.success('下架成功');
      refresh();
    } catch (error) {}
  };

  const handleSort = useCallback(async (orders) => {
    const orderKeys = Object.keys(orders);
    if (orderKeys.length) {
      const ids = orderKeys.reduce((all, item) => {
        return all.concat(orders[item].map((d) => d.id));
      }, []);
      const result = await request(
        api.materialsSort,
        undefined,
        undefined,
        JSON.stringify({ ids, action: 'sort' }),
      );
      refresh();
      return result;
    }
  }, []);

  const handleTableChange = (_pagination, filter, sorter) => {
    setFilter(filter);
    setSorter(sorter);
  };

  const { officialCategoryId, status } = filter;
  const { field, order } = sorter;

  let resultData = data.data
    .filter((d) => d.name.includes(search))
    .filter((d) => {
      return (
        (!officialCategoryId ||
          officialCategoryId.length == 0 ||
          officialCategoryId.includes(d.officialCategoryId + '')) &&
        (!status || status.length == 0 || status.includes(d.status + ''))
      );
    });
  if (field) {
    resultData = resultData.concat().sort((a, b) => {
      if (field === 'updatedAt') {
        if (order === 'ascend') {
          return +new Date(a.updatedAt) - +new Date(b.updatedAt);
        } else {
          return +new Date(b.updatedAt) - +new Date(a.updatedAt);
        }
      } else {
        if (order === 'ascend') {
          return a[field] - b[field];
        } else {
          return b[field] - a[field];
        }
      }
    });
  }

  const columns = [
      {
        title: '名称',
        dataIndex: 'name',
        width: '20%',
      },
      {
        title: '封面',
        dataIndex: 'thumb',
        width: '10%',
        render: (text) => (
          <Thumb
            src={text ? getAssetsUrl(`${text}`) : undefined}
            style={{ width: 68, height: 44 }}
          />
        ),
      },
      {
        title: '类型',
        dataIndex: 'type',
        width: '10%',
        render: (text) => (text === 1 ? '图片' : '视频'),
      },
      {
        title: '分类',
        dataIndex: 'officialCategoryId',
        width: '10%',
        filters: groupedCategorys.map((d) => ({
          text: d.name,
          value: d.id,
          children: d.children?.map((v) => ({ text: v.name, value: v.id })),
        })),
        render: (text) => {
          return categorysData.find((d: any) => d.id === text)?.name || '未分类';
        },
      },
      {
        title: '状态',
        dataIndex: 'status',
        width: '10%',
        filters: [
          { text: '已发布', value: 1 },
          { text: '未发布', value: 0 },
        ],
        render: (text) => (
          <span style={{ display: 'flex', alignItems: 'center' }}>
            <i
              style={{
                width: 8,
                height: 8,
                borderRadius: '50%',
                marginRight: 8,
                background: text ? '#00A755' : '#BFBFBF',
              }}
            />
            {text ? '已发布' : '未发布'}
          </span>
        ),
      },
      {
        title: '使用次数',
        dataIndex: 'usedTime',
        width: '10%',
        sorter: true,
        showSorterTooltip: false,
      },
      {
        title: '创建时间',
        dataIndex: 'createdAt',
        width: '15%',
        sorter: true,
        showSorterTooltip: false,
        render: (text) => new Date(text).toLocaleString(),
      },
      {
        title: '操作',
        dataIndex: 'options',
        render: (_text, record: any) => (
          <Space>
            <EditModal
              data={record}
              categorys={groupedCategorys}
              onOk={handleUpdate}
              edit={true}
              labelsAllList={labelsAllList}>
              <EasyvTooltip title="编辑">
                <i className={classNames('icon iconfont icon-custom ' + styles.iconHover)} />
              </EasyvTooltip>
            </EditModal>

            <ExportContainer list={[record.id]}>
              <EasyvTooltip title="导出">
                <i className={classNames('icon iconfont icon-daochu ' + styles.iconHover)} />
              </EasyvTooltip>
            </ExportContainer>
            {record.status ? (
              <EasyvTooltip title="下架">
                <i
                  onClick={() => handleUnRelease([record.id])}
                  className={classNames('icon iconfont icon-xiajia ' + styles.iconHover)}
                />
              </EasyvTooltip>
            ) : (
              <EasyvTooltip title="发布">
                <i
                  onClick={() => handleRelease([record.id])}
                  className={classNames(
                    'icon iconfont icon-btn_publishhomepage ' + styles.iconHover,
                  )}
                />
              </EasyvTooltip>
            )}
            <DeleteConfirmModal title="删除组件" onOk={() => handleDelete([record.id])}>
              <EasyvTooltip title="删除">
                <i className={classNames('icon iconfont icon-btn_delete ' + styles.iconHover)} />
              </EasyvTooltip>
            </DeleteConfirmModal>
          </Space>
        ),
      },
    ];

  return (
    <Fragment>
      <PanelHeaderContainer>
        <div>
          <ConfigProvider>
            <Search
              className={styles.searchInput}
              onChange={(e) => setSearch(e.target.value)}
              placeholder="请输入搜索"
              value={search}
            />
          </ConfigProvider>
          <EasyvButton
            style={{ marginLeft: 16 }}
            disabled={selected.length === 0}
            onClick={() => handleUnRelease(selected)}>
            批量下架
          </EasyvButton>
          <EasyvButton
            style={{ marginLeft: 12 }}
            disabled={selected.length === 0}
            onClick={() => handleRelease(selected)}>
            批量上架
          </EasyvButton>
          <MultiExportModal
            data={selected.map((d) => ({ id: d, name: data.data.find((v) => v.id === d)?.name }))}>
            <EasyvButton style={{ marginLeft: 12 }} disabled={selected.length === 0}>
              批量导出
            </EasyvButton>
          </MultiExportModal>
          <DeleteConfirmModal
            title="批量删除"
            onOk={() => {
              handleDelete(selected);
            }}>
            <EasyvButton style={{ marginLeft: 12 }} disabled={selected.length === 0}>
              批量删除
            </EasyvButton>
          </DeleteConfirmModal>
        </div>
        <div>
          <CategoryModal
            belongTo="tenant"
            type="material"
            data={groupedCategorys}
            refresh={refreshCategorys}>
            <EasyvButton style={{ marginRight: 12 }}>分类管理</EasyvButton>
          </CategoryModal>
          {/* <SortModal categorys={groupedCategorys} data={data.data} onOk={handleSort}>
            <EasyvButton style={{ marginRight: 12 }}>排序</EasyvButton>
          </SortModal> */}
          <EditModal categorys={groupedCategorys} onOk={handleAdd} labelsAllList={labelsAllList}>
            <EasyvButton style={{ marginRight: 12 }}>新建</EasyvButton>
          </EditModal>
          <MultiImportModal refresh={refresh}>
            <EasyvButton theme="primary">导入</EasyvButton>
          </MultiImportModal>
        </div>
      </PanelHeaderContainer>
      <EasyvTable
        loading={loading}
        selectedRowKeys={selected}
        onRowSelectChange={(v) => setSelected(v)}
        dataSource={resultData}
        rowKey={(d: any) => d.id}
        scroll={deadline ? { y: 'calc(100vh - 298px)' } : { y: 'calc(100vh - 250px)' }}
        columns={columns}
        onChange={handleTableChange}
      />
    </Fragment>
  );
}

function getGroupedCategorys(data) {
  let result: any[] = [];
  const nestedCategorys = nest()
    .key((d) => d.parentId)
    .entries(data);

  nestedCategorys
    .concat()
    .sort((a, b) => a.key - b.key)
    .map((d) => {
      if (d.key == 0) {
        result = d.values;
      } else {
        result = result.map((v) => {
          if (v.id == d.key) {
            return {
              ...v,
              children: d.values,
            };
          } else {
            return v;
          }
        });
      }
    });

  result = result.map((d) => (d.children ? d : { ...d, children: [] }));

  return result;
}
