import { Image } from 'expo-image';
import { LinearGradient } from 'expo-linear-gradient';
import { router, useLocalSearchParams } from 'expo-router';
import { Settings, Trash2, X } from 'lucide-react-native';
import React, { useEffect, useState } from 'react';
import {
  ActivityIndicator,
  Alert,
  Modal,
  Platform,
  Pressable,
  ScrollView,
  StyleSheet,
  useWindowDimensions,
  View,
} from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { useTranslation } from 'react-i18next';

import { Icon } from '@/components/ui/icon';
import { Text } from '@/components/ui/text';
import { ScreenHeader } from '@/components/screen-header';
import { ScreenGutter } from '@/constants/layout';
import { useChapterDetail, useDeleteChapter } from '@/features/memoir/hooks';

// Life-Echo reading colors (from HTML reference)
const READING_COLORS = {
  background: '#F8F9FA',
  backgroundSepia: '#F2E8CF',
  primary: '#8177A6',
  onSurface: '#1b1b1f',
  onSurfaceVariant: '#48454e',
  divider: 'rgba(141, 140, 144, 0.2)',
  surfaceContainerHigh: '#e9e7ec',
  outlineVariant: 'rgba(121, 117, 127, 0.3)',
};

type FontSize = 'small' | 'default' | 'large';
type FontFamily = 'serif' | 'sans';
type BackgroundTheme = 'white' | 'sepia';

const FONT_SIZES: Record<FontSize, number> = {
  small: 16,
  default: 20,
  large: 24,
};

const LINE_HEIGHTS: Record<FontSize, number> = {
  small: 30,
  default: 38,
  large: 44,
};

const FONT_FAMILIES: Record<FontFamily, string> = {
  serif:
    Platform.select({ ios: 'Georgia', android: 'serif', default: 'serif' }) ??
    'serif',
  sans:
    Platform.select({
      ios: 'System',
      android: 'sans-serif',
      default: 'sans-serif',
    }) ?? 'sans-serif',
};

const BACKGROUND_COLORS: Record<BackgroundTheme, string> = {
  white: READING_COLORS.background,
  sepia: READING_COLORS.backgroundSepia,
};

