import { useEffect, useMemo, useRef, useState } from 'react';
import { useNavigate, useSearchParams } from 'react-router-dom';
import QRCode from 'qrcode';
import PageHeader from '@dukang/shared-ui/PageHeader';
import { invokeWechatPay } from '@dukang/weixin-sdk';
import ChinaRegionPicker from '../components/ChinaRegionPicker';
import { getToken, request } from '../lib/api';
import { formatRegionLabel, parseRegionCodes } from '../lib/china-region';
import {
  clearProxyOrderDraft,
  loadProxyOrderDraft,
  saveProxyOrderDraft,
  type ProxyOrderDraft,
} from '../lib/proxyOrderDraft';
import { toastError, toastSuccess } from '../lib/toast';
import { isWechatEnv } from '../lib/weixin';
import { fetchPartnerProfile, partnerHasWechatBinding } from '../lib/wechat-auth';
import type {
  PartnerProxyDeliveryMode,
  PartnerProxyOrderCreateRequest,
  PartnerProxyOrderOptions,
  PartnerProxyOrderPreviewResult,
  ProxyOrderCreateResponse,
  ProxyOrderPayResponse,
  ProxyPayMethod,
} from '@dukang/shared-types';

function fmtMoney(n: number) {
  return n.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
}

function initialDraft(): ProxyOrderDraft {
  return (
    loadProxyOrderDraft() ?? {
      phone: '',
      receiverName: '',
      regionCodes: [],
      addressDetail: '',
      productId: '',
      quantity: 2,
      promoCodeId: '',
      deliveryMode: 'ADDRESS',
      autoReceive: false,
    }
  );
}

