import { useCallback, useEffect, useState } from 'react';
import { Link } from 'react-router-dom';
import { Button, Popconfirm, Space, Table, Typography, message } from 'antd';
import type { ColumnsType } from 'antd/es/table';
import type { PartnerAssocSummary, PartnerAssocUserItem } from '@dukang/shared-types';
import { request, requestDownload, type HqProfile, type Paginated } from '../lib/api';
import { fmtTime } from '../lib/constants';
import ActivityPosterDownloadModal from './ActivityPosterDownloadModal';

function formatNicknameWithRemark(row: PartnerAssocUserItem) {
  const name = row.nickname?.trim() || '—';
  const remark = row.hqRemark?.trim();
  return remark ? `${name}（${remark}）` : name;
}

type PartnerAssocPanelProps = {
  partnerId: string;
};

export default function PartnerAssocPanel({ partnerId }: PartnerAssocPanelProps) {
  const [summary, setSummary] = useState<PartnerAssocSummary | null>(null);
  const [users, setUsers] = useState<PartnerAssocUserItem[]>([]);
  const [total, setTotal] = useState(0);
  const [page, setPage] = useState(1);
  const [loading, setLoading] = useState(false);
  const [issuing, setIssuing] = useState(false);
  const [canEditAssoc, setCanEditAssoc] = useState(false);
  const [canDownloadPosters, setCanDownloadPosters] = useState(false);
  const [posterDownloadOpen, setPosterDownloadOpen] = useState(false);
  const [downloadingQr, setDownloadingQr] = useState(false);

  const loadSummary = useCallback(async () => {
    const data = await request<PartnerAssocSummary>(`/admin/partners/${partnerId}/assoc`);
    setSummary(data);
  }, [partnerId]);

  const loadUsers = useCallback(async (p = 1) => {
    setLoading(true);
    try {
      const res = await request<Paginated<PartnerAssocUserItem>>(
        `/admin/partners/${partnerId}/assoc/users?page=${p}&pageSize=20`,
      );
      setUsers(res.items ?? []);
      setTotal(res.total ?? 0);
      setPage(p);
    } finally {
      setLoading(false);
    }
  }, [partnerId]);

  useEffect(() => {
    void request<HqProfile>('/admin/auth/me')
      .then((p) => {
        const keys = p.permissionKeys ?? [];
        setCanEditAssoc(keys.includes('users_partner_assoc'));
        setCanDownloadPosters(keys.includes('activity_posters'));
      })
      .catch(() => {
        setCanEditAssoc(false);
        setCanDownloadPosters(false);
      });
  }, []);

  useEffect(() => {
    void loadSummary().catch((e) => message.error(e instanceof Error ? e.message : '加载关联码失败'));
    void loadUsers(1).catch(() => undefined);
  }, [loadSummary, loadUsers]);

  async function reissue() {
    setIssuing(true);
    try {
      await request(`/admin/partners/${partnerId}/assoc/qrcode`, { method: 'POST' });
      message.success('已重新生成关联码');
      await loadSummary();
    } catch (e) {
      message.error(e instanceof Error ? e.message : '生成失败');
    } finally {
      setIssuing(false);
    }
  }

  async function downloadBareQrcode() {
    if (!summary?.qrcodeUrl) {
      message.warning('尚未生成关联码');
      return;
    }
    setDownloadingQr(true);
    try {
      await requestDownload(
        `/admin/partners/${partnerId}/assoc/qrcode`,
        {},
        `partner-assoc-${partnerId}.png`,
      );
      message.success('已开始下载二维码');
    } catch (e) {
      message.error(e instanceof Error ? e.message : '下载二维码失败');
    } finally {
      setDownloadingQr(false);
    }
  }

  async function unbind(userId: string) {
    try {
      await request(`/admin/partners/${partnerId}/assoc/users/${userId}/unbind`, { method: 'POST' });
      message.success('已解绑');
      await Promise.all([loadSummary(), loadUsers(page)]);
    } catch (e) {
      message.error(e instanceof Error ? e.message : '解绑失败');
    }
  }

  const columns: ColumnsType<PartnerAssocUserItem> = [
    { title: '用户编号', dataIndex: 'userNo', width: 140 },
    {
      title: '用户',
      dataIndex: 'nickname',
      render: (_, row) => (
        <Link
          className="admin-primary-link"
          to={`/users?userId=${encodeURIComponent(row.id)}`}
          title="在用户列表中查看"
        >
          {formatNicknameWithRemark(row)}
        </Link>
      ),
    },
    { title: '手机', dataIndex: 'phone', render: (v) => v || '—' },
    { title: '关联时间', dataIndex: 'boundAt', render: (v) => (v ? fmtTime(v) : '—') },
    { title: '已付订单', dataIndex: 'orderCount', width: 90 },
    ...(canEditAssoc
      ? [
          {
            title: '操作',
            width: 90,
            render: (_: unknown, row: PartnerAssocUserItem) => (
              <Popconfirm title="解绑后该用户新单不再计订单佣金" onConfirm={() => void unbind(row.id)}>
                <Button type="link" size="small" danger>
                  解绑
                </Button>
              </Popconfirm>
            ),
          } satisfies ColumnsType<PartnerAssocUserItem>[number],
        ]
      : []),
  ];

  return (
    <div>
      <Space align="start" style={{ marginBottom: 16 }} wrap>
        {summary?.qrcodeUrl ? (
          <img src={summary.qrcodeUrl} alt="关联码" style={{ width: 160, height: 160, background: '#fff' }} />
        ) : (
          <Typography.Text type="secondary">尚未生成关联码</Typography.Text>
        )}
        <div>
          <Typography.Paragraph style={{ marginBottom: 8 }}>
            <Link to={`/users?assocPartnerAccountId=${encodeURIComponent(partnerId)}`}>
              关联用户 {summary?.userCount ?? 0} 人
            </Link>
          </Typography.Paragraph>
          <Space wrap>
            <Button loading={issuing} onClick={() => void reissue()}>
              {summary?.qrcodeUrl ? '补发关联码' : '生成关联码'}
            </Button>
            {summary?.qrcodeUrl ? (
              <Button loading={downloadingQr} onClick={() => void downloadBareQrcode()}>
                下载二维码
              </Button>
            ) : null}
            {canDownloadPosters ? (
              <Button onClick={() => setPosterDownloadOpen(true)}>下载活动图</Button>
            ) : null}
          </Space>
        </div>
      </Space>
      <Table
        rowKey="id"
        size="small"
        loading={loading}
        columns={columns}
        dataSource={users}
        pagination={{
          current: page,
          pageSize: 20,
          total,
          onChange: (p) => void loadUsers(p),
        }}
      />
      <ActivityPosterDownloadModal
        open={posterDownloadOpen}
        partnerIds={[partnerId]}
        onClose={() => setPosterDownloadOpen(false)}
      />
    </div>
  );
}
