import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { View, Text, Image } from '@tarojs/components';
import Taro, {
  useDidShow,
  useLoad,
  usePageScroll,
  useRouter,
  useShareAppMessage,
  useShareTimeline,
} from '@tarojs/taro';
import PageShell from '../../components/PageShell';
import PageNavBar from '../../components/PageNavBar';
import ProductCarousel from '../../components/ProductCarousel';
import ShareNavButton from '../../components/ShareNavButton';
import StoreRedeemMarquee from '../../components/StoreRedeemMarquee';
import WechatShareReady from '../../components/WechatShareReady';
import { request, toast } from '../../lib/api';
import { maskPhone, toDialablePhone } from '../../lib/phone';
import { track } from '../../lib/analytics';
import { formatShanghaiDateTime } from '../../lib/datetime';
import {
  buildSceneSharePayload,
  toWeappShareMessage,
  toWeappShareTimeline,
} from '../../lib/wechat-share';

type StoreMedia = {
  url?: string | null;
  bizType?: string | null;
  mediaType?: string | null;
};

type StorePackage = {
  name: string;
  price: string | number;
  dishes: string;
  usableTime?: string | null;
  otherNotes?: string | null;
  imageUrl?: string | null;
  sortOrder?: number;
};

type Store = {
  id: string;
  name: string;
  address?: string;
  province?: string;
  cityName?: string;
  city?: string;
  district?: string;
  phone?: string;
  intro?: string | null;
  benefitUsageRule?: string | null;
  coverUrl?: string | null;
  carouselUrls?: string[] | null;
  media?: StoreMedia[] | null;
  packages?: StorePackage[] | null;
  openTime?: string | null;
  closeTime?: string | null;
  openTime2?: string | null;
  closeTime2?: string | null;
  avgPrice?: number | null;
  latitude?: number | string | null;
  longitude?: number | string | null;
  category?: { name: string } | null;
};

type RecentRedeem = {
  userLabel: string;
  amount: number | string;
  createdAt: string;
  text?: string;
};

function uniqueUrls(urls: Array<string | null | undefined>) {
  const seen = new Set<string>();
  const out: string[] = [];
  for (const raw of urls) {
    const url = String(raw || '').trim();
    if (!url || seen.has(url)) continue;
    seen.add(url);
    out.push(url);
  }
  return out;
}

function envPhotoUrls(store: Store) {
  return uniqueUrls(
    (store.media || [])
      .filter((m) => !m.bizType || m.bizType === 'ENV')
      .map((m) => m.url),
  );
}

function fullAddress(store: Store) {
  const city = store.cityName || store.city || '';
  return `${store.province || ''}${city}${store.district || ''}${store.address || ''}`.trim();
}

function pickStoreId(raw?: string | null) {
  return String(raw || '')
    .trim()
    .replace(/[^\d]/g, '');
}

/** 与历史记录一致：2026-08-03 15:14:30（Asia/Shanghai） */
function formatRedeemTime(input?: string | null) {
  return formatShanghaiDateTime(input);
}

function formatPackagePriceYuan(price: string | number) {
  const n = typeof price === 'number' ? price : Number(price);
  if (!Number.isFinite(n)) return '0';
  if (Math.abs(n - Math.round(n)) < 1e-9) return String(Math.round(n));
  return n.toFixed(2).replace(/\.?0+$/, '');
}

function formatRedeemAmountYuan(amount: number | string) {
  const n = typeof amount === 'number' ? amount : Number(amount);
  if (!Number.isFinite(n)) return '0';
  if (Math.abs(n - Math.round(n)) < 1e-9) return String(Math.round(n));
  return n.toFixed(2).replace(/\.?0+$/, '');
}

