import {
  MyButtons,
  MyModalFormProps,
  MyPageContainer,
  rulesHelper,
} from '@/common';
import { Selects } from '@/components/Select';
import { Apis } from '@/gen/Apis';
import {
  BetaSchemaForm,
  EditableProTable,
  ProCard,
} from '@ant-design/pro-components';
import { useNavigate } from '@umijs/max';
import { Form, message, Space } from 'antd';
import dayjs from 'dayjs';
import { useCallback, useMemo, useRef, useState } from 'react';

interface SchedulePerson {
  id: number;
  name: string;
  [date: string]: any;
}

interface ScheduleItem {
  company_employees_id: number;
  attendance_shifts_id: number;
  schedule_date: string;
  status: string;
}

const BASE_COLUMNS = [
  { title: '员工ID', dataIndex: 'id', readonly: true },
  { title: '员工', dataIndex: 'name', readonly: true },
];

export default function Index({ title = '批量排班' }) {
  const [form] = Form.useForm();
  const navigate = useNavigate();

  const [originalData, setOriginalData] = useState<SchedulePerson[]>([]);
  const [dataSource, setDataSource] = useState<SchedulePerson[]>([]);
  const [fetchLoading, setFetchLoading] = useState(false);
  const [scheduleDate, setScheduleDate] = useState<string>('');
  const shiftOptionsRef = useRef<any[]>([]);

  // 动态提取日期（排除 id 和 name 字段）
  const extractDates = useCallback((data: SchedulePerson[]): string[] => {
    if (!data || data.length === 0) return [];
    const firstPerson = data[0];
    return Object.keys(firstPerson).filter(
      (key) => key !== 'id' && key !== 'name' && !isNaN(Date.parse(key)),
    );
  }, []);

  // 获取班次选项（组件内缓存，不会跨实例共享）
  const getShiftOptions = useCallback(async (keywords?: string) => {
    if (shiftOptionsRef.current.length) {
      return shiftOptionsRef.current;
    }
    const res = await Apis.Attendance.AttendanceShifts.Select({
      name: keywords || undefined,
    });
    const options = [...(res?.data || []), { id: -1, name: '休息' }];
    shiftOptionsRef.current = options;
    return options;
  }, []);

  // 生成未来 7 天的列配置（缓存避免每次渲染重建）
  const scheduleColumns = useMemo(() => {
    if (!scheduleDate) return BASE_COLUMNS;
    const start = dayjs(scheduleDate);
    const dateColumns = [];
    for (let i = 0; i < 7; i++) {
      const currentDate = start.clone().add(i, 'day').format('YYYY-MM-DD');
      dateColumns.push({
        title: currentDate,
        key: currentDate,
        dataIndex: currentDate,
        formItemProps: { ...rulesHelper.number },
        valueType: 'select',
        request: async (params: any) => getShiftOptions(params?.keyWords),
        fieldProps: {
          showSearch: true,
          allowClear: false,
          fieldNames: { label: 'name', value: 'id' },
        },
      });
    }
    return [...BASE_COLUMNS, ...dateColumns];
  }, [scheduleDate, getShiftOptions]);

  // 将排班数据转换为提交格式
  const transformScheduleData = useCallback(
    (
      data: SchedulePerson[],
      originals: SchedulePerson[],
      dates: string[],
    ): ScheduleItem[] => {
      return data.flatMap((person) =>
        dates.map((date) => {
          let shiftId = person[date];
          // 如果选的是休息(-1)，回查原始排班数据
          if (shiftId === -1) {
            const originalPerson = originals.find(
              (item) => item.id === person.id,
            );
            shiftId = originalPerson?.[date] ?? 0;
          }
          return {
            company_employees_id: person.id,
            attendance_shifts_id: shiftId || 0,
            schedule_date: date,
            status: person[date] < 0 ? 'Cancelled' : '',
          };
        }),
      );
    },
    [],
  );

  // 获取人员信息
  const handleFetchEmployees = useCallback(() => {
    const organizations_id = form.getFieldValue('organizations_id');
    const date = form.getFieldValue('schedule_date');

    if (!organizations_id?.length) {
      message.warning('请先选择组织');
      return;
    }
    if (!date) {
      message.warning('请先选择开始日期');
      return;
    }

    setFetchLoading(true);
    Apis.Attendance.AttendanceSchedules.ShiftList({
      schedule_date: date,
      organizations_id: organizations_id[organizations_id.length - 1],
    })
      .then((res) => {
        const list = JSON.parse(JSON.stringify(res?.data || []));
        setOriginalData(list);
        setDataSource(list);
        setScheduleDate(date);
        shiftOptionsRef.current = [];
      })
      .finally(() => setFetchLoading(false));
  }, [form]);

  return (
    <MyPageContainer
      title={
        <Space style={{ cursor: 'pointer' }} onClick={() => navigate(-1)}>
          {title}
        </Space>
      }
      enableTabs={false}
      tabKey="charge-standards-create"
      tabLabel={title}
    >
      <ProCard>
        <div
          style={{
            maxWidth: 1200,
            minHeight: '83vh',
            margin: '0 auto',
          }}
        >
          <BetaSchemaForm
            {...MyModalFormProps.props}
            title={title}
            layoutType="Form"
            labelCol={{ span: 24 }}
            wrapperCol={{ span: 24 }}
            labelAlign="left"
            width="900px"
            form={form}
            onValuesChange={(changedValues) => {
              if (changedValues.schedule_date !== undefined) {
                setScheduleDate(changedValues.schedule_date);
              }
            }}
            submitter={{
              render: (props) => [
                <MyButtons.Default
                  key="submit"
                  size="middle"
                  type="primary"
                  onClick={() => props.submit()}
                  title="提交保存"
                />,
              ],
            }}
            onFinish={async () => {
              try {
                const dates = extractDates(dataSource);
                const transformedData = transformScheduleData(
                  dataSource,
                  originalData,
                  dates,
                );
                const filteredData = transformedData.filter(
                  (item) =>
                    item.attendance_shifts_id !== null &&
                    item.attendance_shifts_id !== 0,
                );

                await Apis.Attendance.AttendanceSchedules.BatchStore({
                  schedules: filteredData,
                });
                message.success('提交成功');
                navigate(-1);
              } catch {
                return false;
              }
            }}
            columns={[
              Selects?.OrganizationsTree({
                title: '第一步：选择组织',
                key: 'organizations_id',
                colProps: { span: 24 },
                formItemProps: { ...rulesHelper.text },
              }),
              {
                title: '第二步：选择开始日期',
                tooltip: '排班开始日期，最大排班日期为当前日期',
                key: 'schedule_date',
                valueType: 'date',
                fieldProps: {
                  format: 'YYYY-MM-DD',
                  style: { width: '100%' },
                },
                colProps: { span: 24 },
                formItemProps: { ...rulesHelper.text },
              },
              {
                valueType: 'dependency',
                name: ['organizations_id', 'schedule_date'],
                colProps: { span: 24 },
                columns: () => {
                  return [
                    {
                      renderFormItem: () => (
                        <MyButtons.Default
                          type="primary"
                          size="middle"
                          title="第三步：获取人员信息"
                          style={{ width: '100%' }}
                          loading={fetchLoading}
                          onClick={handleFetchEmployees}
                        />
                      ),
                    },
                    {
                      renderFormItem: () => (
                        <ProCard bordered size="small">
                          <EditableProTable<SchedulePerson>
                            headerTitle="第四步：设置员工班次（按周）"
                            bordered
                            recordCreatorProps={false}
                            columns={scheduleColumns}
                            rowKey="id"
                            value={dataSource}
                            onChange={(values) => {
                              setDataSource(values as SchedulePerson[]);
                            }}
                            editable={{
                              type: 'multiple',
                              editableKeys: dataSource?.map((item) => item?.id),
                              onValuesChange: (record, recordList) => {
                                setDataSource(recordList as SchedulePerson[]);
                              },
                              onSave: async () => {},
                            }}
                          />
                        </ProCard>
                      ),
                    },
                  ];
                },
              },
            ]}
          />
        </div>
      </ProCard>
    </MyPageContainer>
  );
}
