import { router } from 'expo-router';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { ScrollView, StyleSheet, View, type NativeScrollEvent, type NativeSyntheticEvent } from 'react-native';

import {
  CategoryTabs,
  CommunityGrid,
  FeatureCarousel,
  Header,
  PageLayout,
  SectionHeader,
  StatusBarSpacer,
  type CommunityItem,
  type FeatureItem
} from '@/components/bestai';
import type { FeatureItem as FeatureItemType } from '@/components/bestai/feature-carousel';
import { useAuth } from '@/hooks/use-auth';
import { useAuthGuard } from '@/hooks/use-auth-guard';
import { getActivities, type Activity } from '@/lib/api/activities';
import { categoriesWithChildren } from '@/lib/api/categories-with-children';
import type { CategoryTemplate, CategoryWithChildren } from '@/lib/types/template';

function coalesceText(...values: Array<string | null | undefined>): string {
  for (const value of values) {
    const trimmed = (value ?? '').trim();
    if (trimmed.length > 0) {
      return trimmed;
    }
  }
  return '';
}

function translateTemplateToCommunity(template: CategoryTemplate): CommunityItem | null {
  const image = coalesceText(template.coverImageUrl, template.previewUrl);
  const title = coalesceText(template.titleEn, template.title);
  if (!image || !title) {
    return null;
  }

  const primaryTag = template.tags?.[0];
  const chip = coalesceText(primaryTag?.nameEn, primaryTag?.name, template.aspectRatio) || 'Featured';

  return {
    id: template.id,
    title,
    image,
    chip,
    actionLabel: 'Generate',
  };
}

function translateActivity(activity: Activity): FeatureItem | null {
  const image = (activity.coverUrl || '').trim();
  const title = (activity.titleEn || '').trim() || (activity.title || '').trim();
  if (!image || !title) {
    return null;
  }

  const subtitle = (activity.descEn || '').trim() || (activity.desc || '').trim();

  return {
    id: activity.id,
    title,
    subtitle,
    image,
  };
}

