import React, { useCallback, useEffect, useState } from 'react';
import {
  View,
  Text,
  ScrollView,
  Pressable,
  StyleSheet,
  Linking,
  Share,
} from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import type { PostSummary } from '@ai-radar/shared';
import { useTheme } from '../theme/ThemeProvider';
import { textStyle, space, radius } from '../theme';
import { getDict } from '../lib/dictionary';
import { getPost, ApiError, type PostPayload } from '../lib/api';
import { longDate } from '../lib/format';
import { CategoryLabel } from '../components/CategoryLabel';
import { SourceIcon } from '../components/SourceIcon';
import { StoryCard } from '../components/StoryCard';
import { SectionHeading } from '../components/SectionHeading';
import { Loading, ErrorState } from '../components/States';
import { useSaved } from '../lib/saved';

/**
 * A story.
 *
 * Same field order as the web story page, because the order IS the
 * briefing: what changed, why it matters, who should care. Anyone who
 * reads both should not have to re-learn where things are.
 */
export function StoryScreen({
  slug,
  onOpen,
}: {
  slug: string;
  onOpen: (post: PostSummary) => void;
}) {
  const { palette, locale, rtl } = useTheme();
  const dict = getDict(locale);
  const insets = useSafeAreaInsets();
  const { isSaved, toggle } = useSaved();

  const [data, setData] = useState<PostPayload | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [loading, setLoading] = useState(true);

  const load = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      setData(await getPost(slug, locale));
    } catch (err) {
      setError(err instanceof ApiError ? err.message : 'Something went wrong.');
    } finally {
      setLoading(false);
    }
  }, [slug, locale]);

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

  if (loading) return <Loading />;
  if (error || !data) return <ErrorState message={error ?? undefined} onRetry={() => void load()} />;

  const post = data.post;
  const align = rtl ? ('right' as const) : ('left' as const);
  const dir = rtl ? ('rtl' as const) : ('ltr' as const);
  const saved = isSaved(post.slug);

  const body = (text: string) => (
    <Text
      style={[
        textStyle('body', locale),
        { color: palette.text2, textAlign: align, writingDirection: dir },
      ]}
    >
      {text}
    </Text>
  );

  return (
    <ScrollView
      style={{ backgroundColor: palette.bg }}
      contentContainerStyle={[styles.content, { paddingBottom: insets.bottom + space.s10 }]}
    >
      <View style={[styles.head, { flexDirection: rtl ? 'row-reverse' : 'row' }]}>
        <CategoryLabel category={post.category} />
        <Text style={[textStyle('meta', locale), { color: palette.text3 }]} numberOfLines={1}>
          {longDate(post.publishedAt, locale)}
        </Text>
      </View>

      <Text
        style={[
          textStyle('display', locale),
          { color: palette.text, textAlign: align, writingDirection: dir, marginTop: space.s3 },
        ]}
      >
        {post.title}
      </Text>

      <Text
        style={[
          textStyle('body', locale),
          { color: palette.text2, textAlign: align, writingDirection: dir, marginTop: space.s4 },
        ]}
      >
        {post.summary}
      </Text>

      {/* Actions sit above the briefing: someone who already knows the
          headline should not have to scroll the whole story to save it. */}
      <View style={[styles.actions, { flexDirection: rtl ? 'row-reverse' : 'row' }]}>
        <Pressable
          onPress={() => toggle(post)}
          accessibilityRole="button"
          accessibilityState={{ selected: saved }}
          style={({ pressed }) => [
            styles.action,
            {
              borderColor: saved ? palette.accent : palette.border,
              // Border and colour carry the saved state; an accentQuiet
              // fill behind accent text is too low-contrast to read.
              opacity: pressed ? 0.7 : 1,
            },
          ]}
        >
          <Text
            style={[
              textStyle('meta', locale),
              { color: saved ? palette.accent : palette.text2 },
            ]}
          >
            {saved ? `✓ ${dict.unsave}` : dict.save}
          </Text>
        </Pressable>

        <Pressable
          onPress={() => void Share.share({ message: `${post.title}\n\n${post.sourceUrl}` })}
          accessibilityRole="button"
          style={({ pressed }) => [
            styles.action,
            { borderColor: palette.border, opacity: pressed ? 0.7 : 1 },
          ]}
        >
          <Text style={[textStyle('meta', locale), { color: palette.text2 }]}>
            {locale === 'ar' ? 'مشاركة' : 'Share'}
          </Text>
        </Pressable>
      </View>

      <View style={styles.block}>
        <SectionHeading title={dict.whatChanged} />
        {body(post.whatChanged)}
      </View>

      {/* Why it matters carries the accent rule: it is the one field that
          separates a briefing from a headline. */}
      <View
        style={[
          styles.why,
          { backgroundColor: palette.surface, borderStartColor: palette.accent },
        ]}
      >
        <Text style={[textStyle('label', locale), { color: palette.accent, textAlign: align }]}>
          {locale === 'ar' ? dict.whyItMatters : dict.whyItMatters.toUpperCase()}
        </Text>
        <Text
          style={[
            textStyle('body', locale),
            {
              color: palette.text,
              textAlign: align,
              writingDirection: dir,
              marginTop: space.s2,
            },
          ]}
        >
          {post.whyItMatters}
        </Text>
      </View>

      {post.whoShouldCare.length > 0 && (
        <View style={styles.block}>
          <SectionHeading title={dict.whoShouldCare} />
          {post.whoShouldCare.map((who) => (
            <View
              key={who}
              style={[styles.bullet, { flexDirection: rtl ? 'row-reverse' : 'row' }]}
            >
              <View style={[styles.dot, { backgroundColor: palette.accent }]} />
              <Text
                style={[
                  textStyle('bodySm', locale),
                  {
                    color: palette.text2,
                    textAlign: align,
                    writingDirection: dir,
                    flex: 1,
                  },
                ]}
              >
                {who}
              </Text>
            </View>
          ))}
        </View>
      )}

      {post.worthTrying === 'yes' && post.worthTryingNote ? (
        <View style={styles.block}>
          <SectionHeading title={dict.worthTrying} />
          {body(post.worthTryingNote)}
        </View>
      ) : null}

      <Pressable
        onPress={() => void Linking.openURL(post.sourceUrl)}
        accessibilityRole="link"
        style={({ pressed }) => [
          styles.source,
          { borderColor: palette.border, opacity: pressed ? 0.7 : 1 },
        ]}
      >
        <View style={[styles.sourceRow, { flexDirection: rtl ? 'row-reverse' : 'row' }]}>
          <SourceIcon src={post.sourceIconUrl} size={24} />
          <Text style={[textStyle('meta', locale), { color: palette.text3 }]} numberOfLines={1}>
            {post.sourceName}
          </Text>
        </View>
        <Text
          style={[textStyle('card', locale), { color: palette.accent, marginTop: space.s1 }]}
        >
          {dict.readSource} →
        </Text>
      </Pressable>

      {data.related.length > 0 && (
        <View style={[styles.block, { marginTop: space.section }]}>
          <SectionHeading title={dict.related} />
          {data.related.map((p) => (
            <StoryCard key={p.slug} post={p} variant="row" onPress={onOpen} />
          ))}
        </View>
      )}
    </ScrollView>
  );
}

const styles = StyleSheet.create({
  content: {
    paddingHorizontal: space.s4,
    paddingTop: space.s4,
  },
  head: {
    alignItems: 'center',
    justifyContent: 'space-between',
    gap: space.s2,
  },
  actions: {
    gap: space.s2,
    marginTop: space.s5,
    marginBottom: space.s6,
  },
  action: {
    paddingVertical: space.s2,
    paddingHorizontal: space.s4,
    borderRadius: radius.chip,
    borderWidth: StyleSheet.hairlineWidth,
  },
  block: {
    marginBottom: space.s6,
  },
  why: {
    padding: space.s4,
    borderRadius: radius.card,
    borderStartWidth: 3,
    marginBottom: space.s6,
  },
  bullet: {
    gap: space.s3,
    alignItems: 'flex-start',
    marginBottom: space.s2,
  },
  dot: {
    width: 5,
    height: 5,
    borderRadius: 3,
    marginTop: 8,
  },
  source: {
    padding: space.s4,
    borderRadius: radius.card,
    borderWidth: StyleSheet.hairlineWidth,
  },
  sourceRow: {
    alignItems: 'center',
    gap: 8,
  },
});
