import { createContext, useContext, useEffect } from 'react';
import { toJS } from 'mobx';
import { observer } from 'mobx-react';
import { DATE_FORMAT, stores_Context } from './../../config';
import { SearchOutlined } from '@ant-design/icons';
import { Form, Row, Col, Select, Button, Space, DatePicker } from 'antd';
import moment from 'moment';
// import locale from 'antd/es/date-picker/locale/zh_CN';
import BusinessSelect from './BusinessSelect';
import BusinessUnitSelect from './BusinessUnitSelect';
import GroupSelect from './GroupSelect';
import SiteSelect from './SiteSelect';
import DateTypeSelect from './DataTypeSelect';
import DatePickerCharts from './DatePickerCharts';
import YearPickerCharts from './YearPickerCharts';
import SearchInput from './Input';
import { objectMapper, at, empty } from './../../utils/commons';

import './search.css';

const EditableContext = createContext();
const Option = Select.Option;

/**
 * 搜索表单
 * @property defaultValue { initialValue, fieldProps, hides, shows, sort }
 * * {object} initialValue 默认值
 * * {object} fieldProps 表单项属性
 * * {array} hides 隐藏的表单项
 * * {array} shows 显示的表单项
 * * {object} sort 表单项排序
 * @property onSubmit
 */
export default observer((props) => {
  const { date_picker_store: searchFormStore } = useContext(stores_Context);
  const [form] = Form.useForm();
  const { sort, initialValue, hides, shows, fieldProps } = {
    sort: '',
    initialValue: '',
    fieldProps: '',
    hides: [],
    shows: [],
    ...props.defaultValue,
  };
  const { onSubmit, confirmText } = props;

  const formValuesMapper = (values) => {
    const destinationObject = {
      'DateType': {
        key: 'DateType',
        transform: (value) => value?.key || '',
        default: '',
      },
      'HTBusinessUnits': {
        key: 'HTBusinessUnits',
        transform: (value) => {
          return Array.isArray(value) ? value.map((ele) => ele.key).join(',') : value ? (!isNaN(parseInt(value.key), 10) ? value.key : '') : '';
        },
        default: '',
      },
      'businessUnits': {
        key: 'businessUnits',
        transform: (value) => {
          return Array.isArray(value) ? value.map((ele) => ele.key).join(',') : value ? (!isNaN(parseInt(value.key), 10) ? value.key : '') : '';
        },
        default: '',
      },
      'DepartmentList': {
        key: 'DepartmentList',
        transform: (value) => {
          return Array.isArray(value) ? value.map((ele) => ele.key).join(',') : value ? value.key : '';
        },
        default: '',
      },
      'WebCode': {
        key: 'WebCode',
        transform: (value) => {
          return Array.isArray(value) ? value.map((ele) => ele.key).join(',') : value ? value.key : '';
        },
        default: '',
      },
      'IncludeTickets': {
        key: 'IncludeTickets',
        transform: (value) => value?.key || '',
        default: '',
      },
      'operator': {
        key: 'operator',
        transform: (value) => value?.key || '',
        default: '',
      },
      'applyDate': [
        {
          key: 'Date1',
          transform: (value) => (value === '' || !Array.isArray(value) ? undefined : moment(value[0]).format(DATE_FORMAT)),
          default: '',
        },
        {
          key: 'Date2',
          transform: (value) => (value === '' || !Array.isArray(value) ? undefined : moment(value[1]).format(`${DATE_FORMAT} 23:59:59`)),
          default: '',
        },
      ],
      'applyDate2': [
        {
          key: 'DateDiff1',
          transform: (value) => (value === '' || !Array.isArray(value) ? undefined : value[0] ? moment(value[0]).format(DATE_FORMAT) : undefined),
          default: '',
        },
        {
          key: 'DateDiff2',
          transform: (value) => (value === '' || !Array.isArray(value) ? undefined : value[1] ? moment(value[1]).format(`${DATE_FORMAT} 23:59:59`) : undefined),
          default: '',
        },
      ],
      'year': [
        {
          key: 'Date1',
          transform: (value) => (value ? moment(value).format(`YYYY-01-01`) : undefined),
          default: '',
        },
        {
          key: 'Date2',
          transform: (value) => (value ? moment(value).format(`YYYY-12-31 23:59:59`) : undefined),
          default: '',
        },
      ],
      'yearDiff': [
        {
          key: 'DateDiff1',
          transform: (value) => (value ? moment(value).format(`YYYY-01-01`) : undefined),
          default: '',
        },
        {
          key: 'DateDiff2',
          transform: (value) => (value ? moment(value).format(`YYYY-12-31 23:59:59`) : undefined),
          default: '',
        },
      ],
      'country': {
        key: 'country',
        transform: (value) => value?.key || '',
        default: '',
      },
      'city': {
        key: 'city',
        transform: (value) => value?.key || '',
        default: '',
      },
    };
    let dest = {};
    const { applyDate, applyDate2, year, yearDiff, ...omittedValue } = values;
    dest = { ...omittedValue, ...objectMapper(values, destinationObject) };
    for (const key in dest) {
      if (Object.prototype.hasOwnProperty.call(dest, key)) {
        dest[key] = typeof dest[key] === 'string' ? (dest[key] || '').trim() : dest[key];
      }
    }
    // omit empty
    Object.keys(dest).forEach((key) => (dest[key] == null || dest[key] === '' || dest[key].length === 0) && delete dest[key]);
    return dest;
  };

  const onFinish = (values) => {
    console.log('Received values of form, origin form value: ', values);
    const dest = formValuesMapper(values);
    console.log('form value send to onSubmit:', dest);
    const str = new URLSearchParams(dest).toString();
    searchFormStore.setFormValues(values);
    searchFormStore.setFormValuesToSub(dest);
    if (typeof onSubmit === 'function') {
      onSubmit(null, dest, values, str);
    }
  };

  const onReset = () => {
    form.setFieldsValue({
      // 'DateType': undefined,
    });
  };
  const onValuesChange = (...args) => {
    const [changedValues, allValues] = args;
    // console.log('form onValuesChange', Object.keys(changedValues), args);

    const dest = formValuesMapper(allValues);
    searchFormStore.setFormValues(allValues);
    searchFormStore.setFormValuesToSub(dest);
  };

  return (
    // layout="inline"
    <Form form={form} name="advanced_search" className="orders-search-form" onFinish={onFinish} onValuesChange={onValuesChange}>
      <EditableContext.Provider value={form}>
        <Row gutter={10} style={{ background: '#f9fafa', margin: '0px 0px 10px 0px', padding: '16px 8px' }}>
          {getFields({ sort, initialValue, hides, shows, fieldProps, form })}
          {/* 'textAlign': 'right' */}
          <Col flex="1 0 120px" style={{ padding: '0px 5px' }}>
            <Space align="center">
              <Button size={'middle'} type="primary" icon={<SearchOutlined />} htmlType="submit">
                {confirmText || '统计'}
              </Button>
              {/* <Button size="small" onClick={onReset}>
                重置
              </Button> */}
            </Space>
          </Col>
        </Row>
      </EditableContext.Provider>
    </Form>
  );
});

