import { useCallback, useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import {
  Button,
  Checkbox,
  Drawer,
  Form,
  Input,
  InputNumber,
  Modal,
  Popconfirm,
  Select,
  Space,
  Table,
  Tabs,
  Typography,
  message,
} from 'antd';
import type { ColumnsType } from 'antd/es/table';
import {
  CITY_PARTNER_SCOPE_LABELS,
  CITY_PARTNER_STATUS_LABELS,
  CityPartnerScopeType,
  CityPartnerStatus,
  PARTNER_PERMISSION_KEYS,
  PARTNER_PERMISSION_LABELS,
  PARTNER_STAFF_ROLE_LABELS,
  type PartnerPermissionKey,
} from '@dukang/shared-types';
import { request, type Paginated } from '../lib/api';
import { omitNullFields } from '../lib/omit-null-fields';
import { districtCodeLabel, formatDistrictLabels } from '../lib/china-region';
import { fmtTime } from '../lib/constants';
import CityDistrictMultiSelect from './CityDistrictMultiSelect';
import PartnerSubAccountList from './PartnerSubAccountList';
import PartnerAssocPanel from './PartnerAssocPanel';

type PartnerRow = {
  id: string;
  companyName: string;
  phone: string;
  name: string;
  scopeType?: string;
  districtCodes?: string[] | null;
  orderCommissionRate?: number;
  redeemCommissionRate?: number;
  storeCount?: number;
  accountCount: number;
  createdAt: string;
};

type PartnerDetail = PartnerRow & {
  address?: string;
  districtCodes?: string[] | null;
  bindingStatus?: string;
  bankAccountName?: string | null;
  bankAccountNo?: string | null;
  bankBranch?: string | null;
  managedWarehouseId?: string | null;
  managedWarehouseName?: string | null;
  contactPhone?: string | null;
  children?: Array<{
    id: string;
    phone: string;
    name: string;
    staffRole?: string;
    permissions?: string[];
    status: string;
  }>;
};

type Props = {
  cityId: string;
  cityCode?: string;
  maxPartnerCommissionRate?: number;
  onChanged?: () => void;
};

const SCOPE_OPTIONS = Object.entries(CITY_PARTNER_SCOPE_LABELS).map(([value, label]) => ({ value, label }));
const BINDING_OPTIONS = Object.entries(CITY_PARTNER_STATUS_LABELS).map(([value, label]) => ({ value, label }));
const PERM_OPTIONS = PARTNER_PERMISSION_KEYS.map((k: PartnerPermissionKey) => ({
  value: k,
  label: PARTNER_PERMISSION_LABELS[k],
}));
const STAFF_ROLE_OPTIONS = Object.entries(PARTNER_STAFF_ROLE_LABELS)
  .filter(([value]) => value !== 'PARTNER')
  .map(([value, label]) => ({ value, label }));

function flattenDistrictCodes(values: string[] | string[][] | undefined): string[] {
  if (!values?.length) return [];
  if (Array.isArray(values[0])) {
    return (values as string[][]).map((path) => path[path.length - 1]).filter(Boolean);
  }
  return values as string[];
}

function commissionSumError(
  orderPercent: number,
  redeemPercent: number,
  maxRate: number,
): string | null {
  // API 可能把 Prisma Decimal 序列化为字符串；`"0.05" + 1e-9` 会变成字符串拼接导致误判超限
  const max = Number(maxRate);
  const sum = Number(orderPercent) / 100 + Number(redeemPercent) / 100;
  if (!Number.isFinite(max) || !Number.isFinite(sum)) return '佣金比例无效';
  if (sum > max + 1e-9) {
    return `订单佣金与核销佣金合计不得超过 ${(max * 100).toFixed(2)}%（当前 ${(sum * 100).toFixed(2)}%）`;
  }
  return null;
}

function formatApiError(err: unknown): string | null {
  if (err && typeof err === 'object' && 'errorFields' in err) return null;
  if (!(err instanceof Error)) return '操作失败';
  return err.message.replace(/\b(\d{6})\b/g, (code) => {
    const label = districtCodeLabel(code);
    return label !== code ? `${label}(${code})` : code;
  });
}

export default function CityPartnersPanel({
  cityId,
  cityCode,
  maxPartnerCommissionRate = 0.05,
  onChanged,
}: Props) {
  const navigate = useNavigate();
  const [editForm] = Form.useForm();
  const [createForm] = Form.useForm();
  const [subForm] = Form.useForm();
  const [subEditForm] = Form.useForm();
  const [partners, setPartners] = useState<PartnerRow[]>([]);
  const [loading, setLoading] = useState(false);
  const [detail, setDetail] = useState<PartnerDetail | null>(null);
  const [drawerOpen, setDrawerOpen] = useState(false);
  const [createOpen, setCreateOpen] = useState(false);
  const [subOpen, setSubOpen] = useState(false);
  const [subEditOpen, setSubEditOpen] = useState(false);
  const [subEditId, setSubEditId] = useState<string | null>(null);
  const [createScopeType, setCreateScopeType] = useState<CityPartnerScopeType>(CityPartnerScopeType.CITY_WIDE);
  const [editScopeType, setEditScopeType] = useState<CityPartnerScopeType>(CityPartnerScopeType.CITY_WIDE);

  const loadPartners = useCallback(async () => {
    setLoading(true);
    try {
      const res = await request<Paginated<PartnerRow>>(`/admin/partners?cityId=${cityId}&pageSize=100`);
      setPartners(res.items);
    } finally {
      setLoading(false);
    }
  }, [cityId]);

  useEffect(() => {
    void loadPartners();
  }, [loadPartners]);

  async function openPartner(id: string) {
    const d = await request<PartnerDetail>(`/admin/partners/${id}`);
    setDetail(d);
    setEditScopeType((d.scopeType as CityPartnerScopeType) || CityPartnerScopeType.CITY_WIDE);
    editForm.setFieldsValue({
      name: d.name,
      phone: d.phone,
      companyName: d.companyName,
      contactPhone: d.contactPhone ?? d.phone,
      address: d.address ?? '',
      scopeType: d.scopeType,
      districtCodes: d.districtCodes ?? [],
      orderCommissionRate: (d.orderCommissionRate ?? 0) * 100,
      redeemCommissionRate: (d.redeemCommissionRate ?? 0.03) * 100,
      bindingStatus: d.bindingStatus ?? CityPartnerStatus.ACTIVE,
      bankAccountName: d.bankAccountName ?? '',
      bankAccountNo: d.bankAccountNo ?? '',
      bankBranch: d.bankBranch ?? '',
    });
    setDrawerOpen(true);
  }

  async function savePartner() {
    if (!detail) return;
    try {
      const v = await editForm.validateFields();
      const err = commissionSumError(
        Number(v.orderCommissionRate ?? 0),
        Number(v.redeemCommissionRate ?? 0),
        maxPartnerCommissionRate,
      );
      if (err) {
        message.error(err);
        return;
      }
      await request(`/admin/partners/${detail.id}`, {
        method: 'PUT',
        body: JSON.stringify({
          ...omitNullFields(v),
          orderCommissionRate: Number(v.orderCommissionRate ?? 0) / 100,
          redeemCommissionRate: Number(v.redeemCommissionRate ?? 3) / 100,
          districtCodes: editScopeType === CityPartnerScopeType.DISTRICT ? flattenDistrictCodes(v.districtCodes) : undefined,
        }),
      });
      message.success('已保存');
      setDrawerOpen(false);
      void loadPartners();
      onChanged?.();
    } catch (e) {
      const msg = formatApiError(e);
      if (msg) message.error(msg);
    }
  }

  async function deletePartner(row: { id: string; storeCount?: number }) {
    if ((row.storeCount ?? 0) > 0) {
      Modal.warning({
        title: '请先删除门店',
        content: `该城市合伙人下还有 ${row.storeCount} 家门店，请先删除门店后再删除合伙人。`,
        okText: '查看门店',
        onOk: () => navigate(`/stores?partnerId=${row.id}`),
      });
      return;
    }
    try {
      await request(`/admin/partners/${row.id}`, { method: 'DELETE' });
      message.success('城市合伙人已删除');
      if (detail?.id === row.id) {
        setDrawerOpen(false);
        setDetail(null);
      }
      void loadPartners();
      onChanged?.();
    } catch (e) {
      const msg = formatApiError(e);
      if (msg) message.error(msg);
    }
  }

  async function deleteSubAccount(subId: string) {
    await request(`/admin/partner-accounts/${subId}`, { method: 'DELETE' });
    message.success('子账号已删除');
    if (detail) void openPartner(detail.id);
    void loadPartners();
    onChanged?.();
  }

  const columns: ColumnsType<PartnerRow> = [
    {
      title: '区县',
      dataIndex: 'districtCodes',
      width: 160,
      render: (codes: string[] | null | undefined, row) =>
        row.scopeType === CityPartnerScopeType.CITY_WIDE ? '全城' : formatDistrictLabels(codes),
    },
    { title: '公司名', dataIndex: 'companyName' },
    { title: '主账号', dataIndex: 'phone', width: 120 },
    {
      title: '管辖',
      dataIndex: 'scopeType',
      width: 100,
      render: (v) => (v ? CITY_PARTNER_SCOPE_LABELS[v as keyof typeof CITY_PARTNER_SCOPE_LABELS] || v : '—'),
    },
    {
      title: '佣金',
      width: 120,
      render: (_, row) => `${Math.round((row.orderCommissionRate ?? 0) * 100)}% / ${Math.round((row.redeemCommissionRate ?? 0.03) * 100)}%`,
    },
    { title: '子账号', dataIndex: 'accountCount', width: 70, render: (n) => Math.max(0, n - 1) },
    { title: '创建', dataIndex: 'createdAt', width: 150, render: fmtTime },
    {
      title: '操作',
      width: 140,
      render: (_, row) => (
        <Space size={0}>
          <Button type="link" size="small" onClick={() => void openPartner(row.id)}>
            管理
          </Button>
          <Popconfirm
            title="确认删除该城市合伙人？"
            description="若有门店需先删除门店；账号下有订单或核销单将禁止删除。"
            okText="删除"
            okButtonProps={{ danger: true }}
            onConfirm={() => void deletePartner(row)}
          >
            <Button type="link" size="small" danger>
              删除
            </Button>
          </Popconfirm>
        </Space>
      ),
    },
  ];

  return (
    <>
      <Button
        type="primary"
        style={{ marginBottom: 12 }}
        onClick={() => {
          createForm.resetFields();
          createForm.setFieldsValue({
            cityId,
            orderCommissionRate: 0,
            redeemCommissionRate: 3,
            scopeType: CityPartnerScopeType.CITY_WIDE,
          });
          setCreateScopeType(CityPartnerScopeType.CITY_WIDE);
          setCreateOpen(true);
        }}
      >
        新建合伙人
      </Button>
      <Table rowKey="id" size="small" loading={loading} columns={columns} dataSource={partners} pagination={false} />

      <Drawer
        title="城市合伙人"
        width={640}
        open={drawerOpen}
        onClose={() => setDrawerOpen(false)}
        extra={
          <Space>
            {detail ? (
              <Popconfirm
                title="确认删除该城市合伙人？"
                description="若有门店需先删除门店；账号下有订单或核销单将禁止删除。"
                okText="删除"
                okButtonProps={{ danger: true }}
                onConfirm={() => void deletePartner(detail)}
              >
                <Button danger>删除</Button>
              </Popconfirm>
            ) : null}
            <Button type="primary" onClick={() => void savePartner()}>保存</Button>
          </Space>
        }
      >
        {detail && (
          <Tabs
            items={[
              {
                key: 'info',
                label: '主账号',
                children: (
                  <Form form={editForm} layout="vertical">
                    <Form.Item name="companyName" label="公司名"><Input placeholder="选填" /></Form.Item>
                    <Form.Item name="name" label="主账号姓名" rules={[{ required: true }]}><Input /></Form.Item>
                    <Form.Item name="phone" label="登录手机号" rules={[{ required: true }]}><Input /></Form.Item>
                    <Form.Item name="contactPhone" label="业务联系电话"><Input /></Form.Item>
                    <Form.Item name="address" label="地址"><Input placeholder="选填" /></Form.Item>
                    <Form.Item name="bindingStatus" label="绑定状态" rules={[{ required: true }]}>
                      <Select options={BINDING_OPTIONS} />
                    </Form.Item>
                    <Form.Item name="scopeType" label="管辖类型" rules={[{ required: true }]}>
                      <Select options={SCOPE_OPTIONS} onChange={(v) => setEditScopeType(v)} />
                    </Form.Item>
                    {editScopeType === CityPartnerScopeType.DISTRICT && (
                      <Form.Item
                        name="districtCodes"
                        label="区县"
                        extra="仅作标识，可多选当前城市下的区县（不做互斥）"
                      >
                        <CityDistrictMultiSelect cityCode={cityCode} />
                      </Form.Item>
                    )}
                    <Space style={{ width: '100%' }} size="large">
                      <Form.Item name="orderCommissionRate" label="订单佣金 %"><InputNumber min={0} max={100} precision={2} /></Form.Item>
                      <Form.Item name="redeemCommissionRate" label="核销佣金 %"><InputNumber min={0} max={100} precision={2} /></Form.Item>
                    </Space>
                    <Typography.Text type="secondary" style={{ display: 'block', marginBottom: 12 }}>
                      订单 + 核销合计不得超过 {(maxPartnerCommissionRate * 100).toFixed(2)}%（可在城市基本信息中调整）
                    </Typography.Text>
                    <Form.Item label="管仓仓库">
                      <Input
                        disabled
                        value={detail.managedWarehouseName ?? '未分配（请在仓库管理中设置）'}
                      />
                    </Form.Item>
                    <Form.Item name="bankAccountName" label="户名"><Input /></Form.Item>
                    <Form.Item name="bankAccountNo" label="账号"><Input /></Form.Item>
                    <Form.Item name="bankBranch" label="开户行"><Input /></Form.Item>
                  </Form>
                ),
              },
              {
                key: 'staff',
                label: `子账号 (${Math.max(0, (detail.accountCount ?? 1) - 1)})`,
                children: (
                  <PartnerSubAccountList
                    subs={detail.children ?? []}
                    onAdd={() => {
                      subForm.resetFields();
                      subForm.setFieldsValue({ staffRole: 'INTERNAL', permissions: ['store:create', 'store:manage'] });
                      setSubOpen(true);
                    }}
                    onEdit={(row) => {
                      setSubEditId(row.id);
                      subEditForm.setFieldsValue({
                        name: row.name,
                        phone: row.phone,
                        staffRole: row.staffRole ?? 'INTERNAL',
                        permissions: row.permissions ?? [],
                        status: row.status,
                      });
                      setSubEditOpen(true);
                    }}
                    onDelete={(subId) => void deleteSubAccount(subId)}
                  />
                ),
              },
              {
                key: 'assoc',
                label: '关联码',
                children: <PartnerAssocPanel partnerId={detail.id} />,
              },
            ]}
          />
        )}
      </Drawer>

      <Modal title="新建城市合伙人" open={createOpen} width={560} onCancel={() => setCreateOpen(false)} onOk={async () => {
        try {
          const v = await createForm.validateFields();
          const err = commissionSumError(
            Number(v.orderCommissionRate ?? 0),
            Number(v.redeemCommissionRate ?? 3),
            maxPartnerCommissionRate,
          );
          if (err) {
            message.error(err);
            return;
          }
          await request('/admin/partners', {
            method: 'POST',
            body: JSON.stringify({
              ...v,
              cityId,
              orderCommissionRate: Number(v.orderCommissionRate ?? 0) / 100,
              redeemCommissionRate: Number(v.redeemCommissionRate ?? 3) / 100,
              districtCodes: createScopeType === CityPartnerScopeType.DISTRICT ? flattenDistrictCodes(v.districtCodes) : undefined,
            }),
          });
          message.success('已创建');
          setCreateOpen(false);
          void loadPartners();
          onChanged?.();
        } catch (e) {
          const msg = formatApiError(e);
          if (msg) message.error(msg);
        }
      }}>
        <Form form={createForm} layout="vertical">
          <Form.Item name="companyName" label="公司名"><Input placeholder="选填" /></Form.Item>
          <Form.Item name="name" label="主账号姓名" rules={[{ required: true }]}><Input /></Form.Item>
          <Form.Item name="phone" label="登录手机号" rules={[{ required: true }]}><Input /></Form.Item>
          <Form.Item name="address" label="地址"><Input placeholder="选填" /></Form.Item>
          <Form.Item name="scopeType" label="管辖类型" rules={[{ required: true }]}>
            <Select options={SCOPE_OPTIONS} onChange={(v) => setCreateScopeType(v)} />
          </Form.Item>
          {createScopeType === CityPartnerScopeType.DISTRICT && (
            <Form.Item
              name="districtCodes"
              label="区县"
              extra="选填；仅作标识，可多选当前城市下的区县（不做互斥）"
            >
              <CityDistrictMultiSelect cityCode={cityCode} />
            </Form.Item>
          )}
          <Space style={{ width: '100%' }} size="large">
            <Form.Item name="orderCommissionRate" label="订单佣金 %"><InputNumber min={0} max={100} precision={2} /></Form.Item>
            <Form.Item name="redeemCommissionRate" label="核销佣金 %"><InputNumber min={0} max={100} precision={2} /></Form.Item>
          </Space>
          <Typography.Text type="secondary" style={{ display: 'block', marginBottom: 12 }}>
            订单 + 核销合计不得超过 {(maxPartnerCommissionRate * 100).toFixed(2)}%
          </Typography.Text>
        </Form>
      </Modal>

      <Modal title="添加子账号" open={subOpen} onCancel={() => setSubOpen(false)} onOk={async () => {
        if (!detail) return;
        const v = await subForm.validateFields();
        await request('/admin/partner-accounts', {
          method: 'POST',
          body: JSON.stringify({ ...v, parentAccountId: detail.id }),
        });
        message.success('已创建');
        setSubOpen(false);
        void openPartner(detail.id);
        void loadPartners();
        onChanged?.();
      }}>
        <Form form={subForm} layout="vertical">
          <Form.Item name="name" label="姓名" rules={[{ required: true }]}><Input /></Form.Item>
          <Form.Item name="phone" label="手机号" rules={[{ required: true }]}><Input /></Form.Item>
          <Form.Item name="staffRole" label="角色" initialValue="INTERNAL">
            <Select options={STAFF_ROLE_OPTIONS} />
          </Form.Item>
          <Form.Item name="permissions" label="权限">
            <Checkbox.Group options={PERM_OPTIONS} />
          </Form.Item>
        </Form>
      </Modal>

      <Modal title="编辑子账号" open={subEditOpen} onCancel={() => setSubEditOpen(false)} onOk={async () => {
        if (!subEditId || !detail) return;
        const v = await subEditForm.validateFields();
        await request(`/admin/partner-accounts/${subEditId}`, { method: 'PUT', body: JSON.stringify(v) });
        message.success('已更新');
        setSubEditOpen(false);
        void openPartner(detail.id);
      }}>
        <Form form={subEditForm} layout="vertical">
          <Form.Item name="name" label="姓名" rules={[{ required: true }]}><Input /></Form.Item>
          <Form.Item name="phone" label="手机号" rules={[{ required: true }]}><Input /></Form.Item>
          <Form.Item name="staffRole" label="角色"><Select options={STAFF_ROLE_OPTIONS} /></Form.Item>
          <Form.Item name="status" label="状态">
            <Select options={[{ value: 'ACTIVE', label: '启用' }, { value: 'DISABLED', label: '停用' }]} />
          </Form.Item>
          <Form.Item name="permissions" label="权限">
            <Checkbox.Group options={PERM_OPTIONS} />
          </Form.Item>
        </Form>
      </Modal>
    </>
  );
}