function ChapterContent({
  sections,
  coverImageUrl,
  fontSize,
  fontFamily,
  backgroundColor,
}: {
  sections: { content: string; image: { url: string | null } | null }[];
  coverImageUrl: string | null;
  fontSize: FontSize;
  fontFamily: FontFamily;
  backgroundColor: BackgroundTheme;
}) {
  const { width } = useWindowDimensions();
  const contentWidth = Math.min(width - ScreenGutter * 2, 672);
  const heroAspectRatio = 4 / 5;
  const bodySize = FONT_SIZES[fontSize];
  const lineHeight = LINE_HEIGHTS[fontSize];
  const fontFam = FONT_FAMILIES[fontFamily];
  const bgColor = BACKGROUND_COLORS[backgroundColor];

  const [heroLoadFailed, setHeroLoadFailed] = useState(false);
  useEffect(() => {
    setHeroLoadFailed(false);
  }, [coverImageUrl]);
  const hasCoverImage = !!coverImageUrl && !heroLoadFailed;

  return (
    <>
      {/* Hero Image: 仅在有封面图且加载成功时显示，避免无图或加载失败时大片空白 */}
      {hasCoverImage && (
        <View
          style={{
            width: '100%',
            aspectRatio: heroAspectRatio,
            overflow: 'hidden',
          }}
        >
          <Image
            source={{ uri: coverImageUrl! }}
            alt="Chapter hero"
            onError={() => setHeroLoadFailed(true)}
            style={{
              width: '100%',
              height: '100%',
              objectFit: 'cover',
            }}
          />
          <LinearGradient
            colors={['transparent', bgColor]}
            locations={[0.3, 1]}
            style={{
              position: 'absolute',
              left: 0,
              right: 0,
              top: 0,
              bottom: 0,
            }}
          />
        </View>
      )}

      {/* Memoir Content */}
      <View
        style={{
          paddingHorizontal: ScreenGutter,
          marginTop: hasCoverImage ? -60 : 0,
          paddingTop: hasCoverImage ? 0 : 12,
          paddingBottom: 48,
          backgroundColor: bgColor,
        }}
      >
        <View
          style={{ maxWidth: contentWidth, alignSelf: 'center', width: '100%' }}
        >
          {(() => {
            const indent = '\u3000\u3000';
            let isFirstParagraph = true;

            return sections.flatMap((section, i) => {
              const text = section.content?.trim() ?? '';
              const hasImage = !!section.image?.url;
              if (!text && !hasImage) return [];

              const paragraphs = text
                ? text
                    .split(/\n\n+/)
                    .map((p) => p.trim())
                    .filter(Boolean)
                : [];

              const nodes: React.ReactNode[] = [];

              paragraphs.forEach((para, pIdx) => {
                const firstChar = para.charAt(0);
                const rest = para.slice(1);
                const isLastInSection =
                  pIdx === paragraphs.length - 1 && !hasImage;
                const mb = isLastInSection ? 20 : 16;

                if (isFirstParagraph && firstChar) {
                  const firstParaLineHeight = Math.round(lineHeight * 1.35);
                  nodes.push(
                    <Text
                      key={`${i}-${pIdx}`}
                      selectable
                      style={{
                        fontSize: bodySize,
                        lineHeight: firstParaLineHeight,
                        color: READING_COLORS.onSurfaceVariant,
                        fontFamily: fontFam,
                        marginBottom: mb,
                      }}
                    >
                      <Text
                        style={{
                          fontSize: bodySize * 2.2,
                          fontWeight: '700',
                          color: READING_COLORS.primary,
                          lineHeight: firstParaLineHeight,
                          fontFamily: fontFam,
                        }}
                      >
                        {firstChar}
                      </Text>
                      {rest}
                    </Text>,
                  );
                  isFirstParagraph = false;
                } else {
                  nodes.push(
                    <Text
                      key={`${i}-${pIdx}`}
                      selectable
                      style={{
                        fontSize: bodySize,
                        lineHeight,
                        color: READING_COLORS.onSurfaceVariant,
                        fontFamily: fontFam,
                        marginBottom: mb,
                      }}
                    >
                      {indent}
                      {para}
                    </Text>,
                  );
                }
              });

              if (hasImage) {
                nodes.push(
                  <Image
                    key={`${i}-img`}
                    source={{ uri: section.image!.url }}
                    style={{
                      width: '100%',
                      aspectRatio: 16 / 9,
                      borderRadius: 12,
                      marginTop: paragraphs.length > 0 ? 12 : 0,
                      marginBottom: 20,
                    }}
                  />,
                );
              }

              return nodes;
            });
          })()}

          {sections.length > 0 && (
            <View
              style={{
                paddingTop: 24,
                paddingBottom: 24,
                alignItems: 'center',
              }}
            >
              <View
                style={{
                  width: 96,
                  height: 1,
                  backgroundColor: READING_COLORS.divider,
                }}
              />
            </View>
          )}
        </View>
      </View>
    </>
  );
}

