/*
 * @Author: wangqiang@feewee.cn
 * @Date: 2022-05-25 10:03:00
 * @LastEditors: wangqiang@feewee.cn
 * @LastEditTime: 2022-10-08 16:33:31
 */
import { InitialReturn } from "@/hooks/useInitail";
import {
  Button,
  Checkbox,
  Divider,
  Input,
  Modal,
  Popconfirm,
  Popover,
  Radio,
  Row,
  Select,
  Spin,
  Table,
} from "antd";
import { CheckboxChangeEvent } from "antd/lib/checkbox";
import { debounce } from "lodash";
import React from "react";
import {
  ShopItem,
  BizType,
  DealerOrBrand,
  Value,
  Option,
  QueryParams,
  ShopSelectNewOptions,
} from "../api";

interface Props {
  visible: boolean;
  setVisible: React.Dispatch<React.SetStateAction<boolean>>;
  selected: Value[];
  setSelected: React.Dispatch<React.SetStateAction<Value[]>>;
  tableType: "列表" | "选择";
  setTableType: React.Dispatch<React.SetStateAction<"列表" | "选择">>;
  checkInfo: {
    indeterminate: boolean;
    checkAll: boolean;
  };
  onChange?: Function;
  type: 1 | 2; // 1 集团维度 2 自定义门店维度
  multiple?: boolean;
  optionInitial: InitialReturn<Option, QueryParams>;
  listInitial: InitialReturn<ShopItem[], QueryParams>;
  defaultOptions?: ShopSelectNewOptions;
}

