import { useCallback, useEffect, useRef, useState } from 'react';

import { Link, useNavigate, useSearchParams } from 'react-router-dom';

import PullToRefresh from '@dukang/shared-ui/PullToRefresh';

import { isScanPermissionWarmupError } from '@dukang/weixin-sdk';

import { useStoreSession } from '../contexts/StoreSessionContext';

import { request } from '../lib/api';

import { parseRedeemTokenFromScan } from '../lib/redeem-scan';

import {

  authorizeShopWechat,

  checkNeedsWechatAuth,

  fetchShopAccount,

} from '../lib/wechat-auth';

import { isWechatEnv, weixinSdk } from '../lib/weixin';

import {

  clearPendingScanAfterAuth,

  getPostAuthScanDelayMs,

  markPendingScanAfterAuth,

  peekPendingScanAfterAuth,

} from '../lib/shop-scan-auth';

import WechatScanAuthModal from '../components/WechatScanAuthModal';

import { useStorePageView } from '../lib/usePageView';

import { trackStore } from '../lib/analytics';



function formatMoney(n: number) {

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

}



function formatScanError(e: unknown, opts?: { afterAuth?: boolean }): string {

  const msg = e instanceof Error ? e.message : '扫码失败，请重试';

  if (/invalid signature/i.test(msg)) {

    return '微信 JSSDK 签名校验失败：请确认公众号已配置 JS 接口安全域名，并刷新页面后重试';

  }

  if (isScanPermissionWarmupError(msg)) {

    if (opts?.afterAuth) {

      return '微信授权已完成，扫码权限仍在准备中，请再点一次「扫码核销」';

    }

    return '微信权限校验尚未完成，请等待 1～2 秒后再次点击扫码（首次绑定微信时较常见）';

  }

  return msg;

}



