import { useEffect, useMemo, useState } from 'react';
import { FlatList, Pressable, StyleSheet, View } from 'react-native';
import { Image } from 'expo-image';
import { ThemedText } from '@/components/themed-text';
import { ThemedView } from '@/components/themed-view';
import { ExternalLink } from '@/components/external-link';
import { Colors, Fonts } from '@/constants/theme';
import { useTranslation } from '@/localization/i18n';
import { useColorScheme } from '@/hooks/use-color-scheme';

const BASE_URL = 'https://simplico.net/wp-json/wp/v2';
const CATEGORY_SLUG = 'blogs';
const PER_PAGE = 10;

type Post = {
  id: number;
  link: string;
  date: string;
  title: { rendered: string };
  excerpt: { rendered: string };
  _embedded?: {
    'wp:featuredmedia'?: Array<{
      source_url?: string;
    }>;
  };
};

type Category = {
  id: number;
  name: string;
  link: string;
};

export default function BlogScreen() {
  const { t } = useTranslation();
  const theme = useColorScheme() ?? 'light';
  const palette = Colors[theme];
  const [posts, setPosts] = useState<Post[]>([]);
  const [status, setStatus] = useState<'loading' | 'ready' | 'error'>('loading');
  const [categoryId, setCategoryId] = useState<number | null>(null);
  const [categories, setCategories] = useState<Category[]>([]);
  const [page, setPage] = useState(1);
  const [loadingMore, setLoadingMore] = useState(false);
  const [totalPages, setTotalPages] = useState<number | null>(null);
  const [loadMoreDebug, setLoadMoreDebug] = useState('');
  const [langFilter, setLangFilter] = useState<'en' | 'th' | 'ja' | 'zh'>('en');

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

    async function loadPosts() {
      try {
        const fetchedCategoryId = await fetchCategoryId(CATEGORY_SLUG);
        if (!fetchedCategoryId) {
          setPosts([]);
          setCategories([]);
          setStatus('ready');
          return;
        }
        setCategoryId(fetchedCategoryId);
        const categoryList = await fetchChildCategories(fetchedCategoryId);
        setCategories(categoryList);
        const response = await fetch(
          `${BASE_URL}/posts?per_page=${PER_PAGE}&page=1&_embed=1&cat=9&orderby=modified&order=desc`
        );
        if (!response.ok) {
          throw new Error(`HTTP ${response.status}`);
        }
        const data = (await response.json()) as Post[];
        if (!isActive) return;
        setPosts(data);
        setPage(1);
        setTotalPages(readTotalPages(response));
        setStatus('ready');
      } catch {
        if (isActive) setStatus('error');
      }
    }

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

  const filteredPosts = useMemo(() => {
    if (langFilter === 'en') {
      return posts.filter((post) => detectLangFromUrl(post.link) === 'en');
    }
    return posts.filter((post) => detectLangFromUrl(post.link) === langFilter);
  }, [langFilter, posts]);

  const statusText =
    status === 'loading'
      ? t('blog.loading')
      : status === 'error'
        ? t('blog.error')
        : filteredPosts.length === 0
          ? t('blog.empty')
          : '';

  const canLoadMore = useMemo(() => {
    if (status !== 'ready') return false;
    if (!totalPages) return false;
    return page < totalPages;
  }, [page, status, totalPages]);

  async function handleLoadMore() {
    if (!categoryId || loadingMore || !canLoadMore) return;
    setLoadingMore(true);
    setLoadMoreDebug('');
    try {
      const nextPage = page + 1;
      setLoadMoreDebug(
        `Requesting page ${nextPage}/${totalPages ?? '?'} (category ${categoryId})`
      );
      const response = await fetch(
        `${BASE_URL}/posts?per_page=${PER_PAGE}&page=${nextPage}&_embed=1&cat=9&orderby=modified&order=desc`
      );
      if (!response.ok) {
        const body = await response.json().catch(() => null);
        if (body?.code === 'rest_post_invalid_page_number') {
          setTotalPages(page);
          setLoadMoreDebug(`No more pages. Server says page ${nextPage} is invalid.`);
          return;
        }
        setLoadMoreDebug(`HTTP ${response.status}`);
        throw new Error(`HTTP ${response.status}`);
      }
      const data = (await response.json()) as Post[];
      setPosts((prev) => mergeUniquePosts(prev, data));
      setPage(nextPage);
      setTotalPages(readTotalPages(response));
      setLoadMoreDebug(
        `Loaded ${data.length} posts. Total pages: ${readTotalPages(response) ?? '?'}`
      );
    } finally {
      setLoadingMore(false);
    }
  }

  return (
    <FlatList
      data={filteredPosts}
      keyExtractor={(item) => String(item.id)}
      renderItem={({ item }) => (
        <ThemedView style={[styles.card, { backgroundColor: palette.card, borderColor: palette.border }]}>
          {getFeaturedImage(item) ? (
            <Image
              source={{ uri: getFeaturedImage(item) }}
              style={styles.featuredImage}
              contentFit="cover"
            />
          ) : null}
          <ExternalLink href={item.link}>
            <ThemedText type="subtitle">{stripTags(item.title.rendered)}</ThemedText>
          </ExternalLink>
          <ThemedText style={styles.meta}>{formatDate(item.date)}</ThemedText>
          <ThemedText>{truncateText(stripTags(item.excerpt.rendered), 160)}</ThemedText>
          <View style={styles.readMore}>
            <ExternalLink href={item.link}>
              <ThemedText type="link">Read more</ThemedText>
            </ExternalLink>
          </View>
        </ThemedView>
      )}
      ItemSeparatorComponent={() => <View style={styles.separator} />}
      ListHeaderComponent={
        <View>
          <ThemedView style={styles.hero}>
            <Image
              source={require('@/assets/images/blogpost.jpg')}
              style={styles.heroImage}
              contentFit="cover"
            />
          </ThemedView>
          <ThemedView style={styles.titleContainer}>
            <ThemedText type="title" style={{ fontFamily: Fonts.rounded }}>
              {t('blog.title')}
            </ThemedText>
          </ThemedView>

          {statusText ? (
            <ThemedView style={styles.section}>
              <ThemedText>{statusText}</ThemedText>
            </ThemedView>
          ) : null}

          {categories.length > 0 ? (
            <ThemedView style={styles.section}>
              <ThemedText type="subtitle">Categories</ThemedText>
              <View style={styles.categoryRow}>
                {categories.map((category) => (
                  <ExternalLink key={category.id} href={category.link} asChild>
                    <Pressable
                      style={[
                        styles.categoryBadge,
                        { borderColor: palette.border, backgroundColor: palette.surface },
                      ]}>
                      <ThemedText style={styles.categoryBadgeText}>{category.name}</ThemedText>
                    </Pressable>
                  </ExternalLink>
                ))}
              </View>
            </ThemedView>
          ) : null}

          <ThemedView style={styles.section}>
            <ThemedText type="subtitle">{t('blog.language')}</ThemedText>
            <View style={styles.segmented}>
              {(['en', 'th', 'ja', 'zh'] as const).map((lang) => (
                <Pressable
                  key={lang}
                  onPress={() => setLangFilter(lang)}
                  style={[
                    styles.segmentItem,
                    { borderColor: palette.border },
                    lang === langFilter
                      ? { borderColor: palette.success, backgroundColor: palette.surface }
                      : undefined,
                  ]}>
                  <ThemedText
                    style={[
                      styles.segmentText,
                      lang === langFilter ? [styles.segmentTextActive, { color: palette.success }] : undefined,
                    ]}>
                    {labelForLang(t, lang)}
                  </ThemedText>
                </Pressable>
              ))}
            </View>
          </ThemedView>
        </View>
      }
      ListFooterComponent={
        loadingMore || loadMoreDebug ? (
          <View style={styles.footer}>
            {loadMoreDebug ? (
              <ThemedText style={styles.debugText}>{loadMoreDebug}</ThemedText>
            ) : null}
            {loadingMore ? <ThemedText>{t('blog.loadingMore')}</ThemedText> : null}
          </View>
        ) : (
          <View style={styles.footer} />
        )
      }
      onEndReached={() => {
        if (canLoadMore) {
          handleLoadMore();
        }
      }}
      onEndReachedThreshold={0.6}
      extraData={langFilter}
    />
  );
}