export default function ExploreScreen() {
  const { isAuthenticated } = useAuth();
  const { requireAuth } = useAuthGuard();
  const [activeCategory, setActiveCategory] = useState<string>('');
  const [activityFeatures, setActivityFeatures] = useState<FeatureItem[]>([]);
  const [categoryCollection, setCategoryCollection] = useState<CategoryWithChildren[]>([]);

  const scrollViewRef = useRef<ScrollView>(null);
  const categoryPositionsRef = useRef<Map<string, number>>(new Map());
  const isScrollingProgrammaticallyRef = useRef(false);

  useEffect(() => {
    const hydrateFeatureCarousel = async () => {
      try {
        const activities = await getActivities({ isActive: true });
        const curatedFeatures = activities
          .map(translateActivity)
          .filter((feature): feature is FeatureItem => feature !== null);
        if (curatedFeatures.length > 0) {
          setActivityFeatures(curatedFeatures);
        }
      } catch (error) {
        const detail = error instanceof Error ? error.message : String(error);
        console.warn('FeatureCarousel activities feed unavailable:', detail);
      }
    };

    hydrateFeatureCarousel();
  }, []);

  useEffect(() => {
    let isActive = true;

    const hydrateCategories = async () => {
      try {
        const response = await categoriesWithChildren();
        if (!isActive) {
          return;
        }

        const payload = response.success && Array.isArray(response.data) ? response.data : [];
        const curated = payload.filter((category) => category.id && (category.isActive ?? true));

        setCategoryCollection(curated.length > 0 ? curated : payload);
      } catch (error) {
        if (isActive) {
          const detail = error instanceof Error ? error.message : String(error);
          console.warn('Categories feed unavailable:', detail);
        }
      }
    };

    hydrateCategories();

    return () => {
      isActive = false;
    };
  }, [isAuthenticated]);

  useEffect(() => {
    if (categoryCollection.length === 0) {
      return;
    }

    const hasActive = categoryCollection.some((category) => category.id === activeCategory);
    if (!hasActive) {
      setActiveCategory(categoryCollection[0].id);
    }
  }, [categoryCollection, activeCategory]);

  const categoryOptions = useMemo(() => {
    if (categoryCollection.length === 0) {
      return [];
    }

    const options = categoryCollection
      .map((category) => {
        const label = coalesceText(category.nameEn, category.name);
        return label
          ? {
            id: category.id,
            label,
          }
          : null;
      })
      .filter((category): category is { id: string; label: string } => category !== null);

    return options.length > 0 ? options : [];
  }, [categoryCollection]);

  const allCategoriesWithTemplates = useMemo(() => {
    return categoryCollection.map((category) => {
      const templates = (category.templates ?? [])
        .map(translateTemplateToCommunity)
        .filter((item): item is CommunityItem => item !== null);

      return {
        id: category.id,
        name: coalesceText(category.nameEn, category.name),
        templates,
      };
    });
  }, [categoryCollection]);

  const handleScroll = useCallback((event: NativeSyntheticEvent<NativeScrollEvent>) => {
    if (isScrollingProgrammaticallyRef.current) {
      return;
    }

    const scrollY = event.nativeEvent.contentOffset.y;
    const positions = Array.from(categoryPositionsRef.current.entries());

    let newActiveCategory = activeCategory;
    for (let i = positions.length - 1; i >= 0; i--) {
      const [categoryId, position] = positions[i];
      if (scrollY >= position - 100) {
        newActiveCategory = categoryId;
        break;
      }
    }

    if (newActiveCategory !== activeCategory) {
      setActiveCategory(newActiveCategory);
    }
  }, [activeCategory]);

  const handleCategoryChange = useCallback((categoryId: string) => {
    const targetPosition = categoryPositionsRef.current.get(categoryId);
    if (targetPosition === undefined) {
      return;
    }

    isScrollingProgrammaticallyRef.current = true;
    scrollViewRef.current?.scrollTo({
      y: targetPosition,
      animated: true,
    });

    setTimeout(() => {
      isScrollingProgrammaticallyRef.current = false;
    }, 500);

    setActiveCategory(categoryId);
  }, []);

  const handleGeneratePress = useCallback((item: CommunityItem) => {
    requireAuth(() => {
      const templateId = item.id.split('-').pop() || item.id;
      router.push(`/templates/${templateId}`);
    });
  }, [requireAuth]);

  const handleFeaturePress = useCallback((item: FeatureItemType) => {
    requireAuth(() => {
      // TODO: 实现功能逻辑
    });
  }, [requireAuth]);

  return (
    <PageLayout backgroundColor="#050505" topInset="none">
      <StatusBarSpacer />
      <Header />
      <CategoryTabs
        categories={categoryOptions}
        activeId={activeCategory}
        onChange={handleCategoryChange}
      />
      <ScrollView
        ref={scrollViewRef}
        style={styles.scroll}
        contentContainerStyle={styles.contentContainer}
        showsVerticalScrollIndicator={false}
        onScroll={handleScroll}
        scrollEventThrottle={16}
      >
        {activityFeatures.length > 0 && (
          <FeatureCarousel
            items={activityFeatures}
            onPress={handleFeaturePress}
          />
        )}
        {allCategoriesWithTemplates.map((category, index) => (
          <View
            key={category.id}
            onLayout={(event) => {
              const layout = event.nativeEvent.layout;
              categoryPositionsRef.current.set(category.id, layout.y);
            }}
          >
            <SectionHeader title={category.name} />
            <CommunityGrid
              items={category.templates.map((template, idx) => ({
                ...template,
                id: `${category.id}-${template.id || idx}`,
              }))}
              onPressAction={handleGeneratePress}
            />
          </View>
        ))}
      </ScrollView>
    </PageLayout>
  );
}

const styles = StyleSheet.create({
  scroll: {
    flex: 1,
  },
  contentContainer: {
    paddingBottom: 16,
  },
});
