import { useEffect, useState, useCallback, useMemo } from 'react';
import {
  Table,
  Button,
  Space,
  Modal,
  Form,
  Select,
  DatePicker,
  TimePicker,
  InputNumber,
  Segmented,
  Spin,
  message,
  Card,
  Row,
  Col,
  Empty,
} from 'antd';
import { PlusOutlined, EditOutlined } from '@ant-design/icons';
import { dayjs } from '../../utils/dayjs';
import type { Dayjs } from 'dayjs';
import {
  appointmentApi,
  type Schedule,
  type CreateScheduleReq,
  type UpdateScheduleReq,
  type CalendarDay,
} from '../../api/health/appointments';
import { DoctorSelect } from './components/DoctorSelect';
import { CalendarView, type ScheduleItem } from './components/CalendarView';
import { StatusTag } from './components/StatusTag';
import { AuthButton } from '../../components/AuthButton';

/** 时段选项 */
const PERIOD_OPTIONS = [
  { value: 'am', label: '上午' },
  { value: 'pm', label: '下午' },
];

const PERIOD_LABEL: Record<string, string> = {
  am: '上午',
  pm: '下午',
};

/** 排班状态选项 */
const SCHEDULE_STATUS_OPTIONS = [
  { value: 'active', label: '启用' },
  { value: 'inactive', label: '停用' },
  { value: 'cancelled', label: '已取消' },
];