export default function ProxyOrderPage() {
  const navigate = useNavigate();
  const [searchParams] = useSearchParams();
  const draft0 = useMemo(() => initialDraft(), []);
  const [options, setOptions] = useState<PartnerProxyOrderOptions | null>(null);
  const [loadingOptions, setLoadingOptions] = useState(true);
  const [phone, setPhone] = useState(draft0.phone);
  const [receiverName, setReceiverName] = useState(draft0.receiverName);
  const [regionCodes, setRegionCodes] = useState<string[]>(draft0.regionCodes);
  const [addressDetail, setAddressDetail] = useState(draft0.addressDetail);
  const [productId, setProductId] = useState(draft0.productId);
  const [quantity, setQuantity] = useState(draft0.quantity);
  const [promoCodeId, setPromoCodeId] = useState(draft0.promoCodeId);
  const [deliveryMode, setDeliveryMode] = useState<PartnerProxyDeliveryMode>(draft0.deliveryMode);
  const [autoReceive, setAutoReceive] = useState(draft0.autoReceive);
  const [preview, setPreview] = useState<PartnerProxyOrderPreviewResult | null>(null);
  const [previewLoading, setPreviewLoading] = useState(false);
  const [submitting, setSubmitting] = useState(false);
  const [msg, setMsg] = useState('');
  const [step, setStep] = useState<'form' | 'pay'>('form');
  const [created, setCreated] = useState<ProxyOrderCreateResponse | null>(null);
  const [payMethod, setPayMethod] = useState<ProxyPayMethod>('NATIVE');
  const [codeUrl, setCodeUrl] = useState<string | null>(null);
  const [qrDataUrl, setQrDataUrl] = useState<string | null>(null);
  const [paying, setPaying] = useState(false);
  const pollRef = useRef<number | null>(null);

  const region = useMemo(() => parseRegionCodes(regionCodes), [regionCodes]);
  const regionLabel = region ? formatRegionLabel(region) : '';

  function stopPoll() {
    if (pollRef.current != null) {
      window.clearInterval(pollRef.current);
      pollRef.current = null;
    }
  }

  useEffect(() => () => stopPoll(), []);

  useEffect(() => {
    if (!codeUrl) {
      setQrDataUrl(null);
      return;
    }
    void QRCode.toDataURL(codeUrl, { width: 220, margin: 1 }).then(setQrDataUrl).catch(() => setQrDataUrl(null));
  }, [codeUrl]);

  function persistDraft(overrides?: Partial<ProxyOrderDraft>) {
    saveProxyOrderDraft({
      phone,
      receiverName,
      regionCodes,
      addressDetail,
      productId,
      quantity,
      promoCodeId,
      deliveryMode,
      autoReceive,
      ...overrides,
    });
  }

  useEffect(() => {
    request<PartnerProxyOrderOptions>('PARTNER_H5', '/partner/proxy-orders/options')
      .then((data) => {
        setOptions({
          ...data,
          stores: Array.isArray(data.stores) ? data.stores : [],
        });
        const fromQuery = searchParams.get('productId');
        if (fromQuery && data.products.some((p) => p.id === fromQuery)) {
          setProductId(fromQuery);
          persistDraft({ productId: fromQuery });
        } else if (data.products[0] && !productId) {
          setProductId(data.products[0].id);
        }
      })
      .catch((e) => toastError(e instanceof Error ? e.message : '加载失败'))
      .finally(() => setLoadingOptions(false));
    // eslint-disable-next-line react-hooks/exhaustive-deps -- hydrate once; productId from query
  }, [searchParams]);

  useEffect(() => {
    const fromQuery = searchParams.get('productId');
    if (fromQuery) {
      setProductId(fromQuery);
      persistDraft({ productId: fromQuery });
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps -- only sync productId from URL
  }, [searchParams]);

  useEffect(() => {
    persistDraft();
    // eslint-disable-next-line react-hooks/exhaustive-deps -- keep draft in sync for product-picker roundtrip
  }, [
    phone,
    receiverName,
    regionCodes,
    addressDetail,
    productId,
    quantity,
    promoCodeId,
    deliveryMode,
    autoReceive,
  ]);

  useEffect(() => {
    if (!productId || quantity < 1) {
      setPreview(null);
      return;
    }
    const timer = setTimeout(() => {
      setPreviewLoading(true);
      request<PartnerProxyOrderPreviewResult>('PARTNER_H5', '/partner/proxy-orders/preview', {
        method: 'POST',
        body: JSON.stringify({
          productId,
          quantity,
          deliveryMode,
          receiverCity: deliveryMode === 'ADDRESS' ? region?.city || undefined : undefined,
          receiverDistrict: deliveryMode === 'ADDRESS' ? region?.district || undefined : undefined,
        }),
        silent: true,
      })
        .then(setPreview)
        .catch(() => setPreview(null))
        .finally(() => setPreviewLoading(false));
    }, 300);
    return () => clearTimeout(timer);
  }, [productId, quantity, deliveryMode, region?.city, region?.district]);

  function validateForm(): string | null {
    if (!/^1\d{10}$/.test(phone.trim())) return '请输入有效手机号';
    if (!productId) return '请选择商品';
    if (deliveryMode === 'ADDRESS') {
      if (!region?.province || !region?.city || !region?.district) return '请选择省市区';
      if (!addressDetail.trim()) return '请填写详细地址';
      if (!autoReceive) return '配送到址须勾选同意自动收货';
    }
    if (!preview) return '请等待费用计算完成';
    return null;
  }

  function startPoll(orderId: string) {
    stopPoll();
    pollRef.current = window.setInterval(() => {
      void request<{ payStatus: string; orderNo: string }>(
        'PARTNER_H5',
        `/partner/proxy-orders/${orderId}/pay-status`,
        { silent: true },
      )
        .then((st) => {
          if (st.payStatus === 'PAID') {
            stopPoll();
            toastSuccess(`支付成功：${st.orderNo}`);
            clearProxyOrderDraft();
            navigate(`/center/proxy-orders/${orderId}`, { replace: true });
          }
        })
        .catch(() => undefined);
    }, 2000);
  }

  async function startPay(orderId: string, method: ProxyPayMethod) {
    setPaying(true);
    setMsg('');
    try {
      if (method === 'JSAPI') {
        if (!isWechatEnv()) {
          throw new Error('请在微信内打开合伙人端以使用微信代付');
        }
        const profile = await fetchPartnerProfile();
        if (!partnerHasWechatBinding(profile)) {
          throw new Error('请先绑定微信后再代付');
        }
      }

      const pay = await request<ProxyOrderPayResponse>(
        'PARTNER_H5',
        `/partner/proxy-orders/${orderId}/pay`,
        {
          method: 'POST',
          body: JSON.stringify({ payMethod: method }),
          silent: true,
        },
      );

      if (pay.mode === 'mock') {
        toastSuccess('支付成功');
        clearProxyOrderDraft();
        navigate(`/center/proxy-orders/${orderId}`, { replace: true });
        return;
      }

      if (pay.mode === 'native' && pay.codeUrl) {
        setCodeUrl(pay.codeUrl);
        startPoll(orderId);
        return;
      }

      if (pay.mode === 'jsapi' && pay.prepay) {
        await invokeWechatPay(pay.prepay, {
          apiBase: '/api/v1',
          clientApp: 'PARTNER_H5',
          getAccessToken: getToken,
          platform: 'wechat-h5',
        });
        startPoll(orderId);
        return;
      }

      throw new Error('支付发起失败');
    } catch (e) {
      setMsg(e instanceof Error ? e.message : '支付失败');
    } finally {
      setPaying(false);
    }
  }

  async function submit() {
    setMsg('');
    const err = validateForm();
    if (err) {
      setMsg(err);
      return;
    }

    const payload: PartnerProxyOrderCreateRequest = {
      phone: phone.trim(),
      deliveryMode,
      autoReceive: deliveryMode === 'ADDRESS' ? true : undefined,
      receiverName: receiverName.trim() || undefined,
      province: deliveryMode === 'ADDRESS' ? region?.province : undefined,
      city: deliveryMode === 'ADDRESS' ? region?.city : undefined,
      district: deliveryMode === 'ADDRESS' ? region?.district : undefined,
      addressDetail: deliveryMode === 'ADDRESS' ? addressDetail.trim() : undefined,
      productId,
      quantity,
      promoCodeId: promoCodeId || undefined,
    };

    setSubmitting(true);
    try {
      const order = await request<ProxyOrderCreateResponse>('PARTNER_H5', '/partner/proxy-orders', {
        method: 'POST',
        body: JSON.stringify(payload),
        silent: true,
      });
      clearProxyOrderDraft();
      setCreated(order);
      setStep('pay');
      setCodeUrl(null);
      await startPay(order.id, payMethod);
    } catch (e) {
      setMsg(e instanceof Error ? e.message : '下单失败');
    } finally {
      setSubmitting(false);
    }
  }

  const selectedProduct = options?.products.find((p) => p.id === productId);
  const deliveryLabel =
    preview?.deliveryType === 'ON_SITE_PICKUP'
      ? '现场提货'
      : preview?.deliveryType === 'CROSS_CITY'
        ? '跨城配送'
        : '同城配送';

  return (
    <div className="page partner-proxy-order-page">
      <PageHeader title={step === 'pay' ? '代下单支付' : '代下单'} onBack={() => navigate(-1)} />

      <main className="partner-form-card" style={{ margin: '0 16px 24px' }}>
        {step === 'pay' && created ? (
          <>
            <p className="body-md">
              订单 {created.orderNo} · 应付 ¥{fmtMoney(created.payAmount)}
            </p>
            <p className="label-md text-muted" style={{ marginTop: 8 }}>
              {created.deliveryType === 'ON_SITE_PICKUP'
                ? '支付成功后订单即为已完成，并发放好客权益'
                : '支付成功后进入待发货，由总部履约'}
            </p>

            <section className="partner-form-section" style={{ marginTop: 16 }}>
              <label className="partner-form-label">支付方式</label>
              <div className="partner-proxy-mode-tabs">
                <button
                  type="button"
                  className={`partner-proxy-mode-tab${payMethod === 'NATIVE' ? ' is-active' : ''}`}
                  onClick={() => {
                    setPayMethod('NATIVE');
                    void startPay(created.id, 'NATIVE');
                  }}
                >
                  收款码
                </button>
                <button
                  type="button"
                  className={`partner-proxy-mode-tab${payMethod === 'JSAPI' ? ' is-active' : ''}`}
                  onClick={() => {
                    setPayMethod('JSAPI');
                    void startPay(created.id, 'JSAPI');
                  }}
                >
                  微信代付
                </button>
              </div>
            </section>

            {payMethod === 'NATIVE' ? (
              <div style={{ textAlign: 'center', marginTop: 16 }}>
                {qrDataUrl ? (
                  <img src={qrDataUrl} alt="收款码" width={220} height={220} style={{ margin: '0 auto' }} />
                ) : (
                  <p className="label-md text-muted">{paying ? '生成收款码中…' : '暂无收款码'}</p>
                )}
                <p className="label-md text-muted" style={{ marginTop: 8 }}>
                  请使用微信扫码支付，支付成功后自动跳转
                </p>
                <button
                  type="button"
                  className="btn btn-block"
                  style={{ marginTop: 16 }}
                  disabled={paying}
                  onClick={() => void startPay(created.id, 'NATIVE')}
                >
                  {paying ? '生成中…' : '重新生成收款码'}
                </button>
              </div>
            ) : (
              <div style={{ marginTop: 16 }}>
                <p className="label-md text-muted">将调起微信支付，由合伙人微信完成代付</p>
                <button
                  type="button"
                  className="btn btn-primary btn-block"
                  style={{ marginTop: 12 }}
                  disabled={paying}
                  onClick={() => void startPay(created.id, 'JSAPI')}
                >
                  {paying ? '支付中…' : '重新调起微信代付'}
                </button>
              </div>
            )}

            {msg ? (
              <p className="partner-form-error" role="alert" style={{ marginTop: 12 }}>
                {msg}
              </p>
            ) : null}
          </>
        ) : loadingOptions ? (
          <p className="label-md text-muted">加载商品…</p>
        ) : (
          <>
            <section className="partner-form-section">
              <label className="partner-form-label">用户手机号</label>
              <div className="partner-input-wrap">
                <input
                  className="partner-input"
                  placeholder="11 位手机号"
                  value={phone}
                  onChange={(e) => setPhone(e.target.value.replace(/\D/g, '').slice(0, 11))}
                />
              </div>
            </section>

            <section className="partner-form-section">
              <label className="partner-form-label">酒品</label>
              <button
                type="button"
                className="partner-proxy-product-picker"
                onClick={() => {
                  persistDraft();
                  navigate(
                    `/proxy-order/products${productId ? `?selected=${encodeURIComponent(productId)}` : ''}`,
                  );
                }}
              >
                {selectedProduct ? (
                  <>
                    <span className="partner-proxy-product-name">{selectedProduct.name}</span>
                    <span className="label-md text-muted">
                      {selectedProduct.spec} · ¥{fmtMoney(selectedProduct.price)}
                    </span>
                  </>
                ) : (
                  <span className="label-md text-muted">点击选择酒品</span>
                )}
                <span className="partner-proxy-product-picker-arrow">›</span>
              </button>
            </section>

            <section className="partner-form-section">
              <label className="partner-form-label">数量</label>
              <div className="partner-input-wrap">
                <input
                  className="partner-input"
                  type="number"
                  min={1}
                  value={quantity}
                  onChange={(e) => setQuantity(Math.max(1, Number(e.target.value) || 1))}
                />
              </div>
            </section>

            {(options?.promoCodes.length ?? 0) > 0 && (
              <section className="partner-form-section">
                <label className="partner-form-label">绑定推广码（选填）</label>
                <select
                  className="partner-input"
                  value={promoCodeId}
                  onChange={(e) => setPromoCodeId(e.target.value)}
                  style={{
                    width: '100%',
                    padding: '12px 14px',
                    borderRadius: 12,
                    border: '1px solid var(--color-border)',
                  }}
                >
                  <option value="">不绑定</option>
                  {options!.promoCodes.map((p) => (
                    <option key={p.id} value={p.id}>
                      {p.name}（{p.code}）
                    </option>
                  ))}
                </select>
              </section>
            )}

            <section className="partner-form-section">
              <label className="partner-form-label">履约方式</label>
              <div className="partner-proxy-mode-tabs">
                <button
                  type="button"
                  className={`partner-proxy-mode-tab${deliveryMode === 'ADDRESS' ? ' is-active' : ''}`}
                  onClick={() => setDeliveryMode('ADDRESS')}
                >
                  配送到址
                </button>
                <button
                  type="button"
                  className={`partner-proxy-mode-tab${deliveryMode === 'ON_SITE_PICKUP' ? ' is-active' : ''}`}
                  onClick={() => setDeliveryMode('ON_SITE_PICKUP')}
                >
                  现场提货
                </button>
              </div>
            </section>

            {deliveryMode === 'ADDRESS' ? (
              <>
                <section className="partner-form-section">
                  <label className="partner-form-label">收货人（选填）</label>
                  <div className="partner-input-wrap">
                    <input
                      className="partner-input"
                      placeholder="默认：用户+手机尾号"
                      value={receiverName}
                      onChange={(e) => setReceiverName(e.target.value)}
                    />
                  </div>
                </section>

                <section className="partner-form-section">
                  <label className="partner-form-label">收货地区</label>
                  <ChinaRegionPicker value={regionCodes} onChange={setRegionCodes} />
                  {regionLabel ? (
                    <p className="label-md text-muted" style={{ marginTop: 8 }}>
                      {regionLabel}
                    </p>
                  ) : null}
                </section>

                <section className="partner-form-section">
                  <label className="partner-form-label">详细地址</label>
                  <div className="partner-field-input partner-field-input--block">
                    <textarea
                      rows={3}
                      placeholder="街道、门牌号等"
                      value={addressDetail}
                      onChange={(e) => setAddressDetail(e.target.value)}
                    />
                  </div>
                </section>

                <label className="partner-proxy-auto-receive">
                  <input
                    type="checkbox"
                    checked={autoReceive}
                    onChange={(e) => setAutoReceive(e.target.checked)}
                  />
                  <span>同意自动收货（配送到址必选）</span>
                </label>
              </>
            ) : null}

            <section className="partner-form-section">
              <label className="partner-form-label">支付方式</label>
              <div className="partner-proxy-mode-tabs">
                <button
                  type="button"
                  className={`partner-proxy-mode-tab${payMethod === 'NATIVE' ? ' is-active' : ''}`}
                  onClick={() => setPayMethod('NATIVE')}
                >
                  收款码
                </button>
                <button
                  type="button"
                  className={`partner-proxy-mode-tab${payMethod === 'JSAPI' ? ' is-active' : ''}`}
                  onClick={() => setPayMethod('JSAPI')}
                >
                  微信代付
                </button>
              </div>
              <p className="label-md text-muted" style={{ marginTop: 8, lineHeight: 1.5 }}>
                {payMethod === 'NATIVE'
                  ? '提交后展示商家收款码，客户或现场扫码支付'
                  : '提交后在微信内由您代客户完成支付（需已绑定微信）'}
              </p>
            </section>

            <section className="partner-proxy-fee-card">
              <h3 className="headline-md">费用明细</h3>
              {previewLoading ? (
                <p className="label-md text-muted">计算中…</p>
              ) : preview ? (
                <>
                  <div className="partner-proxy-fee-row">
                    <span className="label-md text-muted">商品单价</span>
                    <span className="body-md">¥{fmtMoney(preview.unitPrice)}</span>
                  </div>
                  <div className="partner-proxy-fee-row">
                    <span className="label-md text-muted">数量</span>
                    <span className="body-md">×{quantity}</span>
                  </div>
                  <div className="partner-proxy-fee-row">
                    <span className="label-md text-muted">履约类型</span>
                    <span className="body-md">{deliveryLabel}</span>
                  </div>
                  <div className="partner-proxy-fee-row">
                    <span className="label-md text-muted">权益额</span>
                    <span className="body-md">¥{fmtMoney(preview.benefitAmount)}</span>
                  </div>
                  <div className="partner-proxy-fee-row partner-proxy-fee-row--total">
                    <span className="headline-md">应付金额</span>
                    <span className="amount-lg text-primary">¥{fmtMoney(preview.payAmount)}</span>
                  </div>
                </>
              ) : (
                <p className="label-md text-muted">
                  {selectedProduct ? '请确认数量与履约信息后查看费用' : '请选择商品'}
                </p>
              )}
            </section>

            {msg ? (
              <p className="partner-form-error" role="alert">
                {msg}
              </p>
            ) : null}

            <button
              type="button"
              className="btn btn-primary btn-block"
              disabled={submitting || paying || !preview}
              onClick={() => void submit()}
              style={{ marginTop: 16 }}
            >
              {submitting || paying ? '处理中…' : '提交并支付'}
            </button>

            <p className="label-md text-muted" style={{ marginTop: 12, lineHeight: 1.5 }}>
              提交后进入在线支付；支付成功后发放权益。配送单将进入待发货由总部履约，现场提货走自提闭环。
            </p>
          </>
        )}
      </main>
    </div>
  );
}