function formatRecentRedeemLine(row: RecentRedeem) {
  try {
    // 优先用服务端拼好的 text，避免客户端时区 / Intl 差异
    if (row.text?.trim()) return row.text.trim();
    const label = String(row.userLabel || '用户***').trim() || '用户***';
    const rawTime = String(row.createdAt || '').trim();
    const time =
      /^\d{4}-\d{2}-\d{2}/.test(rawTime)
        ? rawTime.slice(0, 19).replace('T', ' ')
        : formatRedeemTime(row.createdAt);
    const amount = formatRedeemAmountYuan(row.amount);
    return `${label} ${time} 核销${amount}元`;
  } catch {
    return '';
  }
}

function normalizeRecentRedeems(payload: unknown): RecentRedeem[] {
  try {
    if (Array.isArray(payload)) return payload as RecentRedeem[];
    if (payload && typeof payload === 'object') {
      const list =
        (payload as { list?: unknown; items?: unknown; data?: unknown }).list ??
        (payload as { items?: unknown }).items ??
        (payload as { data?: unknown }).data;
      if (Array.isArray(list)) return list as RecentRedeem[];
    }
  } catch {
    /* ignore */
  }
  return [];
}

export default function StoreDetailPage() {
  const router = useRouter();
  const [storeId, setStoreId] = useState(() => pickStoreId(router.params.id));
  const [store, setStore] = useState<Store | null>(null);
  const [recentRedeems, setRecentRedeems] = useState<RecentRedeem[]>([]);
  const [loading, setLoading] = useState(true);
  const [loadError, setLoadError] = useState('');
  const [headerSolid, setHeaderSolid] = useState(false);
  const storeRef = useRef<Store | null>(null);
  storeRef.current = store;

  usePageScroll(({ scrollTop }) => {
    setHeaderSolid(scrollTop > 100);
  });

  const loadStore = useCallback(async (id: string) => {
    if (!id) {
      setLoading(false);
      setLoadError('缺少门店参数');
      return;
    }
    setLoadError('');
    if (!storeRef.current) setLoading(true);
    try {
      const data = await request<Store>(`/stores/${id}`);
      if (!data || !data.id) {
        setStore(null);
        setLoadError('门店不存在或暂不可见');
        toast('门店不存在或暂不可见');
        return;
      }
      setStore(data);
    } catch (e) {
      const msg = e instanceof Error ? e.message : '加载失败';
      setLoadError(msg);
      if (!storeRef.current) toast(msg);
    } finally {
      setLoading(false);
    }
  }, []);

  const loadRecentRedeems = useCallback(async (id: string) => {
    if (!id) {
      setRecentRedeems([]);
      return;
    }
    try {
      const list = await request<unknown>(`/stores/${id}/recent-redeems?limit=20`);
      setRecentRedeems(normalizeRecentRedeems(list));
    } catch {
      setRecentRedeems([]);
    }
  }, []);

  const bootstrap = useCallback(
    (id: string) => {
      const nextId = pickStoreId(id);
      if (!nextId) {
        setLoading(false);
        setLoadError('缺少门店参数');
        return;
      }
      setStoreId(nextId);
      void loadStore(nextId);
      void loadRecentRedeems(nextId);
    },
    [loadStore, loadRecentRedeems],
  );

  // 首屏：useLoad 带 options.id，比仅用 useDidShow 更稳（H5/小程序都覆盖）
  useLoad((options) => {
    bootstrap(options?.id || router.params.id || '');
  });

  useEffect(() => {
    const fromRouter = pickStoreId(router.params.id);
    if (fromRouter && fromRouter !== storeId) {
      bootstrap(fromRouter);
    }
  }, [router.params.id, storeId, bootstrap]);

  // 登录态变化后回到本页：重拉详情与走马灯
  useDidShow(() => {
    const id = pickStoreId(storeId || router.params.id);
    if (!id) return;
    void loadStore(id);
    void loadRecentRedeems(id);
  });

  const sharePayload = useMemo(() => {
    const envFirst = store ? envPhotoUrls(store)[0] : undefined;
    return buildSceneSharePayload('storeDetail', {
      path: `/pages/store-detail/index?id=${storeId}`,
      dynamicTitle: store?.name,
      dynamicDesc: store?.intro?.trim() || store?.address,
      dynamicImageUrl: store?.coverUrl || envFirst || store?.carouselUrls?.[0],
    });
  }, [store, storeId]);

  const marqueeLines = useMemo(
    () => recentRedeems.map(formatRecentRedeemLine).filter(Boolean),
    [recentRedeems],
  );

  useShareAppMessage(() => toWeappShareMessage(sharePayload));
  useShareTimeline(() =>
    toWeappShareTimeline(sharePayload, storeId ? `id=${storeId}` : ''),
  );

  function goBack() {
    const pages = Taro.getCurrentPages();
    if (pages.length > 1) Taro.navigateBack();
    else Taro.switchTab({ url: '/pages/stores/index' });
  }

  function callStore() {
    if (!store?.phone) {
      toast('暂无门店电话');
      return;
    }
    track('store_phone_call', { storeId: store.id });
    Taro.makePhoneCall({ phoneNumber: toDialablePhone(store.phone) }).catch(() => toast('无法拨打电话'));
  }

  function openMap() {
    if (!store) return;
    const lat = store.latitude != null ? Number(store.latitude) : NaN;
    const lng = store.longitude != null ? Number(store.longitude) : NaN;
    const address = fullAddress(store) || store.address || store.name;

    if (Number.isFinite(lat) && Number.isFinite(lng)) {
      Taro.openLocation({
        latitude: lat,
        longitude: lng,
        name: store.name,
        address,
        scale: 16,
      }).catch(() => {
        if (process.env.TARO_ENV === 'h5' && typeof window !== 'undefined') {
          window.location.href = `https://uri.amap.com/marker?position=${lng},${lat}&name=${encodeURIComponent(store.name)}&address=${encodeURIComponent(address)}`;
          return;
        }
        toast('无法打开地图导航');
      });
      return;
    }

    if (process.env.TARO_ENV === 'h5' && typeof window !== 'undefined' && address) {
      window.location.href = `https://uri.amap.com/search?keyword=${encodeURIComponent(address)}&src=dukang`;
      return;
    }
    toast('门店位置待完善，暂无法导航');
  }

  if (!store) {
    return (
      <PageShell variant="scroll" className="store-detail-page">
        <PageNavBar title="门店详情" solid onBack={goBack} />
        <View className="page-with-nav-bar u-empty">
          {loading ? '加载中…' : loadError || '门店不存在或暂不可见'}
        </View>
      </PageShell>
    );
  }

  const envPhotos = envPhotoUrls(store);
  const heroImages = uniqueUrls([store.coverUrl, ...(store.carouselUrls || [])]);
  const packages = store.packages ?? [];

  const intro = store.intro?.trim() || '';
  const benefitRuleRaw = store.benefitUsageRule?.trim() || '';
  const benefitRule =
    benefitRuleRaw && !/^null$/i.test(benefitRuleRaw) ? benefitRuleRaw : '';

  function openPackageDetail(index: number) {
    Taro.navigateTo({
      url: `/pages/store-package-detail/index?storeId=${storeId}&index=${index}`,
    });
  }

  function previewEnv(index: number) {
    if (!envPhotos.length) return;
    Taro.previewImage({
      current: envPhotos[index],
      urls: envPhotos,
    }).catch(() => toast('无法预览图片'));
  }

  return (
    <PageShell variant="scroll" className="store-detail-page" hasFixedFooter>
      <WechatShareReady payload={sharePayload} />
      <PageNavBar
        title={store.name}
        solid={headerSolid}
        titleVisible={headerSolid}
        onBack={goBack}
        right={<ShareNavButton payload={sharePayload} />}
      />

      <View className="store-detail-hero full-bleed">
        <ProductCarousel
          images={heroImages}
          alt={store.name}
          variant="store"
          previewable
          imageFit="contain"
        />
      </View>

      <View className="store-detail-info-card">
        <Text className="store-detail-name">{store.name}</Text>

        <View className="store-detail-row">
          <Text className="store-detail-meta store-detail-meta--flex">
            {store.district ? `${store.district} · ` : ''}
            {store.address || '地址待完善'}
          </Text>
          <Text className="store-detail-action" onClick={openMap}>
            导航
          </Text>
        </View>

        <Text className="store-detail-meta">
          营业时间:{' '}
          {(() => {
            const parts: string[] = [];
            if (store.openTime && store.closeTime) parts.push(`${store.openTime}-${store.closeTime}`);
            if (store.openTime2 && store.closeTime2) parts.push(`${store.openTime2}-${store.closeTime2}`);
            return parts.length ? parts.join('，') : '10:00-22:00';
          })()}
        </Text>
        {store.avgPrice != null && Number(store.avgPrice) > 0 ? (
          <Text className="store-detail-meta">人均约 ¥{Number(store.avgPrice).toFixed(0)}</Text>
        ) : null}

        {store.phone ? (
          <View className="store-detail-row">
            <Text className="store-detail-meta store-detail-meta--flex">
              电话: {maskPhone(store.phone)}
            </Text>
            <Text className="store-detail-action" onClick={callStore}>
              拨打
            </Text>
          </View>
        ) : null}

        <View className="store-detail-tags">
          {store.category?.name ? (
            <Text className="store-detail-tag">{store.category.name}</Text>
          ) : null}
          <Text className="store-detail-tag">可核销</Text>
          <Text className="store-detail-tag">好客门店</Text>
        </View>
      </View>

      {marqueeLines.length > 0 ? (
        <View className="store-detail-marquee-wrap">
          <StoreRedeemMarquee key={marqueeLines.join('|')} lines={marqueeLines} />
        </View>
      ) : null}

      {packages.length > 0 ? (
        <View className="store-detail-section store-detail-section--packages">
          <Text className="store-detail-section-title">门店套餐</Text>
          <View className="store-detail-package-list">
            {packages.map((pkg, index) => (
              <View
                key={`${pkg.name}-${index}`}
                className="store-detail-package-list-item"
                onClick={() => openPackageDetail(index)}
              >
                <View className="store-detail-package-list-row">
                  <Text className="store-detail-package-list-title">{pkg.name}</Text>
                  <Text className="store-detail-package-list-price">
                    &nbsp;&nbsp;&nbsp;&nbsp;¥{formatPackagePriceYuan(pkg.price)}
                  </Text>
                </View>
              </View>
            ))}
          </View>
        </View>
      ) : null}

      {intro ? (
        <View className="store-detail-section">
          <Text className="store-detail-section-title">门店详情</Text>
          <Text className="store-detail-intro">{intro}</Text>
        </View>
      ) : null}

      {benefitRule ? (
        <View className="store-detail-section">
          <Text className="store-detail-section-title">好客权益券使用规则</Text>
          <Text className="store-detail-intro">{benefitRule}</Text>
        </View>
      ) : null}

      {envPhotos.length > 0 ? (
        <View className="store-detail-section">
          <Text className="store-detail-section-title">店内环境</Text>
          <View className="store-detail-env-grid">
            {envPhotos.map((url, index) => (
              <View
                key={`${url}-${index}`}
                className="store-detail-env-item"
                onClick={() => previewEnv(index)}
              >
                <Image className="store-detail-env-img" src={url} mode="widthFix" />
              </View>
            ))}
          </View>
        </View>
      ) : null}

      <View className="store-detail-bar">
        <View
          className="u-btn u-btn--block"
          onClick={() => Taro.navigateTo({ url: '/pages/redeem/index' })}
        >
          <Text>到店核销</Text>
        </View>
      </View>
    </PageShell>
  );
}