function ReadingSettingsModal({
  visible,
  onClose,
  fontSize,
  fontFamily,
  backgroundColor,
  onFontSizeChange,
  onFontFamilyChange,
  onBackgroundChange,
  t,
}: {
  visible: boolean;
  onClose: () => void;
  fontSize: FontSize;
  fontFamily: FontFamily;
  backgroundColor: BackgroundTheme;
  onFontSizeChange: (v: FontSize) => void;
  onFontFamilyChange: (v: FontFamily) => void;
  onBackgroundChange: (v: BackgroundTheme) => void;
  t: (key: string) => string;
}) {
  const insets = useSafeAreaInsets();

  return (
    <Modal
      visible={visible}
      animationType="slide"
      transparent
      onRequestClose={onClose}
    >
      <Pressable style={readingSettingsStyles.backdrop} onPress={onClose}>
        <Pressable
          style={[
            readingSettingsStyles.sheet,
            { paddingBottom: insets.bottom + 24 },
          ]}
          onPress={() => {}}
        >
          <View style={readingSettingsStyles.handle} />
          <View style={readingSettingsStyles.header}>
            <Text style={readingSettingsStyles.title}>
              {t('chapterReading.readingSettings')}
            </Text>
            <Pressable
              onPress={onClose}
              hitSlop={12}
              style={({ pressed }) => [
                readingSettingsStyles.closeBtn,
                pressed && { opacity: 0.6 },
              ]}
              accessibilityLabel={t('chapterReading.close')}
              accessibilityRole="button"
            >
              <Icon as={X} size={22} color={READING_COLORS.onSurfaceVariant} />
            </Pressable>
          </View>

          <View style={readingSettingsStyles.section}>
            <Text style={readingSettingsStyles.label}>
              {t('chapterReading.fontSize')}
            </Text>
            <View style={readingSettingsStyles.segmented}>
              {(['small', 'default', 'large'] as const).map((s) => (
                <Pressable
                  key={s}
                  onPress={() => onFontSizeChange(s)}
                  style={({ pressed }) => [
                    readingSettingsStyles.segItem,
                    fontSize === s && readingSettingsStyles.segItemActive,
                    pressed && { opacity: 0.8 },
                  ]}
                >
                  <Text
                    style={[
                      readingSettingsStyles.segText,
                      fontSize === s && readingSettingsStyles.segTextActive,
                    ]}
                  >
                    {t(
                      `chapterReading.fontSize${s.charAt(0).toUpperCase() + s.slice(1)}`,
                    )}
                  </Text>
                </Pressable>
              ))}
            </View>
          </View>

          <View style={readingSettingsStyles.section}>
            <Text style={readingSettingsStyles.label}>
              {t('chapterReading.typography')}
            </Text>
            <View style={readingSettingsStyles.segmented}>
              {(['serif', 'sans'] as const).map((f) => (
                <Pressable
                  key={f}
                  onPress={() => onFontFamilyChange(f)}
                  style={({ pressed }) => [
                    readingSettingsStyles.segItem,
                    fontFamily === f && readingSettingsStyles.segItemActive,
                    pressed && { opacity: 0.8 },
                  ]}
                >
                  <Text
                    style={[
                      readingSettingsStyles.segText,
                      fontFamily === f && readingSettingsStyles.segTextActive,
                      { fontFamily: FONT_FAMILIES[f] },
                    ]}
                  >
                    {t(
                      `chapterReading.font${f.charAt(0).toUpperCase() + f.slice(1)}`,
                    )}
                  </Text>
                </Pressable>
              ))}
            </View>
          </View>

          <View style={readingSettingsStyles.section}>
            <Text style={readingSettingsStyles.label}>
              {t('chapterReading.backgroundColor')}
            </Text>
            <View style={readingSettingsStyles.bgRow}>
              {(['white', 'sepia'] as const).map((theme) => (
                <Pressable
                  key={theme}
                  onPress={() => onBackgroundChange(theme)}
                  style={({ pressed }) => [
                    readingSettingsStyles.bgOption,
                    { backgroundColor: BACKGROUND_COLORS[theme] },
                    backgroundColor === theme &&
                      readingSettingsStyles.bgOptionActive,
                    pressed && { opacity: 0.9 },
                  ]}
                >
                  <View
                    style={[
                      readingSettingsStyles.bgSwatch,
                      { backgroundColor: BACKGROUND_COLORS[theme] },
                      theme === 'sepia' && {
                        borderColor: 'rgba(91,77,62,0.5)',
                      },
                    ]}
                  />
                  <Text
                    style={[
                      readingSettingsStyles.bgLabel,
                      theme === 'sepia' && { color: '#5B4D3E' },
                      backgroundColor === theme &&
                        readingSettingsStyles.bgLabelActive,
                    ]}
                  >
                    {t(
                      `chapterReading.bg${theme === 'white' ? 'PureWhite' : 'Sepia'}`,
                    )}
                  </Text>
                </Pressable>
              ))}
            </View>
          </View>
        </Pressable>
      </Pressable>
    </Modal>
  );
}

