import { useState, useCallback, useEffect, useMemo } from 'react';
import { useSearchParams } from 'react-router-dom';
import {
  Table,
  Button,
  Space,
  Modal,
  Form,
  Select,
  DatePicker,
  TimePicker,
  Input,
  Dropdown,
  message,
  Alert,
} from 'antd';
import {
  PlusOutlined,
  DownOutlined,
} from '@ant-design/icons';
import type { Dayjs } from 'dayjs';
import { appointmentApi, type Appointment, type CreateAppointmentReq } from '../../api/health/appointments';
import { StatusTag } from './components/StatusTag';
import { PatientSelect } from './components/PatientSelect';
import { DoctorSelect } from './components/DoctorSelect';
import { AuthButton } from '../../components/AuthButton';
import { PageContainer } from '../../components/PageContainer';
import { DrawerForm } from '../../components/DrawerForm';
import { EntityName } from '../../components/EntityName';
import { formatDateTime } from '../../utils/format';
import { usePaginatedData } from '../../hooks/usePaginatedData';
import { useApiRequest } from '../../hooks/useApiRequest';

/** 预约类型选项 */
const APPOINTMENT_TYPE_OPTIONS = [
  { value: 'outpatient', label: '门诊' },
  { value: 'recheck', label: '复诊' },
  { value: 'health_checkup', label: '体检' },
  { value: 'consultation', label: '咨询' },
  { value: 'dialysis', label: '透析' },
];

const APPOINTMENT_TYPE_MAP: Record<string, string> = {
  outpatient: '门诊',
  recheck: '复诊',
  health_checkup: '体检',
  consultation: '咨询',
  dialysis: '透析',
  follow_up: '随访',
};

/** 状态筛选选项 */
const STATUS_OPTIONS = [
  { value: 'pending', label: '待确认' },
  { value: 'confirmed', label: '已确认' },
  { value: 'completed', label: '已完成' },
  { value: 'cancelled', label: '已取消' },
  { value: 'no_show', label: '未到诊' },
];

/** 状态流转规则 */
const STATUS_TRANSITIONS: Record<string, { value: string; label: string }[]> = {
  pending: [
    { value: 'confirmed', label: '确认' },
    { value: 'cancelled', label: '取消' },
  ],
  confirmed: [
    { value: 'completed', label: '完成' },
    { value: 'no_show', label: '未到诊' },
    { value: 'cancelled', label: '取消' },
  ],
  completed: [],
  cancelled: [],
  no_show: [
    { value: 'confirmed', label: '重新确认' },
  ],
};

/** 筛选器类型 */
interface AppointmentFilters {
  status: string | undefined;
  dateRange: [Dayjs | null, Dayjs | null] | null;
  patientSearch: string;
  appointmentType: string | undefined;
}

