import { useCallback, useEffect, useMemo, useState } from 'react';
import { View, Text, Image, Input } from '@tarojs/components';
import Taro, { useDidShow, usePullDownRefresh } from '@tarojs/taro';
import PageShell from '../../components/PageShell';
import TabMainHeader from '../../components/TabMainHeader';
import RegionPicker from '../../components/RegionPicker';
import CategoryPicker, {
  EMPTY_CATEGORY,
  formatCategoryLabel,
  type CategorySelection,
  type StoreCategoryNode,
} from '../../components/CategoryPicker';
import {
  DEFAULT_REGION,
  formatRegionLabel,
  matchesRegionFilter,
  type RegionSelection,
} from '../../lib/region-data';
import UserTabBar, { shouldRenderPageTabBar, syncTabBarSelected } from '../../components/UserTabBar';
import { getCityCodeForCatalog, resolveUserCity } from '../../lib/user-location';
import { FALLBACK_CITY_CODE } from '../../lib/product-images';
import { request, toast } from '../../lib/api';

type Store = {
  id: string;
  name: string;
  address?: string;
  province?: string;
  cityName?: string;
  district?: string;
  coverUrl?: string | null;
  openTime?: string | null;
  closeTime?: string | null;
  status?: string;
  categoryId?: string | null;
  category?: { id?: string; name?: string; parentId?: string | null } | null;
};

const MOCK_DISTANCES = ['800m', '1.2km', '3.5km', '1.5km', '2.0km'];