export default function DoctorSchedule() {
  // ---- 状态 ----
  const [selectedDoctorId, setSelectedDoctorId] = useState<string | undefined>(undefined);
  const [data, setData] = useState<Schedule[]>([]);
  const [total, setTotal] = useState(0);
  const [page, setPage] = useState(1);
  const [pageSize, setPageSize] = useState(50);
  const [loading, setLoading] = useState(false);

  // 视图模式
  const [viewMode, setViewMode] = useState<string>('列表');

  // 日历数据
  const [calendarData, setCalendarData] = useState<CalendarDay[]>([]);
  const [calendarLoading, setCalendarLoading] = useState(false);

  // 弹窗
  const [modalOpen, setModalOpen] = useState(false);
  const [editing, setEditing] = useState<Schedule | null>(null);
  const [form] = Form.useForm();

  // ---- 列表数据获取 ----
  const fetchSchedules = useCallback(async (p = page, ps = pageSize) => {
    if (!selectedDoctorId) {
      setData([]);
      setTotal(0);
      return;
    }
    setLoading(true);
    try {
      const result = await appointmentApi.listSchedules({
        page: p,
        page_size: ps,
        doctor_id: selectedDoctorId,
      });
      setData(result.data);
      setTotal(result.total);
    } catch {
      message.error('加载排班列表失败');
    } finally {
      setLoading(false);
    }
  }, [page, pageSize, selectedDoctorId]);

  // ---- 日历数据获取 ----
  const [calendarMonth, setCalendarMonth] = useState<Dayjs>(dayjs());

  const fetchCalendar = useCallback(async (month?: Dayjs) => {
    if (!selectedDoctorId) {
      setCalendarData([]);
      return;
    }
    const target = month ?? calendarMonth;
    setCalendarLoading(true);
    try {
      const result = await appointmentApi.calendar({
        start_date: target.startOf('month').format('YYYY-MM-DD'),
        end_date: target.endOf('month').format('YYYY-MM-DD'),
        doctor_id: selectedDoctorId,
      });
      setCalendarData(result);
    } catch {
      message.error('加载日历数据失败');
    } finally {
      setCalendarLoading(false);
    }
  }, [selectedDoctorId, calendarMonth]);

  // 切换医护或视图模式时加载数据
  useEffect(() => {
    if (viewMode === '列表') {
      fetchSchedules();
    } else {
      fetchCalendar();
    }
  }, [fetchSchedules, fetchCalendar, viewMode]);

  // 切换医护时重置页码
  const handleDoctorChange = (val: string) => {
    setSelectedDoctorId(val || undefined);
    setPage(1);
  };

  // ---- 新建 / 编辑排班 ----
  const openCreate = () => {
    setEditing(null);
    form.resetFields();
    form.setFieldsValue({ period_type: 'am', max_appointments: 10 });
    setModalOpen(true);
  };

  const openEdit = (record: Schedule) => {
    setEditing(record);
    form.setFieldsValue({
      schedule_date: dayjs(record.schedule_date),
      period_type: record.period_type,
      start_time: dayjs(record.start_time, 'HH:mm'),
      end_time: dayjs(record.end_time, 'HH:mm'),
      max_appointments: record.max_appointments,
      status: record.status,
    });
    setModalOpen(true);
  };

  const handleSubmit = async (values: {
    schedule_date: Dayjs;
    period_type: string;
    start_time: Dayjs;
    end_time: Dayjs;
    max_appointments: number;
    status?: string;
  }) => {
    if (!selectedDoctorId) {
      message.warning('请先选择医护');
      return;
    }
    try {
      if (editing) {
        const req: UpdateScheduleReq & { version: number } = {
          start_time: values.start_time.format('HH:mm'),
          end_time: values.end_time.format('HH:mm'),
          max_appointments: values.max_appointments,
          status: values.status,
          version: editing.version,
        };
        await appointmentApi.updateSchedule(editing.id, req);
        message.success('排班更新成功');
      } else {
        const req: CreateScheduleReq = {
          doctor_id: selectedDoctorId,
          schedule_date: values.schedule_date.format('YYYY-MM-DD'),
          period_type: values.period_type,
          start_time: values.start_time.format('HH:mm'),
          end_time: values.end_time.format('HH:mm'),
          max_appointments: values.max_appointments,
        };
        await appointmentApi.createSchedule(req);
        message.success('排班创建成功');
      }
      setModalOpen(false);
      form.resetFields();
      if (viewMode === '列表') {
        fetchSchedules(page, pageSize);
      } else {
        fetchCalendar();
      }
    } catch {
      message.error(editing ? '更新排班失败' : '创建排班失败');
    }
  };

  // ---- 列定义 ----
  const columns = useMemo(() => [
    {
      title: '日期',
      dataIndex: 'schedule_date',
      key: 'schedule_date',
      width: 120,
      render: (val: string) => val || '-',
    },
    {
      title: '时段',
      dataIndex: 'period_type',
      key: 'period_type',
      width: 80,
      render: (val: string) => PERIOD_LABEL[val] || val,
    },
    {
      title: '开始时间',
      dataIndex: 'start_time',
      key: 'start_time',
      width: 100,
      render: (val: string) => val || '-',
    },
    {
      title: '结束时间',
      dataIndex: 'end_time',
      key: 'end_time',
      width: 100,
      render: (val: string) => val || '-',
    },
    {
      title: '已约/上限',
      key: 'appointment_ratio',
      width: 110,
      render: (_: unknown, record: Schedule) => {
        const ratio = record.max_appointments > 0
          ? record.current_appointments / record.max_appointments
          : 0;
        const color = ratio >= 1 ? '#ff4d4f' : ratio >= 0.8 ? '#faad14' : '#52c41a';
        return (
          <span style={{ color }}>
            {record.current_appointments}/{record.max_appointments}
          </span>
        );
      },
    },
    {
      title: '状态',
      dataIndex: 'status',
      key: 'status',
      width: 90,
      render: (val: string) => <StatusTag status={val} />,
    },
    {
      title: '操作',
      key: 'action',
      width: 120,
      render: (_: unknown, record: Schedule) => (
        <AuthButton code="health.doctor.manage">
          <Space size="small">
            <Button
              type="link"
              size="small"
              icon={<EditOutlined />}
              onClick={() => openEdit(record)}
            >
              编辑
            </Button>
          </Space>
        </AuthButton>
      ),
    },
  ], [openEdit]);

  // ---- 将日历数据转换为 CalendarView 所需格式 ----
  const calendarScheduleMap: Record<string, ScheduleItem[]> = {};
  for (const day of calendarData) {
    calendarScheduleMap[day.date] = day.schedules.map((s) => ({
      id: s.id,
      start_time: s.start_time,
      end_time: s.end_time,
      current_appointments: s.current_appointments,
      max_appointments: s.max_appointments,
      status: s.status,
    }));
  }

  return (
    <Card>
      {/* 顶部操作栏 */}
      <Row gutter={16} style={{ marginBottom: 16 }} align="middle">
        <Col>
          <Space>
            <span style={{ fontWeight: 500 }}>选择医护:</span>
            <DoctorSelect
              value={selectedDoctorId}
              onChange={handleDoctorChange}
              placeholder="搜索选择医护"
            />
            {selectedDoctorId && (
              <Segmented
                value={viewMode}
                onChange={(val) => setViewMode(val as string)}
                options={['列表', '日历']}
              />
            )}
          </Space>
        </Col>
        <Col flex="auto" />
        <Col>
          {selectedDoctorId && (
            <AuthButton code="health.doctor.manage">
              <Button type="primary" icon={<PlusOutlined />} onClick={openCreate}>
                新建排班
              </Button>
            </AuthButton>
          )}
        </Col>
      </Row>

      {/* 内容区 */}
      {!selectedDoctorId ? (
        <Empty description="请先选择医护以查看排班" />
      ) : viewMode === '列表' ? (
        <Table
          rowKey="id"
          columns={columns}
          dataSource={data}
          loading={loading}
          scroll={{ x: 750 }}
          pagination={{
            current: page,
            pageSize,
            total,
            showSizeChanger: true,
            showTotal: (t) => `共 ${t} 条`,
            onChange: (p, ps) => {
              setPage(p);
              setPageSize(ps);
            },
          }}
        />
      ) : (
        <Spin spinning={calendarLoading}>
          <div style={{ marginTop: 16 }}>
            <CalendarView
              schedules={calendarScheduleMap}
              onPanelChange={(date) => {
                setCalendarMonth(date);
                fetchCalendar(date);
              }}
            />
          </div>
        </Spin>
      )}

      {/* 新建 / 编辑排班弹窗 */}
      <Modal
        title={editing ? '编辑排班' : '新建排班'}
        open={modalOpen}
        onCancel={() => {
          setModalOpen(false);
          form.resetFields();
        }}
        onOk={() => form.submit()}
        destroyOnHidden
        width={520}
      >
        <Form form={form} layout="vertical" onFinish={handleSubmit}>
          <Row gutter={16}>
            <Col span={12}>
              <Form.Item
                name="schedule_date"
                label="排班日期"
                rules={[{ required: true, message: '请选择日期' }]}
              >
                <DatePicker style={{ width: '100%' }} disabled={!!editing} />
              </Form.Item>
            </Col>
            <Col span={12}>
              <Form.Item name="period_type" label="时段" rules={[{ required: true }]}>
                <Select options={PERIOD_OPTIONS} disabled={!!editing} />
              </Form.Item>
            </Col>
          </Row>
          <Row gutter={16}>
            <Col span={12}>
              <Form.Item
                name="start_time"
                label="开始时间"
                rules={[{ required: true, message: '请选择开始时间' }]}
              >
                <TimePicker format="HH:mm" style={{ width: '100%' }} />
              </Form.Item>
            </Col>
            <Col span={12}>
              <Form.Item
                name="end_time"
                label="结束时间"
                rules={[{ required: true, message: '请选择结束时间' }]}
              >
                <TimePicker format="HH:mm" style={{ width: '100%' }} />
              </Form.Item>
            </Col>
          </Row>
          <Row gutter={16}>
            <Col span={12}>
              <Form.Item
                name="max_appointments"
                label="最大预约数"
                rules={[{ required: true, message: '请输入最大预约数' }]}
              >
                <InputNumber min={1} max={200} style={{ width: '100%' }} />
              </Form.Item>
            </Col>
            {editing && (
              <Col span={12}>
                <Form.Item name="status" label="状态">
                  <Select options={SCHEDULE_STATUS_OPTIONS} />
                </Form.Item>
              </Col>
            )}
          </Row>
        </Form>
      </Modal>
    </Card>
  );
}