export default function ShopModal({
  visible,
  setVisible,
  selected,
  setSelected,
  tableType,
  setTableType,
  checkInfo,
  onChange,
  type,
  multiple,
  optionInitial,
  listInitial,
  defaultOptions = {},
}: Props) {
  const fetchListByName = debounce(
    (keywords) => listInitial.setParams({ type, keywords }, true),
    500
  );
  /**
   * @description: 当一个门店被点击时，触发该回调函数。
   * @param {ShopItem} record 当前门店数据
   * @param {boolean} _selected 是否选中
   * @param {Object[]} selectedRows 已被选择的数据
   * @param {Event} nativeEvent 点击事件
   */
  const onSelect = (
    record: ShopItem,
    _selected: boolean,
    selectedRows: Object[],
    nativeEvent: Event
  ) => {
    if (multiple) {
      if (_selected) {
        // 若被选择，则将该数据处理后，插入已选择列表中
        setSelected([
          ...selected,
          { ...record, value: record.shopId, label: record.shopShortName },
        ]);
      } else {
        // 若被取消选择，则将该数据，从已选择列表中删除
        setSelected(selected.filter((item) => item.shopId !== record.shopId));
      }
    } else {
      true;
      if (_selected) {
        setSelected([
          { ...record, value: record.shopId, label: record.shopShortName },
        ]);
      } else {
        setSelected([]);
      }
    }
  };

  /**
   * @description: 当全选CheckBox被点击时，调用该回调函数
   * @description: 只有 多选才会调用该全选函数，故起函数内部不需要判断是否多选情况
   * @param {boolean} _selected 是否选中
   * @param {ShopItem[]} selectedRows 已被选择的数据列表
   * @param {ShopItem[]} changeRows 点击全选CheckBox后，受影响的数据列表。该数据与_selected参数共同使用，可以得知是应该将changeRows数据加入已选中数据还是删除
   */
  const onSelectAll = (
    _selected: boolean,
    selectedRows: ShopItem[],
    changeRows: ShopItem[]
  ) => {
    if (_selected) {
      // 若选中全选CheckBox，则将changeRows中的还未被选入selected中的数据插入
      setSelected(
        selected.concat(
          changeRows.map((row) => ({
            ...row,
            value: row.shopId,
            label: row.shopShortName,
          }))
        )
      );
    } else {
      // 若取消选择全选CheckBox，则将changeRows中的数据全部从selected中删除
      const cancelIds = changeRows.map((row) => row.shopId);
      // @ts-ignore
      setSelected(selected.filter((item) => !cancelIds.includes(item.value)));
    }
  };

  const rowClick = (record: Value) => {
    if (multiple) {
      if (selected.some((item) => item.value === record.shopId)) {
        setSelected(selected.filter((item) => item.value !== record.shopId));
      } else {
        setSelected(
          selected.concat({
            ...record,
            value: record.shopId,
            label: record.shopShortName,
          })
        );
      }
    } else {
      setSelected([
        { ...record, value: record.shopId, label: record.shopShortName },
      ]);
    }
  };

  const onOk = () => {
    onChange && onChange(selected);
    setVisible(false);
  };

  const checkAll = (e: CheckboxChangeEvent) => {
    const checked = e.target.checked;
    setSelected(
      checked
        ? listInitial.data.map((item) => ({
            ...item,
            value: item.shopId,
            label: item.shopShortName,
          }))
        : []
    );
  };

  return (
    <Modal
      title={`选择门店(${multiple ? "多选" : "单选"})`}
      width="80%"
      maskClosable={false}
      visible={visible}
      onCancel={() => setVisible(false)}
      onOk={() => onOk()}
    >
      {multiple ? (
        <>
          <Row justify="space-between">
            <Radio.Group
              buttonStyle="solid"
              value={tableType}
              onChange={(e) => setTableType(e.target.value)}
            >
              <Radio.Button value="列表">列表</Radio.Button>
              <Radio.Button value="选择" disabled={!selected.length}>
                当前选择({selected.length} 个)
              </Radio.Button>
            </Radio.Group>
            <Row>
              {multiple ? (
                <Checkbox
                  className="ShopSelectNew_checkbox"
                  indeterminate={checkInfo.indeterminate}
                  checked={checkInfo.checkAll}
                  onChange={checkAll}
                >
                  全选
                </Checkbox>
              ) : null}
              <Popconfirm
                title="确定清空已选择门店？"
                disabled={!selected.length}
                onConfirm={() => {
                  setSelected([]);
                  setTableType("列表");
                }}
              >
                <Button danger type="link" disabled={!selected.length}>
                  清空
                </Button>
              </Popconfirm>
            </Row>
          </Row>
          <Divider />
        </>
      ) : null}
      <Spin spinning={optionInitial.loading}>
        <Row
          justify="start"
          align="middle"
          style={{ display: tableType === "列表" ? "flex" : "none" }}
          className="ShopSelectNew_Filter_Container"
        >
          <Input
            allowClear
            placeholder="请输入门店名查询"
            value={listInitial.params.keywords}
            onChange={(e) => fetchListByName(e.target.value)}
            style={{ maxWidth: 260, marginRight: 10, marginBottom: 10 }}
          />
          <Select
            allowClear
            placeholder="请选择业态"
            mode="multiple"
            value={
              listInitial.params.bizTypes
                ? listInitial.params.bizTypes.split(",")
                : undefined
            }
            onChange={(bizs) => listInitial.setParams(
                {
                  type,
                  bizTypes: bizs.length
                    ? bizs?.join(",")
                    : defaultOptions.bizTypes,
                },
                true
              )}
            showSearch
            optionFilterProp="children"
            style={{ minWidth: 260, marginBottom: 10, marginRight: 10 }}
            getPopupContainer={(triggerNode) => triggerNode.parentNode}
          >
            {optionInitial.data.bizList?.map((biz) => (
              <Select.Option
                key={biz.type}
                value={"" + biz.type!}
                disabled={defaultOptions.bizTypes?.includes("" + biz.type)}
              >
                {biz.name}
              </Select.Option>
            ))}
          </Select>
          <Select
            allowClear
            placeholder="请选择区域"
            mode="multiple"
            value={
              listInitial.params.regions
                ? listInitial.params.regions.split(",")
                : undefined
            }
            onChange={(regions) => listInitial.setParams(
                {
                  type,
                  regions: regions.length
                    ? regions?.join(",")
                    : defaultOptions.regions,
                },
                true
              )}
            showSearch
            optionFilterProp="children"
            style={{ minWidth: 260, marginBottom: 10, marginRight: 10 }}
            getPopupContainer={(triggerNode) => triggerNode.parentNode}
          >
            {optionInitial.data.regionList?.map((region) => (
              <Select.Option
                key={region.bh}
                value={region.bh!}
                disabled={defaultOptions.regions?.includes("" + region.bh)}
              >
                {region.fullName}
              </Select.Option>
            ))}
          </Select>
          <Select
            allowClear
            placeholder="请选择品牌"
            mode="multiple"
            value={
              listInitial.params.brands
                ? listInitial.params.brands.split(",")
                : undefined
            }
            onChange={(brandList) => listInitial.setParams(
                {
                  type,
                  brands: brandList.length
                    ? brandList?.join(",")
                    : defaultOptions.brands,
                },
                true
              )}
            showSearch
            optionFilterProp="children"
            style={{ minWidth: 260, marginBottom: 10, marginRight: 10 }}
            getPopupContainer={(triggerNode) => triggerNode.parentNode}
          >
            {optionInitial.data.brandList?.map((brand) => (
              <Select.Option
                key={brand.id}
                value={"" + brand.id!}
                disabled={defaultOptions.brands?.includes("" + brand.id)}
              >
                {brand.name}
              </Select.Option>
            ))}
          </Select>
          <Select
            allowClear
            placeholder="请选择商家"
            mode="multiple"
            value={
              listInitial.params.dealers
                ? listInitial.params.dealers.split(",")
                : undefined
            }
            onChange={(dealerList) => listInitial.setParams(
                {
                  type,
                  dealers: dealerList.length
                    ? dealerList?.join(",")
                    : defaultOptions.dealers,
                },
                true
              )}
            showSearch
            optionFilterProp="children"
            style={{ minWidth: 260, marginBottom: 10, marginRight: 10 }}
            getPopupContainer={(triggerNode) => triggerNode.parentNode}
          >
            {optionInitial.data.dealerList?.map((dealer) => (
              <Select.Option
                key={dealer.id}
                value={"" + dealer.id!}
                disabled={defaultOptions.dealers?.includes("" + dealer.id)}
              >
                {dealer.name}
              </Select.Option>
            ))}
          </Select>
        </Row>
      </Spin>
      <Table
        dataSource={tableType === "列表" ? listInitial.data : selected}
        rowKey="shopId"
        size="small"
        loading={listInitial.loading}
        onRow={(record) => ({
          onClick: () => rowClick(record),
        })}
        rowSelection={{
          type: multiple ? "checkbox" : "radio",
          selectedRowKeys: selected.map(
            (item) => item.value || item.shopId || -1
          ),
          onSelect,
          onSelectAll,
        }}
      >
        <Table.Column
          title="门店名称"
          dataIndex="shopFullName"
          align="left"
          render={(shopFullName) => shopFullName || "-"}
        />
        <Table.Column
          title="门店简称"
          dataIndex="shopShortName"
          align="left"
          render={(shopFullName) => shopFullName || "-"}
        />
        <Table.Column
          title="门店业态"
          dataIndex="bizType"
          align="left"
          render={(bizType) => (bizType ? BizType[bizType] : "-")}
        />
        <Table.Column
          title="归属公司"
          dataIndex="dealer"
          align="left"
          render={(dealer) => dealer?.name || "-"}
        />
        <Table.Column
          title="门店区域"
          dataIndex="region"
          align="left"
          render={(region) => region?.fullName || "-"}
        />
        <Table.Column
          title="授权品牌"
          dataIndex="brandList"
          align="left"
          render={(brandList: DealerOrBrand[]) => (brandList?.length ? (
            <Popover
              placement="topLeft"
              content={
                <span>
                  {brandList?.map((brand) => (
                    <div key={brand.id}>{brand.name}</div>
                    ))}
                </span>
                }
            >
              <span className="span_limit_1">
                {brandList?.map((brand) => brand.name).join("；")}
              </span>
            </Popover>
            ) : (
              "-"
            ))}
        />
        <Table.Column
          title="对应售后门店"
          dataIndex="casShopName"
          align="left"
          render={(casShopName) => casShopName || "-"}
        />
      </Table>
    </Modal>
  );
}