export default function HomePage() {

  useStorePageView('store_home_view');

  const navigate = useNavigate();

  const { ready, authenticated } = useStoreSession();

  const [searchParams] = useSearchParams();

  const [dash, setDash] = useState<Record<string, unknown> | null>(null);

  const [scanMsg, setScanMsg] = useState('');

  const [scanning, setScanning] = useState(false);

  const [authModalOpen, setAuthModalOpen] = useState(false);

  const [authLoading, setAuthLoading] = useState(false);

  const [authError, setAuthError] = useState('');

  const pendingScanStartedRef = useRef(false);



  const loadDashboard = useCallback(() => {

    return request<Record<string, unknown>>('SHOP_H5', '/shop/dashboard')

      .then((d) => {

        setDash(d);

      })

      .catch(() => {});

  }, []);



  useEffect(() => {

    void loadDashboard();

  }, [loadDashboard]);



  useEffect(() => {

    function onResume() {

      setScanning(false);

      void loadDashboard();

    }

    function onVisibility() {

      if (document.visibilityState === 'visible') onResume();

    }

    document.addEventListener('visibilitychange', onVisibility);

    window.addEventListener('pageshow', onResume);

    window.addEventListener('focus', onResume);

    return () => {

      document.removeEventListener('visibilitychange', onVisibility);

      window.removeEventListener('pageshow', onResume);

      window.removeEventListener('focus', onResume);

    };

  }, [loadDashboard]);



  const runScan = useCallback(

    async (opts?: { postAuthWarmup?: boolean }) => {

      trackStore('store_redeem_scan_start');

      if (!isWechatEnv()) {

        setScanMsg('请在微信内打开门店端进行扫码核销');

        return;

      }

      setScanning(true);

      if (!opts?.postAuthWarmup) {

        setScanMsg('');

      }

      try {

        if (opts?.postAuthWarmup) {

          weixinSdk.reset();

        }

        await weixinSdk.init();

        const raw = await weixinSdk.scanQrCode(

          opts?.postAuthWarmup ? { postAuthWarmup: true } : undefined,

        );

        if (!raw) {

          void loadDashboard();

          return;

        }

        const token = parseRedeemTokenFromScan(raw);

        if (!token) {

          setScanMsg('无法识别核销码，请扫描用户出示的核销二维码');

          return;

        }

        navigate(`/redeem?token=${encodeURIComponent(token)}`);

      } catch (e) {

        setScanMsg(formatScanError(e, { afterAuth: opts?.postAuthWarmup }));

      } finally {

        setScanning(false);

      }

    },

    [loadDashboard, navigate],

  );



  // OAuth 由 StoreSessionContext 单例处理；此处仅在授权完成后续扫

  useEffect(() => {

    if (!ready || !authenticated || !isWechatEnv()) return;

    if (searchParams.get('code')) return;

    if (!peekPendingScanAfterAuth() || pendingScanStartedRef.current) return;



    pendingScanStartedRef.current = true;

    clearPendingScanAfterAuth();

    setAuthModalOpen(false);

    setAuthLoading(false);

    setAuthError('');

    setScanMsg('微信授权成功，正在准备扫码…');



    const timer = window.setTimeout(() => {

      void runScan({ postAuthWarmup: true });

    }, getPostAuthScanDelayMs());



    return () => window.clearTimeout(timer);

  }, [ready, authenticated, searchParams, runScan]);



  async function handleScan() {

    setScanMsg('');

    if (!isWechatEnv()) {

      setScanMsg('请在微信内打开门店端进行扫码核销');

      return;

    }

    try {

      const profile = await fetchShopAccount();

      if (await checkNeedsWechatAuth(profile)) {

        pendingScanStartedRef.current = false;

        setAuthModalOpen(true);

        return;

      }

      await runScan();

    } catch (e) {

      setScanMsg(e instanceof Error ? e.message : '无法发起扫码');

    }

  }



  async function startWechatAuth() {

    setAuthLoading(true);

    setAuthError('');

    try {

      pendingScanStartedRef.current = false;

      markPendingScanAfterAuth();

      await authorizeShopWechat();

    } catch (e) {

      clearPendingScanAfterAuth();

      setAuthError(e instanceof Error ? e.message : '微信授权失败');

      setAuthLoading(false);

    }

  }



  const store = dash?.store as Record<string, unknown> | undefined;

  const recent = (dash?.recentRecords as Array<Record<string, unknown>>) || [];

  const status = String(store?.status || '');

  const open = status === 'OPEN';

  const hoursParts: string[] = [];

  if (store?.openTime && store?.closeTime) hoursParts.push(`${store.openTime} - ${store.closeTime}`);

  if (store?.openTime2 && store?.closeTime2) hoursParts.push(`${store.openTime2} - ${store.closeTime2}`);

  const hoursText = hoursParts.length ? hoursParts.join('，') : '10:00 - 22:00';

  const statusText =

    status === 'CLOSED' ? '永久关闭' : open ? '当前正在营业中' : '当前临时闭店';



  return (

    <PullToRefresh onRefresh={loadDashboard} className="shop-home-page">

      <header className="shop-home-header">

        <h1 className="app-page-title">门店管理中心</h1>

      </header>



      <div className="shop-home-content">

        <section className="shop-home-hero">

          <div className="shop-home-hero-store">

            <span className="material-symbols-outlined shop-fill-icon">store</span>

            <h2>{String(store?.name || '门店')}</h2>

          </div>

          <div className="shop-home-stats">

            <div className="shop-home-stat">

              <p className="shop-home-stat-label">今日核销笔数</p>

              <p className="shop-home-stat-value">{Number(dash?.todayCount || 0)}</p>

              <p className="shop-home-stat-sub">

                扫码 {Number(dash?.todayScanCount || 0)} · 手机号 {Number(dash?.todayPhoneCount || 0)}

              </p>

            </div>

            <div className="shop-home-stat">

              <p className="shop-home-stat-label">今日到账金额</p>

              <p className="shop-home-stat-value">

                <span style={{ fontSize: 18 }}>¥</span>

                {formatMoney(Number(dash?.todayAmount || 0))}

              </p>

            </div>

          </div>

        </section>



        <section className="shop-home-scan">

          <button

            type="button"

            className="shop-home-scan-btn"

            disabled={scanning}

            onClick={() => void handleScan()}

          >

            <span className="material-symbols-outlined">qr_code_scanner</span>

          </button>

          <p className="shop-home-scan-label">{scanning ? '正在打开相机…' : '扫码核销'}</p>

          {scanMsg && <p className="shop-home-scan-msg" role="alert">{scanMsg}</p>}

          <Link to="/redeem/phone" className="shop-home-phone-link">

            <span className="material-symbols-outlined">smartphone</span>

            手机号核销

          </Link>

        </section>



        <section className="shop-home-status">

          <div className="shop-home-status-left">

            <div className={`shop-home-status-icon${open ? '' : ' closed'}`}>

              <span className="material-symbols-outlined shop-fill-icon">schedule</span>

            </div>

            <div>

              <p className="shop-home-status-title">营业状态</p>

              <p className="shop-home-status-sub">{statusText}</p>

              <p className="shop-home-status-sub">营业时间: {hoursText}</p>

            </div>

          </div>

          <label className="shop-home-switch" onClick={() => navigate('/status')}>

            <input type="checkbox" checked={open && status !== 'CLOSED'} readOnly tabIndex={-1} />

            <span className="shop-home-switch-track" />

          </label>

        </section>



        <section>

          <div className="shop-home-records-head">

            <h3 className="shop-home-records-title">核销记录</h3>

            <Link to="/records" className="shop-home-records-link">

              查看全部

              <span className="material-symbols-outlined" style={{ fontSize: 16 }}>chevron_right</span>

            </Link>

          </div>

          <div className="shop-home-record-list">

            {recent.length === 0 && (

              <p className="shop-home-status-sub" style={{ textAlign: 'center', padding: '16px 0' }}>暂无核销记录</p>

            )}

            {recent.map((r) => (

              <div key={String(r.id)} className="shop-home-record-item">

                <div>

                  <p className="shop-home-record-time">核销时间</p>

                  <p className="shop-home-record-value">

                    {new Date(String(r.createdAt)).toLocaleString('zh-CN')}

                  </p>

                </div>

                <p className="shop-home-record-amount">¥{formatMoney(Number(r.amount))}</p>

              </div>

            ))}

          </div>

        </section>

      </div>



      <WechatScanAuthModal

        open={authModalOpen}

        loading={authLoading}

        error={authError}

        onAuthorize={() => void startWechatAuth()}

        onCancel={() => {

          setAuthModalOpen(false);

          setAuthError('');

          clearPendingScanAfterAuth();

          pendingScanStartedRef.current = false;

        }}

      />

    </PullToRefresh>

  );

}