const readingSettingsStyles = StyleSheet.create({
  backdrop: {
    flex: 1,
    justifyContent: 'flex-end',
    backgroundColor: 'rgba(0,0,0,0.4)',
  },
  sheet: {
    backgroundColor: '#fff',
    borderTopLeftRadius: 16,
    borderTopRightRadius: 16,
    paddingTop: 8,
    paddingHorizontal: ScreenGutter,
    ...Platform.select({
      ios: {
        shadowColor: '#000',
        shadowOffset: { width: 0, height: -2 },
        shadowOpacity: 0.06,
        shadowRadius: 12,
      },
      android: { elevation: 12 },
    }),
  },
  handle: {
    alignSelf: 'center',
    width: 40,
    height: 4,
    borderRadius: 2,
    backgroundColor: 'rgba(0,0,0,0.2)',
    marginBottom: 16,
  },
  header: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    marginBottom: 20,
  },
  title: {
    fontSize: 17,
    fontWeight: '700',
    color: READING_COLORS.onSurface,
  },
  closeBtn: { padding: 8 },
  label: {
    fontSize: 11,
    fontWeight: '600',
    letterSpacing: 0.5,
    color: READING_COLORS.onSurfaceVariant,
    marginBottom: 10,
    textTransform: 'uppercase',
  },
  section: { marginBottom: 20 },
  segmented: {
    flexDirection: 'row',
    backgroundColor: '#eeeef0',
    borderRadius: 10,
    padding: 4,
  },
  segItem: {
    flex: 1,
    minHeight: 44,
    justifyContent: 'center',
    alignItems: 'center',
    borderRadius: 8,
  },
  segItemActive: {
    backgroundColor: READING_COLORS.primary,
  },
  segText: {
    fontSize: 14,
    fontWeight: '500',
    color: READING_COLORS.onSurfaceVariant,
  },
  segTextActive: {
    fontWeight: '700',
    color: '#fff',
  },
  bgRow: { flexDirection: 'row', gap: 12 },
  bgOption: {
    flex: 1,
    minHeight: 64,
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
    gap: 10,
    borderRadius: 10,
    borderWidth: 2,
    borderColor: 'transparent',
  },
  bgOptionActive: {
    borderColor: READING_COLORS.primary,
  },
  bgSwatch: {
    width: 28,
    height: 28,
    borderRadius: 6,
    borderWidth: 1,
    borderColor: 'rgba(0,0,0,0.1)',
  },
  bgLabel: {
    fontSize: 14,
    fontWeight: '500',
    color: READING_COLORS.onSurface,
  },
  bgLabelActive: { fontWeight: '700' },
});

