import { useState } from 'react';
import {
  Avatar,
  Button,
  Checkbox,
  Descriptions,
  Form,
  Input,
  InputNumber,
  Modal,
  Popconfirm,
  Select,
  Space,
  Switch,
  Table,
  Tag,
  Typography,
  message,
} from 'antd';
import type { ColumnsType } from 'antd/es/table';
import {
  WECOM_PUSH_CONDITION_GROUPS,
  WECOM_PUSH_CONDITION_LABELS,
  type WecomMessagePushDto,
  type WecomPushCondition,
} from '@dukang/shared-types';
import { request } from '../lib/api';
import { fmtTime } from '../lib/constants';
import { useAdminList } from '../lib/useAdminList';
import OssUpload from '../components/OssUpload';

type FormValues = {
  name: string;
  avatarUrl?: string;
  webhookUrl: string;
  enabled: boolean;
  mentionWecomUserId?: string;
  pushConditions: WecomPushCondition[];
  sortOrder: number;
};

function WecomPushConditionPicker({
  value,
  onChange,
}: {
  value?: WecomPushCondition[];
  onChange?: (next: WecomPushCondition[]) => void;
}) {
  const selected = new Set(value ?? []);

  function toggle(cond: WecomPushCondition, checked: boolean) {
    const next = new Set(selected);
    if (checked) next.add(cond);
    else next.delete(cond);
    onChange?.([...next]);
  }

  return (
    <div style={{ width: '100%' }}>
      {WECOM_PUSH_CONDITION_GROUPS.map((group) => (
        <div key={group.key} style={{ marginBottom: 12 }}>
          <Typography.Text strong>{group.label}</Typography.Text>
          <div style={{ marginTop: 8 }}>
            {group.conditions.map((c) => (
              <div key={c}>
                <Checkbox
                  checked={selected.has(c)}
                  onChange={(e) => toggle(c, e.target.checked)}
                >
                  {WECOM_PUSH_CONDITION_LABELS[c]}
                </Checkbox>
              </div>
            ))}
          </div>
        </div>
      ))}
    </div>
  );
}