export default function AppointmentList() {
  const [searchParams] = useSearchParams();
  const urlPatientId = searchParams.get('patient_id');
  const [drawerOpen, setDrawerOpen] = useState(false);
  const [submitting, setSubmitting] = useState(false);

  // 患者选择状态（受控组件，不挂在 Form.Item 上）
  const [selectedPatientId, setSelectedPatientId] = useState<string | undefined>(undefined);
  const [selectedDoctorId, setSelectedDoctorId] = useState<string | undefined>(undefined);

  // 排班校验
  const [scheduleHint, setScheduleHint] = useState<string | null>(null);
  const [selectedDate, setSelectedDate] = useState<string | null>(null);

  // ---- 数据获取 ----
  const fetcher = useCallback(
    async (page: number, pageSize: number, filters: AppointmentFilters) => {
      const dateStart = filters.dateRange?.[0]?.format('YYYY-MM-DD');
      const dateEnd = filters.dateRange?.[1]?.format('YYYY-MM-DD');
      return appointmentApi.list({
        page,
        page_size: pageSize,
        status: filters.status || undefined,
        date: dateStart === dateEnd ? dateStart : undefined,
        patient_id: urlPatientId || undefined,
        search: filters.patientSearch || undefined,
        appointment_type: filters.appointmentType || undefined,
      });
    },
    [urlPatientId],
  );

  const {
    data,
    total,
    page,
    loading,
    filters,
    setFilters,
    refresh,
  } = usePaginatedData<Appointment, AppointmentFilters>(fetcher, {
    pageSize: 20,
    defaultFilters: {
      status: undefined,
      dateRange: null,
      patientSearch: '',
      appointmentType: undefined,
    },
  });

  const { execute } = useApiRequest();

  const handleFilterChange = useCallback(
    (key: keyof AppointmentFilters, value: unknown) => {
      setFilters((prev) => ({ ...prev, [key]: value }));
      refresh(1);
    },
    [setFilters, refresh],
  );

  const resetFilters = useCallback(() => {
    setFilters({
      status: undefined,
      dateRange: null,
      patientSearch: '',
      appointmentType: undefined,
    });
    refresh(1);
  }, [setFilters, refresh]);

  // ---- 状态变更 ----
  const DESTRUCTIVE_STATUSES = new Set(['cancelled', 'no_show']);

  const handleStatusChange = (record: Appointment, newStatus: string) => {
    const transition = STATUS_TRANSITIONS[record.status]?.find((t) => t.value === newStatus);
    if (!transition) return;

    if (DESTRUCTIVE_STATUSES.has(newStatus)) {
      let cancelReason = '';
      Modal.confirm({
        title: `确认${transition.label}`,
        content: newStatus === 'cancelled' ? (
          <Input.TextArea
            rows={3}
            placeholder="请输入取消原因"
            onChange={(e) => { cancelReason = e.target.value; }}
          />
        ) : (
          <span>确定将此预约标记为"{transition.label}"？</span>
        ),
        okText: '确认',
        cancelText: '取消',
        onOk: async () => {
          const result = await execute(
            () => appointmentApi.updateStatus(record.id, {
              status: newStatus,
              version: record.version,
              ...(newStatus === 'cancelled' && { cancel_reason: cancelReason }),
            }),
            '状态更新成功',
          );
          if (result !== null) refresh();
        },
      });
    } else {
      Modal.confirm({
        title: `确认${transition.label}`,
        content: `确定将此预约状态变更为"${transition.label}"？`,
        okText: '确认',
        cancelText: '取消',
        onOk: async () => {
          const result = await execute(
            () => appointmentApi.updateStatus(record.id, {
              status: newStatus,
              version: record.version,
            }),
            '状态更新成功',
          );
          if (result !== null) refresh();
        },
      });
    }
  };

  // ---- 新建预约 ----
  const openCreate = () => {
    setSelectedPatientId(undefined);
    setSelectedDoctorId(undefined);
    setScheduleHint(null);
    setSelectedDate(null);
    setDrawerOpen(true);
  };

  // 排班校验：医生 + 日期选定后查询排班
  useEffect(() => {
    if (!selectedDoctorId || !selectedDate || !drawerOpen) {
      // eslint-disable-next-line react-hooks/set-state-in-effect
      setScheduleHint(null);
      return;
    }
    let cancelled = false;
    appointmentApi.listSchedules({ doctor_id: selectedDoctorId, date: selectedDate, page: 1, page_size: 50 })
      .then((result) => {
        if (cancelled) return;
        const schedules = result.data;
        if (schedules.length === 0) {
          setScheduleHint(`该医生在 ${selectedDate} 暂无排班，请确认是否需要先创建排班`);
        } else {
          const slots = schedules
            .filter((s) => s.status === 'enabled' && s.current_appointments < s.max_appointments)
            .map((s) => `${s.start_time}-${s.end_time}(${s.current_appointments}/${s.max_appointments})`)
            .join('、');
          setScheduleHint(slots ? `可约时段：${slots}` : `该医生在 ${selectedDate} 排班已满或已停用`);
        }
      })
      .catch(() => { if (!cancelled) setScheduleHint(null); });
    return () => { cancelled = true; };
  }, [selectedDoctorId, selectedDate, drawerOpen]);

  const handleSubmit = async (values: Record<string, unknown>) => {
    if (!selectedPatientId) {
      message.warning('请选择患者');
      return;
    }
    if (!selectedDoctorId) {
      message.warning('请选择医护');
      return;
    }
    setSubmitting(true);
    const req: CreateAppointmentReq = {
      patient_id: selectedPatientId,
      doctor_id: selectedDoctorId,
      appointment_date: (values.appointment_date as Dayjs).format('YYYY-MM-DD'),
      start_time: (values.start_time as Dayjs).format('HH:mm'),
      end_time: (values.end_time as Dayjs).format('HH:mm'),
      appointment_type: (values.appointment_type as string) || 'outpatient',
      notes: (values.notes as string) || undefined,
    };
    const result = await execute(
      () => appointmentApi.create(req),
      '预约创建成功',
    );
    setSubmitting(false);
    if (result !== null) {
      setDrawerOpen(false);
      setSelectedPatientId(undefined);
      setSelectedDoctorId(undefined);
      refresh();
    }
  };

  // ---- 列定义 ----
  const columns = useMemo(() => [
    {
      title: '患者',
      dataIndex: 'patient_name',
      key: 'patient_name',
      width: 100,
      render: (_: unknown, record: Appointment) => (
        <EntityName name={record.patient_name} id={record.patient_id} />
      ),
    },
    {
      title: '医护',
      dataIndex: 'doctor_name',
      key: 'doctor_name',
      width: 100,
      render: (_: unknown, record: Appointment) => (
        <EntityName name={record.doctor_name} id={record.doctor_id} />
      ),
    },
    {
      title: '预约类型',
      dataIndex: 'appointment_type',
      key: 'appointment_type',
      width: 90,
      render: (val: string) => APPOINTMENT_TYPE_MAP[val] || val,
    },
    {
      title: '预约日期',
      dataIndex: 'appointment_date',
      key: 'appointment_date',
      width: 120,
      render: (val: string) => val || '-',
    },
    {
      title: '时段',
      key: 'time_range',
      width: 120,
      render: (_: unknown, record: Appointment) =>
        record.start_time && record.end_time
          ? `${record.start_time} - ${record.end_time}`
          : '-',
    },
    {
      title: '状态',
      dataIndex: 'status',
      key: 'status',
      width: 100,
      render: (val: string) => <StatusTag status={val} />,
    },
    {
      title: '创建时间',
      dataIndex: 'created_at',
      key: 'created_at',
      width: 180,
      render: (val: string) => formatDateTime(val),
    },
    {
      title: '备注',
      dataIndex: 'notes',
      key: 'notes',
      width: 180,
      ellipsis: true,
      render: (val: string) => val || '-',
    },
    {
      title: '操作',
      key: 'action',
      width: 100,
      fixed: 'right' as const,
      render: (_: unknown, record: Appointment) => {
        const transitions = STATUS_TRANSITIONS[record.status] || [];
        if (transitions.length === 0) {
          return <span style={{ color: '#999' }}>无可用操作</span>;
        }
        return (
          <AuthButton code="health.appointment.manage">
            <Dropdown
              menu={{
                items: transitions.map((t) => ({
                  key: t.value,
                  label: t.label,
                  onClick: () => handleStatusChange(record, t.value),
                })),
              }}
            >
              <Button type="link" size="small">
                状态变更 <DownOutlined />
              </Button>
            </Dropdown>
          </AuthButton>
        );
      },
    },
  ], [handleStatusChange]);

  return (
    <PageContainer
      title="预约管理"
      filters={
        <Space wrap>
          <Select
            placeholder="筛选状态"
            value={filters.status}
            onChange={(val) => handleFilterChange('status', val)}
            options={STATUS_OPTIONS}
            allowClear
            style={{ width: 140 }}
          />
          <DatePicker.RangePicker
            value={filters.dateRange as [Dayjs, Dayjs] | null}
            onChange={(dates) => handleFilterChange('dateRange', dates)}
            placeholder={['开始日期', '结束日期']}
            allowClear
          />
          <Input
            placeholder="搜索患者"
            value={filters.patientSearch}
            onChange={(e) => handleFilterChange('patientSearch', e.target.value)}
            allowClear
            style={{ width: 180 }}
          />
          <Select
            placeholder="预约类型"
            value={filters.appointmentType}
            onChange={(val) => handleFilterChange('appointmentType', val)}
            options={APPOINTMENT_TYPE_OPTIONS}
            allowClear
            style={{ width: 120 }}
          />
        </Space>
      }
      onResetFilters={resetFilters}
      actions={
        <AuthButton code="health.appointment.manage">
          <Button type="primary" icon={<PlusOutlined />} onClick={openCreate}>
            新建预约
          </Button>
        </AuthButton>
      }
    >
      <Table
        rowKey="id"
        columns={columns}
        dataSource={data}
        loading={loading}
        scroll={{ x: 1200 }}
        pagination={{
          current: page,
          pageSize: 20,
          total,
          showSizeChanger: true,
          showTotal: (t) => `共 ${t} 条`,
          onChange: (p) => refresh(p),
        }}
      />

      {/* 新建预约弹窗 */}
      <DrawerForm
        title="新建预约"
        open={drawerOpen}
        onClose={() => {
          setDrawerOpen(false);
          setSelectedPatientId(undefined);
          setSelectedDoctorId(undefined);
          setScheduleHint(null);
        }}
        onSubmit={handleSubmit}
        loading={submitting}
        width={640}
        columns={2}
        initialValues={{ appointment_type: 'outpatient' }}
        sections={[
          {
            title: '患者信息',
            fields: (
              <>
                <Form.Item label="患者" required>
                  <PatientSelect
                    value={selectedPatientId}
                    onChange={(val) => setSelectedPatientId(val)}
                    placeholder="搜索选择患者"
                  />
                </Form.Item>
                <Form.Item name="appointment_type" label="预约类型" initialValue="outpatient">
                  <Select options={APPOINTMENT_TYPE_OPTIONS} />
                </Form.Item>
                <Form.Item
                  name="appointment_date"
                  label="预约日期"
                  rules={[{ required: true, message: '请选择预约日期' }]}
                >
                  <DatePicker style={{ width: '100%' }} onChange={(d) => setSelectedDate(d ? d.format('YYYY-MM-DD') : null)} />
                </Form.Item>
              </>
            ),
          },
          {
            title: '医生与排班',
            fields: (
              <>
                <Form.Item label="医护" required>
                  <DoctorSelect
                    value={selectedDoctorId}
                    onChange={(val) => setSelectedDoctorId(val)}
                    placeholder="搜索选择医护"
                  />
                </Form.Item>
                <Form.Item
                  name="start_time"
                  label="开始时间"
                  rules={[{ required: true, message: '请选择开始时间' }]}
                >
                  <TimePicker format="HH:mm" style={{ width: '100%' }} />
                </Form.Item>
                <Form.Item
                  name="end_time"
                  label="结束时间"
                  rules={[{ required: true, message: '请选择结束时间' }]}
                >
                  <TimePicker format="HH:mm" style={{ width: '100%' }} />
                </Form.Item>
                {scheduleHint && (
                  <Alert
                    message={scheduleHint}
                    type={scheduleHint.includes('暂无排班') ? 'warning' : 'info'}
                    showIcon
                    style={{ marginBottom: 16, gridColumn: '1 / -1' }}
                  />
                )}
              </>
            ),
          },
          {
            title: '备注',
            fields: (
              <Form.Item name="notes" label="备注" style={{ gridColumn: '1 / -1' }}>
                <Input.TextArea rows={3} placeholder="预约备注信息" />
              </Form.Item>
            ),
          },
        ]}
      />
    </PageContainer>
  );
}