function readTotalPages(response: Response) {
  const value = response.headers.get('x-wp-totalpages');
  if (!value) return null;
  const parsed = Number(value);
  return Number.isFinite(parsed) ? parsed : null;
}

function mergeUniquePosts(existing: Post[], incoming: Post[]) {
  const map = new Map<number, Post>();
  for (const post of existing) map.set(post.id, post);
  for (const post of incoming) map.set(post.id, post);
  return Array.from(map.values());
}

async function fetchChildCategories(parentId: number) {
  const response = await fetch(`${BASE_URL}/categories?parent=${parentId}&per_page=100`);
  if (!response.ok) return [];
  return (await response.json()) as Category[];
}

async function fetchCategoryId(slug: string) {
  const response = await fetch(`${BASE_URL}/categories?slug=${encodeURIComponent(slug)}`);
  if (!response.ok) return null;
  const data = (await response.json()) as { id: number }[];
  return data.length > 0 ? data[0].id : null;
}

function stripTags(html: string) {
  return html.replace(/<[^>]*>/g, '').replace(/\s+/g, ' ').trim();
}

function truncateText(text: string, maxLength: number) {
  if (text.length <= maxLength) return text;
  return `${text.slice(0, maxLength - 1).trim()}…`;
}

function formatDate(value: string) {
  try {
    return new Date(value).toLocaleDateString();
  } catch {
    return value;
  }
}

