import React from 'react';
import cx from 'classnames';
import { isAfter, isBefore, parse } from 'date-fns';
import { getVariable, isEffectiveApi, OptionsControlProps, Payload, OptionsControl, Select } from 'amis';

@OptionsControl({
    test: /(^|\/)course\-list$/,
    name: 'course-list',
})
export class CourseListRenderer extends React.Component<
    OptionsControlProps,
    {
        options: Array<any>;
        selectedOptions: Array<any>;
        selectedProjects: Array<any>;
        selectedClasses: Array<any>;
    }
> {
    constructor(props: OptionsControlProps) {
        super(props);
        this.state = {
            options: [],
            selectedOptions: [],
            selectedProjects: [],
            selectedClasses: [],
        };
    }

    componentDidMount() {
        const { data, value, env, source } = this.props;
        const dateRange = getVariable(data, 'date');
        const startDate = parse(
            dateRange.split(',')[0],
            'yyyy-MM-dd',
            new Date()
        );
        const endDate = parse(
            dateRange.split(',')[1],
            'yyyy-MM-dd',
            new Date()
        );
        let selectedOptions: Array<any> = [];
        if (value) {
            selectedOptions = value.map((item: any) => {
                return {
                    id: item.id,
                    name: item.name,
                    value: item.id,
                    label: item.name,
                    subjectList: item.subjectList.map((sub: any) => {
                        return {
                            value: sub.id,
                            label: sub.name,
                            id: sub.id,
                            name: sub.name,
                            validRoomList: sub.validRoomList
                                ? sub.validRoomList.map((room: any) => {
                                      return {
                                          id: room.id,
                                          name: room.name,
                                          timeslotList: room.timeslotlist
                                              ? room.timeslotlist
                                                    .filter(
                                                        (t: any) =>
                                                            !isBefore(
                                                                parse(
                                                                    t.date,
                                                                    'yyyy-MM-dd',
                                                                    new Date()
                                                                ),
                                                                startDate
                                                            ) &&
                                                            !isAfter(
                                                                parse(
                                                                    t.date,
                                                                    'yyyy-MM-dd',
                                                                    new Date()
                                                                ),
                                                                endDate
                                                            )
                                                    )
                                                    .map((t: any) => {
                                                        return {
                                                            id: t.id,
                                                            date: t.date,
                                                            period: {
                                                                id: t.period.id,
                                                                name: t.period
                                                                    .name,
                                                                startTime:
                                                                    t.period
                                                                        .start_time,
                                                                endTime:
                                                                    t.period
                                                                        .end_time,
                                                            },
                                                        };
                                                    })
                                              : [],
                                      };
                                  })
                                : [],
                            preSubjectList: sub.preSubjectList
                                ? sub.preSubjectList
                                : [],
                        };
                    }),
                    studentGroupList: item.studentGroupList.map((sub: any) => {
                        return {
                            value: sub.id,
                            label: sub.name,
                            id: sub.id,
                            name: sub.name,
                            validTimeslotList: sub.validTimeslotList
                                ? sub.validTimeslotList.filter((t: any) => {
                                      let tDate = parse(
                                          t.date,
                                          'yyyy-MM-dd',
                                          new Date()
                                      );
                                      return (
                                          !isBefore(tDate, startDate) &&
                                          !isAfter(tDate, endDate)
                                      );
                                  })
                                : [],
                        };
                    }),
                };
            });
        }
        if (isEffectiveApi(source)) {
            env.fetcher(source, data).then((payload: Payload) => {
                this.setState({
                    options: payload.data.items.map((item: any) => {
                        return {
                            id: item.id,
                            name: item.name,
                            value: item.id,
                            label: item.name,
                            subjectList: item.course2projects.map(
                                (sub: any) => {
                                    return {
                                        id: sub.projects.id,
                                        name: sub.projects.name,
                                        validRoomList: sub.projects
                                            .validRoomList
                                            ? sub.projects.validRoomList.map(
                                                  (room: any) => {
                                                      return {
                                                          id: room.id,
                                                          name: room.name,
                                                          timeslotList:
                                                              room.timeslotlist
                                                                  ? room.timeslotlist
                                                                        .filter(
                                                                            (
                                                                                t: any
                                                                            ) =>
                                                                                !isBefore(
                                                                                    parse(
                                                                                        t.date,
                                                                                        'yyyy-MM-dd',
                                                                                        new Date()
                                                                                    ),
                                                                                    startDate
                                                                                ) &&
                                                                                !isAfter(
                                                                                    parse(
                                                                                        t.date,
                                                                                        'yyyy-MM-dd',
                                                                                        new Date()
                                                                                    ),
                                                                                    endDate
                                                                                )
                                                                        )
                                                                        .map(
                                                                            (
                                                                                t: any
                                                                            ) => {
                                                                                return {
                                                                                    id: t.id,
                                                                                    date: t.date,
                                                                                    period: {
                                                                                        id: t
                                                                                            .period
                                                                                            .id,
                                                                                        name: t
                                                                                            .period
                                                                                            .name,
                                                                                        startTime:
                                                                                            t
                                                                                                .period
                                                                                                .start_time,
                                                                                        endTime:
                                                                                            t
                                                                                                .period
                                                                                                .end_time,
                                                                                    },
                                                                                };
                                                                            }
                                                                        )
                                                                  : [],
                                                      };
                                                  }
                                              )
                                            : [],
                                        preSubjectList: sub.projects
                                            .preSubjectList
                                            ? sub.projects.preSubjectList
                                            : [],
                                        value: sub.projects.id,
                                        label: sub.projects.name,
                                    };
                                }
                            ),
                            studentGroupList: item.course2orgs.map(
                                (sub: any) => {
                                    return {
                                        id: sub.orgs.id,
                                        name: sub.orgs.name,
                                        validTimeslotList: sub.orgs
                                            .validTimeslotList
                                            ? sub.orgs.validTimeslotList.filter(
                                                  (t: any) => {
                                                      let tDate = parse(
                                                          t.date,
                                                          'yyyy-MM-dd',
                                                          new Date()
                                                      );
                                                      return (
                                                          !isBefore(
                                                              tDate,
                                                              startDate
                                                          ) &&
                                                          !isAfter(
                                                              tDate,
                                                              endDate
                                                          )
                                                      );
                                                  }
                                              )
                                            : [],
                                        value: sub.orgs.id,
                                        label: sub.orgs.name,
                                    };
                                }
                            ),
                        };
                    }),
                    selectedOptions: selectedOptions,
                });
            });
        }
    }

    handleClick(option: any, e: React.MouseEvent<HTMLElement>) {
        if (e.target && (e.target as HTMLElement).closest('a,button')) {
            return;
        }

        const { onChange } = this.props;
        let index = this.state.selectedOptions.findIndex(
            (item: any) => item.value === option.value
        );
        let newOptions = Object.assign([], this.state.selectedOptions);
        if (index === -1) {
            newOptions.push(option);
            this.setState({
                selectedOptions: newOptions,
            });
        } else {
            newOptions.splice(index, 1);
            this.setState({
                selectedOptions: newOptions,
            });
        }
        onChange(newOptions);
    }

    render() {
        const { placeholder, className, onChange } = this.props;

        const { options, selectedOptions } = this.state;

        let body: JSX.Element | null = null;
        if (options && options.length) {
            body = (
                <div>
                    <div className={cx('a-ListControl-items')}>
                        {options.map((option, key) => (
                            <div
                                key={key}
                                className={cx(`a-ListControl-item`, 'w-full', {
                                    'is-active':
                                        selectedOptions.findIndex(
                                            (o: any) => o.value === option.value
                                        ) !== -1,
                                    'is-disabled': option.disabled,
                                })}
                                style={{ maxWidth: '100%' }}
                                onClick={this.handleClick.bind(this, option)}
                            >
                                {option.label}
                            </div>
                        ))}
                    </div>
                    <div className={`m-t-md`}>
                        {selectedOptions.map((option, key) => {
                            let optionData = options.find(
                                (item: any) => item.value === option.value
                            );
                            return (
                                <div
                                    key={key}
                                    className={cx('w-full', 'm-t-xs')}
                                >
                                    <div>{optionData.label}</div>
                                    <Select
                                        multiple
                                        clearable={false}
                                        joinValues
                                        defaultCheckAll
                                        className={`w-full m-xs`}
                                        options={optionData.subjectList}
                                        onChange={(value: any) => {
                                            option.subjectList = value;
                                            onChange(
                                                this.state.selectedOptions
                                            );
                                        }}
                                    />
                                    <Select
                                        multiple
                                        clearable={false}
                                        joinValues
                                        defaultCheckAll
                                        className={`w-full m-xs`}
                                        options={optionData.studentGroupList}
                                        onChange={(value: any) => {
                                            option.studentGroupList = value;
                                            onChange(
                                                this.state.selectedOptions
                                            );
                                        }}
                                    />
                                </div>
                            );
                        })}
                    </div>
                </div>
            );
        }

        return (
            <div className={cx('a-ListControl', className)}>
                {body ? (
                    body
                ) : (
                    <span className={cx('a-ListControl-placeholder')}>
                        {placeholder}
                    </span>
                )}
            </div>
        );
    }
}