export default function WecomMessagePushesPage() {
  const [filterForm] = Form.useForm();
  const [form] = Form.useForm<FormValues>();
  const [filters, setFilters] = useState<Record<string, string>>({});
  const [modalOpen, setModalOpen] = useState(false);
  const [editing, setEditing] = useState<WecomMessagePushDto | null>(null);
  const [saving, setSaving] = useState(false);
  const [detail, setDetail] = useState<WecomMessagePushDto | null>(null);
  const [testingId, setTestingId] = useState<string | null>(null);

  const { data, loading, page, pageSize, setPage, setPageSize, reload } =
    useAdminList<WecomMessagePushDto>(
      '/admin/wecom-message-pushes',
      () => {
        const qs = new URLSearchParams();
        if (filters.name) qs.set('name', filters.name);
        if (filters.enabled) qs.set('enabled', filters.enabled);
        return qs;
      },
      [filters],
    );

  const conditionsWatch = Form.useWatch('pushConditions', form) as WecomPushCondition[] | undefined;

  function openCreate() {
    setEditing(null);
    form.resetFields();
    form.setFieldsValue({
      enabled: true,
      pushConditions: ['alert.ops'],
      sortOrder: 0,
    });
    setModalOpen(true);
  }

  function openEdit(row: WecomMessagePushDto) {
    setEditing(row);
    form.setFieldsValue({
      name: row.name,
      avatarUrl: row.avatarUrl ?? undefined,
      webhookUrl: row.webhookUrl,
      enabled: row.enabled,
      mentionWecomUserId: row.mentionWecomUserId ?? undefined,
      pushConditions: row.pushConditions,
      sortOrder: row.sortOrder,
    });
    setModalOpen(true);
  }

  async function save() {
    const values = await form.validateFields();
    setSaving(true);
    try {
      const body = {
        name: values.name,
        avatarUrl: values.avatarUrl || null,
        webhookUrl: values.webhookUrl,
        enabled: values.enabled,
        mentionWecomUserId: values.mentionWecomUserId?.trim() || null,
        pushConditions: values.pushConditions,
        sortOrder: values.sortOrder ?? 0,
      };
      if (editing) {
        await request(`/admin/wecom-message-pushes/${editing.id}`, {
          method: 'PUT',
          body: JSON.stringify(body),
        });
        message.success('已更新');
      } else {
        await request('/admin/wecom-message-pushes', {
          method: 'POST',
          body: JSON.stringify(body),
        });
        message.success('已创建');
      }
      setModalOpen(false);
      reload();
    } catch (e) {
      message.error(e instanceof Error ? e.message : '保存失败');
    } finally {
      setSaving(false);
    }
  }

  async function remove(id: string) {
    try {
      await request(`/admin/wecom-message-pushes/${id}`, { method: 'DELETE' });
      message.success('已删除');
      reload();
    } catch (e) {
      message.error(e instanceof Error ? e.message : '删除失败');
    }
  }

  async function testPush(id: string) {
    setTestingId(id);
    try {
      const res = await request<{ ok: boolean; message: string }>(
        `/admin/wecom-message-pushes/${id}/test`,
        { method: 'POST', body: '{}' },
      );
      message.success(res.message || '已发送测试消息');
    } catch (e) {
      message.error(e instanceof Error ? e.message : '测试失败');
    } finally {
      setTestingId(null);
    }
  }

  const columns: ColumnsType<WecomMessagePushDto> = [
    {
      title: '名称',
      dataIndex: 'name',
      render: (name: string, row) => (
        <Space>
          <Avatar src={row.avatarUrl ?? undefined}>{name.slice(0, 1)}</Avatar>
          <span>{name}</span>
        </Space>
      ),
    },
    {
      title: 'Webhook',
      dataIndex: 'webhookUrlMasked',
      ellipsis: true,
    },
    {
      title: '推送条件',
      dataIndex: 'pushConditions',
      render: (conds: WecomPushCondition[]) =>
        conds.map((c) => (
          <Tag key={c} style={{ marginBottom: 4 }}>
            {WECOM_PUSH_CONDITION_LABELS[c]}
          </Tag>
        )),
    },
    {
      title: '启用',
      dataIndex: 'enabled',
      width: 72,
      render: (v: boolean) => (v ? <Tag color="green">是</Tag> : <Tag>否</Tag>),
    },
    { title: '排序', dataIndex: 'sortOrder', width: 64 },
    {
      title: '操作',
      key: 'actions',
      width: 220,
      render: (_, row) => (
        <Space wrap>
          <Button type="link" size="small" onClick={() => openEdit(row)}>
            编辑
          </Button>
          <Button
            type="link"
            size="small"
            loading={testingId === row.id}
            onClick={() => void testPush(row.id)}
          >
            测试
          </Button>
          <Button
            type="link"
            size="small"
            onClick={() => {
              void request<WecomMessagePushDto>(`/admin/wecom-message-pushes/${row.id}`).then(setDetail);
            }}
          >
            详情
          </Button>
          <Popconfirm title="确认删除？" onConfirm={() => void remove(row.id)}>
            <Button type="link" size="small" danger>
              删除
            </Button>
          </Popconfirm>
        </Space>
      ),
    },
  ];

  return (
    <div>
      <Typography.Title level={4}>企微机器人 · 消息推送</Typography.Title>
      <Typography.Paragraph type="secondary">
        配置群机器人 Webhook 多实例，按推送条件分发运营告警、技术支持工单、开发任务派发等消息。运行时不再读取
        .env 中的 Webhook URL。
      </Typography.Paragraph>

      <Form
        form={filterForm}
        layout="inline"
        style={{ marginBottom: 16 }}
        onFinish={(v) => setFilters(v as Record<string, string>)}
      >
        <Form.Item name="name" label="名称">
          <Input allowClear placeholder="搜索" />
        </Form.Item>
        <Form.Item name="enabled" label="启用">
          <Select
            allowClear
            placeholder="全部"
            style={{ width: 100 }}
            options={[
              { value: 'true', label: '启用' },
              { value: 'false', label: '停用' },
            ]}
          />
        </Form.Item>
        <Form.Item>
          <Space>
            <Button type="primary" htmlType="submit">
              查询
            </Button>
            <Button
              onClick={() => {
                filterForm.resetFields();
                setFilters({});
              }}
            >
              重置
            </Button>
            <Button type="primary" onClick={openCreate}>
              新建推送
            </Button>
          </Space>
        </Form.Item>
      </Form>

      <Table<WecomMessagePushDto>
        rowKey="id"
        loading={loading}
        columns={columns}
        dataSource={data?.items ?? []}
        pagination={{
          current: page,
          pageSize,
          total: data?.total ?? 0,
          showSizeChanger: true,
          onChange: (p, ps) => {
            setPage(p);
            setPageSize(ps);
          },
        }}
      />

      <Modal
        title={editing ? '编辑消息推送' : '新建消息推送'}
        open={modalOpen}
        onCancel={() => setModalOpen(false)}
        onOk={() => void save()}
        confirmLoading={saving}
        width={640}
        destroyOnClose
      >
        <Form form={form} layout="vertical">
          <Form.Item name="name" label="名称" rules={[{ required: true, message: '请填写名称' }]}>
            <Input placeholder="如：运营告警" />
          </Form.Item>
          <Form.Item name="avatarUrl" label="头像（HQ 列表展示）">
            <OssUpload />
          </Form.Item>
          <Form.Item
            name="webhookUrl"
            label="Webhook URL"
            rules={[{ required: true, message: '请填写 Webhook URL' }]}
          >
            <Input.Password placeholder="企微群机器人 Webhook" />
          </Form.Item>
          <Form.Item name="enabled" label="启用" valuePropName="checked">
            <Switch />
          </Form.Item>
          <Form.Item
            name="mentionWecomUserId"
            label="企微 userid（可选）"
            extra="markdown 推送用 <@userid> @ 群成员；任务派发等场景生效"
          >
            <Input placeholder="如 woDacESQAAD..." allowClear />
          </Form.Item>
          <Form.Item
            name="pushConditions"
            label="推送条件"
            rules={[
              {
                validator: (_, v: WecomPushCondition[] | undefined) =>
                  v?.length ? Promise.resolve() : Promise.reject(new Error('请至少勾选一项推送条件')),
              },
            ]}
          >
            <WecomPushConditionPicker />
          </Form.Item>
          {conditionsWatch?.length ? (
            <Typography.Text type="secondary" style={{ display: 'block', marginBottom: 16 }}>
              已选 {conditionsWatch.length} 项：
              {conditionsWatch.map((c) => WECOM_PUSH_CONDITION_LABELS[c]).join('、')}
            </Typography.Text>
          ) : null}
          <Form.Item name="sortOrder" label="排序">
            <InputNumber min={0} style={{ width: '100%' }} />
          </Form.Item>
        </Form>
      </Modal>

      <Modal
        title="消息推送详情"
        open={!!detail}
        onCancel={() => setDetail(null)}
        footer={null}
        width={560}
      >
        {detail ? (
          <Descriptions column={1} bordered size="small">
            <Descriptions.Item label="名称">{detail.name}</Descriptions.Item>
            <Descriptions.Item label="Webhook">{detail.webhookUrlMasked}</Descriptions.Item>
            <Descriptions.Item label="启用">{detail.enabled ? '是' : '否'}</Descriptions.Item>
            <Descriptions.Item label="userid">{detail.mentionWecomUserId || '—'}</Descriptions.Item>
            <Descriptions.Item label="推送条件">
              {detail.pushConditions.map((c) => WECOM_PUSH_CONDITION_LABELS[c]).join('、')}
            </Descriptions.Item>
            <Descriptions.Item label="排序">{detail.sortOrder}</Descriptions.Item>
            <Descriptions.Item label="创建时间">{fmtTime(detail.createdAt)}</Descriptions.Item>
            <Descriptions.Item label="更新时间">{fmtTime(detail.updatedAt)}</Descriptions.Item>
          </Descriptions>
        ) : null}
      </Modal>
    </div>
  );
}