function getFeaturedImage(post: Post) {
  return post._embedded?.['wp:featuredmedia']?.[0]?.source_url ?? '';
}

function labelForLang(t: (key: string) => string, lang: 'en' | 'th' | 'ja' | 'zh') {
  switch (lang) {
    case 'th':
      return t('blog.lang.th');
    case 'ja':
      return t('blog.lang.ja');
    case 'zh':
      return t('blog.lang.zh');
    default:
      return t('blog.lang.en');
  }
}

function detectLangFromUrl(url: string) {
  const lower = url.toLowerCase();
  let path = lower;
  try {
    const parsed = new URL(lower);
    path = parsed.pathname;
  } catch {
    path = lower;
  }
  if (/(^|\/)th(\/|$)/.test(path) || /-th(\/|$)/.test(path)) return 'th';
  if (/(^|\/)ja(\/|$)/.test(path) || /-ja(\/|$)/.test(path)) return 'ja';
  if (/(^|\/)zh(\/|$)/.test(path) || /-zh(\/|$)/.test(path)) return 'zh';
  return 'en';
}

const styles = StyleSheet.create({
  hero: {
    backgroundColor: '#E8E6DA',
    aspectRatio: 16 / 9,
    width: '100%',
  },
  heroImage: {
    width: '100%',
    height: '100%',
  },
  titleContainer: {
    flexDirection: 'row',
    gap: 8,
    paddingHorizontal: 16,
    paddingVertical: 12,
  },
  section: {
    gap: 8,
    marginBottom: 16,
    paddingHorizontal: 16,
  },
  card: {
    gap: 8,
    marginHorizontal: 16,
    padding: 12,
    borderRadius: 14,
    borderWidth: 1,
    borderColor: '#E1DACB',
    backgroundColor: '#FFFFFF',
  },
  featuredImage: {
    height: 180,
    width: '100%',
    borderRadius: 12,
  },
  meta: {
    opacity: 0.7,
  },
  readMore: {
    paddingTop: 4,
  },
  separator: {
    height: 12,
  },
  footer: {
    paddingTop: 8,
    paddingBottom: 24,
    paddingHorizontal: 16,
  },
  debugText: {
    fontSize: 12,
    opacity: 0.7,
    paddingBottom: 8,
  },
  categoryRow: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    gap: 6,
  },
  categoryBadge: {
    borderRadius: 9999,
    borderWidth: 1,
    borderColor: '#D9D1C2',
    backgroundColor: '#FFFFFF',
    paddingHorizontal: 10,
    paddingVertical: 4,
  },
  categoryBadgeText: {
    fontSize: 12,
    fontWeight: '600',
  },
  segmented: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    gap: 8,
  },
  segmentItem: {
    borderRadius: 999,
    borderWidth: 1,
    borderColor: '#C6C6C6',
    paddingHorizontal: 12,
    paddingVertical: 6,
  },
  segmentItemActive: {
    borderColor: '#1B8A5A',
    backgroundColor: '#E7F3EC',
  },
  segmentText: {
    fontSize: 14,
  },
  segmentTextActive: {
    fontWeight: '700',
    color: '#1B8A5A',
  },
});