export default function StoresPage() {
  const [stores, setStores] = useState<Store[]>([]);
  const [loading, setLoading] = useState(true);
  const [keywordInput, setKeywordInput] = useState('');
  const [keyword, setKeyword] = useState('');
  const [region, setRegion] = useState<RegionSelection>(DEFAULT_REGION);
  const [regionOpen, setRegionOpen] = useState(false);
  const [category, setCategory] = useState<CategorySelection>(EMPTY_CATEGORY);
  const [categoryOpen, setCategoryOpen] = useState(false);
  const [categoryTree, setCategoryTree] = useState<StoreCategoryNode[]>([]);
  const [cityCode, setCityCode] = useState<string>(FALLBACK_CITY_CODE);
  const regionLabel = formatRegionLabel(region);
  const categoryLabel = formatCategoryLabel(category);

  const childIdsByParent = useMemo(() => {
    const map = new Map<string, string[]>();
    for (const root of categoryTree) {
      map.set(
        root.id,
        (root.children ?? []).map((c) => c.id),
      );
    }
    return map;
  }, [categoryTree]);

  useDidShow(() => {
    syncTabBarSelected(1);
    void resolveUserCity().then((resolved) => {
      setRegion(resolved.region);
      setCityCode(getCityCodeForCatalog(resolved));
    });
  });

  useEffect(() => {
    void request<StoreCategoryNode[]>('/store-categories')
      .then((tree) => setCategoryTree(Array.isArray(tree) ? tree : []))
      .catch(() => setCategoryTree([]));
  }, []);

  const loadStores = useCallback(() => {
    setLoading(true);
    const path = cityCode ? `/stores?cityCode=${encodeURIComponent(cityCode)}` : '/stores';
    return request<Store[]>(path)
      .then((list) => setStores(Array.isArray(list) ? list : []))
      .catch((e) => toast(e instanceof Error ? e.message : '加载失败'))
      .finally(() => setLoading(false));
  }, [cityCode]);

  useEffect(() => {
    void loadStores();
  }, [loadStores]);

  usePullDownRefresh(() => {
    void (async () => {
      try {
        const resolved = await resolveUserCity();
        setRegion(resolved.region);
        const nextCode = getCityCodeForCatalog(resolved);
        setCityCode(nextCode);
        setLoading(true);
        const path = nextCode ? `/stores?cityCode=${encodeURIComponent(nextCode)}` : '/stores';
        const list = await request<Store[]>(path);
        setStores(Array.isArray(list) ? list : []);
      } catch (e) {
        toast(e instanceof Error ? e.message : '加载失败');
      } finally {
        setLoading(false);
        Taro.stopPullDownRefresh();
      }
    })();
  });

  function matchesCategory(store: Store): boolean {
    if (!category.parentId) return true;
    const storeCatId = String(store.categoryId || store.category?.id || '');
    const storeParentId = String(store.category?.parentId || '');
    if (category.childId) {
      return storeCatId === category.childId;
    }
    if (storeParentId && storeParentId === category.parentId) return true;
    const siblings = childIdsByParent.get(category.parentId) ?? [];
    return siblings.includes(storeCatId);
  }

  const filtered = stores.filter((s) => {
    if (!matchesRegionFilter(s, region)) return false;
    if (!matchesCategory(s)) return false;
    if (!keyword.trim()) return true;
    const q = keyword.trim();
    return s.name.includes(q) || (s.address ?? '').includes(q) || (s.district ?? '').includes(q);
  });

  function applySearch() {
    setKeyword(keywordInput.trim());
  }

  function resetFilters() {
    setKeywordInput('');
    setKeyword('');
    setCategory(EMPTY_CATEGORY);
    setRegion(DEFAULT_REGION);
  }

  function formatHours(store: Store) {
    if (store.openTime && store.closeTime) {
      return `营业时间: ${store.openTime}-${store.closeTime}`;
    }
    return '营业时间: 10:00-22:00';
  }

  return (
    <PageShell variant="tab" className="store-page no-tab-header">
      <TabMainHeader title="门店" />

      <View className="store-filter">
        <View className="store-search-row">
          <Input
            className="store-search-input"
            placeholder="搜索门店名称/地址"
            value={keywordInput}
            confirmType="search"
            onInput={(e) => setKeywordInput(e.detail.value)}
            onConfirm={applySearch}
          />
          <View className="store-search-btn" onClick={applySearch} aria-label="搜索">
            <View className="store-search-icon" />
          </View>
        </View>

        <View className="store-filter-row">
          <View className="store-filter-chip" onClick={() => setRegionOpen(true)}>
            <Text className="store-filter-chip-text">{regionLabel}</Text>
            <Text className="store-filter-chip-arrow">▾</Text>
          </View>
          <View className="store-filter-chip" onClick={() => setCategoryOpen(true)}>
            <Text className="store-filter-chip-text">{categoryLabel}</Text>
            <Text className="store-filter-chip-arrow">▾</Text>
          </View>
          <Text className="store-filter-reset" onClick={resetFilters}>
            重置
          </Text>
        </View>
      </View>

      <View className="store-list">
        {loading ? <View className="u-empty">加载中…</View> : null}
        {!loading && filtered.length === 0 ? <View className="u-empty">暂无营业中门店</View> : null}
        {!loading &&
          filtered.map((s, index) => (
            <View
              key={s.id}
              className="store-card"
              onClick={() => Taro.navigateTo({ url: `/pages/store-detail/index?id=${s.id}` })}
            >
              {s.coverUrl ? (
                <Image className="store-card-cover" src={s.coverUrl} mode="aspectFill" />
              ) : (
                <View className="store-card-cover--empty" />
              )}
              <View className="store-card-body">
                <Text className="store-card-name">{s.name}</Text>
                <Text className="store-card-meta">
                  {s.district ? `${s.district} · ` : ''}
                  {s.address || '地址待完善'}
                </Text>
                <Text className="store-card-meta">{formatHours(s)}</Text>
                <View className="store-card-footer">
                  <Text className="store-card-distance">{MOCK_DISTANCES[index % MOCK_DISTANCES.length]}</Text>
                  <Text
                    className="store-card-cta"
                    onClick={(e) => {
                      e.stopPropagation();
                      Taro.navigateTo({ url: '/pages/redeem/index' });
                    }}
                  >
                    去核销
                  </Text>
                </View>
              </View>
            </View>
          ))}
      </View>

      {shouldRenderPageTabBar() ? <UserTabBar selected={1} /> : null}
      <RegionPicker
        open={regionOpen}
        value={region}
        levels={3}
        onClose={() => setRegionOpen(false)}
        onConfirm={(next) => setRegion(next)}
      />
      <CategoryPicker
        open={categoryOpen}
        tree={categoryTree}
        value={category}
        onClose={() => setCategoryOpen(false)}
        onConfirm={(next) => setCategory(next)}
      />
    </PageShell>
  );
}
