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 WechatShareReady from '../../components/WechatShareReady';
import { request, toast } from '../../lib/api';
import {
  DEFAULT_SHARE_DESC,
  DEFAULT_SHARE_TITLE,
  toWeappShareMessage,
} from '../../lib/wechat-share';

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

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;
  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;
};

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) {
  const d = input ? new Date(input) : new Date();
  if (Number.isNaN(d.getTime())) {
    // 后端若已是 "2026-08-03 15:14:30" 直接展示
    const s = String(input || '').trim();
    if (/^\d{4}-\d{2}-\d{2}/.test(s)) return s.slice(0, 19).replace('T', ' ');
    return '—';
  }
  const parts = new Intl.DateTimeFormat('en-CA', {
    timeZone: 'Asia/Shanghai',
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit',
    hour12: false,
  }).formatToParts(d);
  const get = (type: Intl.DateTimeFormatPartTypes) =>
    parts.find((p) => p.type === type)?.value ?? '';
  return `${get('year')}-${get('month')}-${get('day')} ${get('hour')}:${get('minute')}:${get('second')}`;
}

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) {
  return `${row.userLabel || '用户***'} ${formatRedeemTime(row.createdAt)} 核销${formatRedeemAmountYuan(row.amount)}元`;
}

function normalizeRecentRedeems(payload: unknown): RecentRedeem[] {
  if (Array.isArray(payload)) return payload as RecentRedeem[];
  if (payload && typeof payload === 'object') {
    const list = (payload as { list?: unknown; items?: unknown }).list
      ?? (payload as { items?: unknown }).items;
    if (Array.isArray(list)) return list as RecentRedeem[];
  }
  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 {
        title: store?.name || DEFAULT_SHARE_TITLE,
        desc: store?.intro?.trim() || store?.address || DEFAULT_SHARE_DESC,
        path: `/pages/store-detail/index?id=${storeId}`,
        imgUrl: store?.coverUrl || envFirst || store?.carouselUrls?.[0] || undefined,
      };
    },
    [store, storeId],
  );

  const marqueeText = useMemo(() => {
    if (!recentRedeems.length) return '';
    return recentRedeems.map(formatRecentRedeemLine).join('　　');
  }, [recentRedeems]);

  useShareAppMessage(() => toWeappShareMessage(sharePayload));
  useShareTimeline(() => ({
    title: sharePayload.title || DEFAULT_SHARE_TITLE,
    query: storeId ? `id=${storeId}` : '',
    imageUrl: sharePayload.imgUrl,
  }));

  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;
    }
    Taro.makePhoneCall({ phoneNumber: 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 images = uniqueUrls([
    store.coverUrl,
    ...(store.carouselUrls || []),
    ...envPhotos,
  ]);

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

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

  const marqueeDurationSec = Math.max(18, Math.min(60, Math.round((marqueeText.length || 24) / 2.2)));

  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={images} alt={store.name} variant="store" />
      </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">电话: {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>

      {marqueeText ? (
        <View className="store-detail-marquee">
          <View
            className="store-detail-marquee-track"
            style={{
              animationDuration: `${marqueeDurationSec}s`,
            }}
          >
            <View className="store-detail-marquee-item">{marqueeText}</View>
            <View className="store-detail-marquee-item">{marqueeText}</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="aspectFill" />
              </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>
  );
}