function getFields(props) {
  const { fieldProps, form } = props;
  const bigCol = 4 * 2;
  const midCol = 6;
  const layoutProps = {
    gutter: { xs: 8, sm: 8, lg: 16 },
    lg: { span: 4 },
    sm: { span: 12 },
    xs: { span: 24 },
  };
  const item = (name, sort = 0, render, col) => {
    const customCol = col || 4;
    return {
      'key': '',
      sort,
      name,
      render,
      'hide': false,
      'col': { lg: { span: customCol } },
    };
  };
  let baseChildren = [];
  baseChildren = [
    item(
      'HTBusinessUnits',
      99,
      <Form.Item name={`HTBusinessUnits`} initialValue={at(props, 'initialValue.HTBusinessUnits')[0] || undefined}>
        <BusinessUnitSelect {...fieldProps.HTBusinessUnits} labelInValue={true} />
      </Form.Item>
    ),
    item(
      'businessUnits',
      99,
      <Form.Item name={`businessUnits`} initialValue={at(props, 'initialValue.businessUnits')[0] || undefined}>
        <BusinessSelect {...fieldProps.businessUnits} labelInValue={true} />
      </Form.Item>
    ),
    item(
      'DepartmentList',
      99,
      <Form.Item name={`DepartmentList`} initialValue={at(props, 'initialValue.DepartmentList')[0] || (fieldProps?.DepartmentList?.show_all ? { key: 'ALL', label: '所有小组' } : undefined)}>
        <GroupSelect {...fieldProps.DepartmentList} labelInValue={true} />
      </Form.Item>
    ),
    item(
      'WebCode',
      99,
      <Form.Item name={`WebCode`} initialValue={at(props, 'initialValue.WebCode')[0] || (fieldProps?.WebCode?.show_all ? { key: 'ALL', label: '所有来源' } : undefined)}>
        <SiteSelect {...fieldProps.WebCode} labelInValue={true} />
      </Form.Item>
    ),
    item(
      'IncludeTickets',
      99,
      //  value={orders_store.include_tickets} onChange={orders_store.handleChange_include_tickets}
      <Form.Item name={`IncludeTickets`} initialValue={at(props, 'initialValue.IncludeTickets')[0] || { key: '1', label: '含门票' }}>
        <Select style={{ width: '100%' }} placeholder="是否含门票" labelInValue>
          <Option key="1" value="1">
            含门票
          </Option>
          <Option key="0" value="0">
            不含门票
          </Option>
        </Select>
      </Form.Item>,
      2
    ),
    //
    item(
      'DateType',
      99,
      <Form.Item name={`DateType`} initialValue={at(props, 'initialValue.DateType')[0] || { key: 'applyDate', label: '提交日期' }}>
        <DateTypeSelect labelInValue={true} />
      </Form.Item>,
      2
    ),
    item(
      'years',
      99,
      <Form.Item>
        {/* <DatePicker picker="year" placeholder='年份' /> */}
        <YearPickerCharts {...fieldProps.years} />
      </Form.Item>,
      2
    ),
    item(
      'months',
      99,
      <Form.Item>
        <DatePicker picker="month" placeholder="月份" />
      </Form.Item>,
      2
    ),
    item(
      'dates',
      99,
      <Form.Item>
        <DatePickerCharts isform={true} {...fieldProps.dates} form={form} />
      </Form.Item>,
      midCol
    ),
    item(
      'operator',
      99,
      <Form.Item name={'operator'} dependencies={['DepartmentList']} >
        <SearchInput
          autoGet
          url="/service-Analyse2/GetOperatorInfo"
          map={{ 'op_id': 'key', 'cn_name': 'label' }}
          resultkey={'result'}
          placeholder="输入搜索顾问: 中/英名字"
          param={{ dept_id: (form.getFieldValue('DepartmentList')?.value || '').replace('ALL', ''), ...(fieldProps?.operator?.param || {}) }}
        />
      </Form.Item>
    ),
    item(
      'country',
      99,
      <Form.Item name={'country'}>
        <SearchInput autoGet url="/service-Analyse2/GetCountryInfo" map={{ 'c_id': 'key', 'cn_name': 'label' }} resultkey={'result'} placeholder="输入搜索国籍: 中/英名字" />
      </Form.Item>
    ),
    item(
      'city',
      99,
      <Form.Item name={'city'}>
        <SearchInput autoGet url="/service-Analyse2/GetDestinationInfo" map={{ 'c_id': 'key', 'cn_name': 'label' }} resultkey={'result'} placeholder="输入搜索城市: 中/英名字" />
      </Form.Item>
    ),
    item(
      'globalCity',
      99,
      <Form.Item name={'globalCity'}>
        <SearchInput autoGet url="/service-Analyse2/GetGlobalDestinationInfo" map={{ 'c_id': 'key', 'cn_name': 'label' }} resultkey={'result'} placeholder="输入搜索城市: 中/英名字" />
      </Form.Item>
    ),
  ];
  baseChildren = baseChildren
    .map((x) => {
      x.hide = false;
      if (props.sort === undefined) {
        return x;
      }
      const tmpSort = props.sort;
      for (const key in tmpSort) {
        if (Object.prototype.hasOwnProperty.call(tmpSort, key)) {
          if (x.name === key) {
            x.sort = tmpSort[key];
          }
        }
      }
      return x;
    })
    .map((x) => {
      if (props.hides.length === 0 && props.shows.length === 0) {
        return x;
      }
      if (props.hides.length === 0) {
        x.hide = !props.shows.includes(x.name);
      } else if (props.shows.length === 0) {
        x.hide = props.hides.includes(x.name);
      }
      return x;
    })
    .filter((x) => !x.hide)
    .sort((a, b) => {
      return a.sort < b.sort ? -1 : 1;
    });
  const children = [];
  const leftStyle = {}; // { borderRight: '1px solid #dedede' };
  for (let i = 0; i < baseChildren.length; i++) {
    let style = { padding: '0px 2px' };
    style = i % 2 === 0 && baseChildren[i].col === 12 ? { ...style, ...leftStyle } : style;
    style = !baseChildren[i].hide ? { ...style, display: 'block' } : { ...style, display: 'none' };
    const Item = (
      <Col key={String(i)} style={style} {...layoutProps} {...baseChildren[i].col}>
        {baseChildren[i].render}
      </Col>
    );
    children.push(Item);
  }
  return children;
}