export default function ChapterScreen() {
  const { id } = useLocalSearchParams<{ id: string }>();
  const insets = useSafeAreaInsets();
  const { t } = useTranslation('memoir');
  const { data: chapter, isLoading } = useChapterDetail(id ?? '');
  const deleteChapter = useDeleteChapter();

  const [settingsVisible, setSettingsVisible] = useState(false);
  const [fontSize, setFontSize] = useState<FontSize>('default');
  const [fontFamily, setFontFamily] = useState<FontFamily>('serif');
  const [backgroundColor, setBackgroundColor] =
    useState<BackgroundTheme>('white');

  const bgColor = BACKGROUND_COLORS[backgroundColor];

  if (isLoading) {
    return (
      <View
        style={{
          flex: 1,
          alignItems: 'center',
          justifyContent: 'center',
          backgroundColor: bgColor,
        }}
      >
        <ActivityIndicator size="large" color={READING_COLORS.primary} />
      </View>
    );
  }

  if (!chapter) {
    return (
      <View
        style={{
          flex: 1,
          alignItems: 'center',
          justifyContent: 'center',
          backgroundColor: bgColor,
          gap: 16,
        }}
      >
        <Text
          selectable
          style={{ color: READING_COLORS.onSurfaceVariant, fontSize: 16 }}
        >
          {t('chapterReading.chapterNotFound')}
        </Text>
        <Pressable
          onPress={() => router.back()}
          style={({ pressed }) => ({
            paddingHorizontal: 20,
            paddingVertical: 12,
            borderRadius: 12,
            backgroundColor: READING_COLORS.primary,
            opacity: pressed ? 0.8 : 1,
          })}
          accessibilityRole="button"
          accessibilityLabel={t('chapterReading.back')}
        >
          <Text
            style={{ color: '#fff', fontSize: 16, fontWeight: '600' }}
            selectable={false}
          >
            {t('chapterReading.back')}
          </Text>
        </Pressable>
      </View>
    );
  }

  const sections = chapter.sections ?? [];
  const coverImageUrl = chapter.cover_image?.url ?? null;

  const handleDeletePress = () => {
    Alert.alert(
      t('chapterReading.deleteChapter'),
      t('chapterReading.confirmDeleteMessage'),
      [
        { text: t('chapterReading.cancel'), style: 'cancel' },
        {
          text: t('chapterReading.deleteChapterAction'),
          style: 'destructive',
          onPress: () => {
            deleteChapter.mutate(chapter.id, {
              onSuccess: () => router.back(),
            });
          },
        },
      ],
    );
  };

  return (
    <View style={{ flex: 1, backgroundColor: bgColor }}>
      <ScreenHeader
        variant="reading"
        absolute
        backgroundColor={bgColor}
        title={chapter.title}
        backAccessibilityLabel={t('chapterReading.back')}
        right={
          <View style={{ flexDirection: 'row', alignItems: 'center', gap: 4 }}>
            <Pressable
              onPress={handleDeletePress}
              disabled={deleteChapter.isPending}
              style={({ pressed }) => ({
                padding: 8,
                borderRadius: 9999,
                opacity: pressed ? 0.7 : 1,
              })}
              accessibilityLabel={t('chapterReading.deleteChapter')}
              accessibilityRole="button"
            >
              <Icon
                as={Trash2}
                size={22}
                color={READING_COLORS.onSurfaceVariant}
              />
            </Pressable>
            <Pressable
              onPress={() => setSettingsVisible(true)}
              style={({ pressed }) => ({
                padding: 8,
                marginRight: -8,
                borderRadius: 9999,
                opacity: pressed ? 0.7 : 1,
              })}
              accessibilityLabel={t('chapterReading.settings')}
              accessibilityRole="button"
            >
              <Icon as={Settings} size={24} color={READING_COLORS.primary} />
            </Pressable>
          </View>
        }
      />

      {/* Scrollable content */}
      <ScrollView
        contentInsetAdjustmentBehavior="never"
        contentContainerStyle={{
          paddingTop: insets.top + 72,
        }}
        showsVerticalScrollIndicator={false}
        style={{ backgroundColor: bgColor }}
      >
        <ChapterContent
          sections={sections}
          coverImageUrl={coverImageUrl}
          fontSize={fontSize}
          fontFamily={fontFamily}
          backgroundColor={backgroundColor}
        />
      </ScrollView>

      <ReadingSettingsModal
        visible={settingsVisible}
        onClose={() => setSettingsVisible(false)}
        fontSize={fontSize}
        fontFamily={fontFamily}
        backgroundColor={backgroundColor}
        onFontSizeChange={setFontSize}
        onFontFamilyChange={setFontFamily}
        onBackgroundChange={setBackgroundColor}
        t={t as (key: string) => string}
      />
    </View>
  );
}
