/**
 * 交易详情页（plan.md「1.1 transaction/[id]」）。
 *
 * 从 ledger.transactions 按 id 查找,展示完整交易信息:
 * - 日期 / 摘要 / 对方 / flag
 * - 全部 postings(账户 / 金额 / 币种 / cost / price)
 * - 标签 / 链接 / 元数据
 * - 原始 .bean 文本
 */
import React, { useMemo, useState } from 'react';
import { Pressable, ScrollView, StyleSheet, Text, View, Alert, Modal, TextInput, FlatList } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { useLocalSearchParams, useRouter } from 'expo-router';
import { Ionicons } from '@expo/vector-icons';
import { useTheme, createCommonStyles } from '../../theme';
import { Card } from '../../components/Card';
import { useLedgerStore } from '../../store/ledgerStore';
import { useNumpadUiStore } from '../../store/numpadUiStore';
import { hash } from '../../domain/ledger';
import { useT } from '../../i18n';
import { TransactionCard } from '../../components/TransactionCard';
import { ScreenHeader } from '../../components/ScreenHeader';
import { logger } from '../../utils/logger';

export default function TransactionDetailScreen() {
  const { theme } = useTheme();
  const commonStyles = useMemo(() => createCommonStyles(theme), [theme]);
  const t = useT();
  const router = useRouter();
  const { id } = useLocalSearchParams<{ id: string }>();
  const ledger = useLedgerStore(s => s.ledger);

  const tx = useMemo(
    () => ledger?.transactions.find(txn => txn.id === id) ?? null,
    [ledger, id],
  );

  const [linkModalVisible, setLinkModalVisible] = useState(false);
  const [searchQuery, setSearchQuery] = useState('');

  const isEditable = tx ? tx.source.endsWith('main.bean') : false;

  // 找出所有共享同一个链接标签的关联交易
  const relatedTransactions = useMemo(() => {
    if (!ledger || !tx || !tx.links || tx.links.length === 0) return [];
    return ledger.transactions.filter(
      t => t.id !== id && t.links.some(l => tx.links.includes(l))
    );
  }, [ledger, id, tx?.links]);

  // 筛选可以用来关联的其他账单
  const linkableTransactions = useMemo(() => {
    if (!ledger) return [];
    const list = ledger.transactions
      .filter(t => t.id !== id && t.source.endsWith('main.bean') && !t.links.some(l => (tx?.links ?? []).includes(l)))
      .filter(t => {
        if (!searchQuery) return true;
        const q = searchQuery.toLowerCase();
        return (
          t.narration?.toLowerCase().includes(q) ||
          t.payee?.toLowerCase().includes(q) ||
          t.postings.some(p => p.account.toLowerCase().includes(q))
        );
      })
      .sort((a, b) => b.date.localeCompare(a.date)); // 显式按交易日期【由新到旧 (最新 ➔ 最旧)】严格倒序排列

    // 有搜索条件时展示最多 100 条匹配结果，无搜索词时默认展示最新 50 条
    return searchQuery ? list.slice(0, 100) : list.slice(0, 50);
  }, [ledger, id, tx?.links, searchQuery]);

  const handleLinkTransaction = async (targetTx: typeof tx) => {
    if (!tx || !targetTx) return;
    let linkTag = tx.links[0] || targetTx.links[0] || '';
    try {
      const { mobileBean, replaceMobileBean } = useLedgerStore.getState();
      
      // 取出已有链接标签，若没有则生成一个随机哈希标签
      if (!linkTag) {
        linkTag = 'lnk-' + Math.random().toString(36).slice(2, 8);
      }

      const addLinkToRaw = (raw: string, tag: string) => {
        const lines = raw.split('\n');
        const line = lines[0];
        const commentIndex = line.indexOf(';');
        
        if (line.includes(`^${tag}`)) {
          return raw;
        }
        
        if (commentIndex !== -1) {
          const beforeComment = line.substring(0, commentIndex).trimEnd();
          const commentPart = line.substring(commentIndex);
          lines[0] = `${beforeComment} ^${tag} ${commentPart}`;
        } else {
          lines[0] = line.trimEnd() + ` ^${tag}`;
        }
        return lines.join('\n');
      };

      const newCurrentRaw = addLinkToRaw(tx.raw, linkTag);
      const newTargetRaw = addLinkToRaw(targetTx.raw, linkTag);

      let newContent = mobileBean;
      newContent = newContent.replaceAll(tx.raw, newCurrentRaw);
      newContent = newContent.replaceAll(targetTx.raw, newTargetRaw);

      const formatTxSummary = (t: typeof tx) => {
        if (!t) return '';
        const postingDesc = t.postings.map(p => `${p.account} (${p.amount ?? ''} ${p.currency ?? ''})`.trim()).join(', ');
        return `[${t.date}] ${t.payee ? t.payee + ' - ' : ''}${t.narration} | 分录: [${postingDesc}] (ID: ${t.id})`;
      };

      await replaceMobileBean(newContent);
      logger.info('ledgerStore', `关联交易成功: 标签 ^${linkTag}\n【交易 1】: ${formatTxSummary(tx)}\n【交易 2】: ${formatTxSummary(targetTx)}`, {
        linkTag,
        transaction1: {
          id: tx.id,
          date: tx.date,
          payee: tx.payee,
          narration: tx.narration,
          postings: tx.postings,
        },
        transaction2: {
          id: targetTx.id,
          date: targetTx.date,
          payee: targetTx.payee,
          narration: targetTx.narration,
          postings: targetTx.postings,
        },
      });
      setLinkModalVisible(false);
      
      // 解决 race condition：直接使用 hash() 算法计算新 ID 避免读取旧状态导致的 404 白屏
      const newId = hash(`main.bean:${newCurrentRaw}`);
      if (newId && newId !== id) {
        router.replace(`/transaction/${newId}`);
      }
      Alert.alert(t('transaction.linkSuccess'), t('transaction.linkSuccessDesc', { tag: linkTag }));
    } catch (e) {
      logger.error('ledgerStore', `关联交易失败 (Tag: ^${linkTag})`, e);
      Alert.alert(t('transaction.linkFail'), String(e));
    }
  };

  const handleUnlink = async (linkTag: string) => {
    if (!tx) return;
    try {
      const { mobileBean, replaceMobileBean } = useLedgerStore.getState();
      
      // 找出所有携带此 linkTag 且属于 main.bean 的同伴交易并同步清除，避免悬空标签
      const companionTxs = (ledger?.transactions ?? []).filter(
        t => t.links.includes(linkTag) && t.source.endsWith('main.bean')
      );

      let newContent = mobileBean;
      let newCurrentRaw = tx.raw;

      for (const companion of companionTxs) {
        const lines = companion.raw.split('\n');
        lines[0] = lines[0].replace(new RegExp(`\\s*\\^${linkTag}\\b`, 'g'), '');
        const newRaw = lines.join('\n');
        
        newContent = newContent.replaceAll(companion.raw, newRaw);
        if (companion.id === tx.id) {
          newCurrentRaw = newRaw;
        }
      }

      const formatTxSummary = (t: typeof tx) => {
        if (!t) return '';
        const postingDesc = t.postings.map(p => `${p.account} (${p.amount ?? ''} ${p.currency ?? ''})`.trim()).join(', ');
        return `[${t.date}] ${t.payee ? t.payee + ' - ' : ''}${t.narration} | 分录: [${postingDesc}] (ID: ${t.id})`;
      };

      await replaceMobileBean(newContent);
      const unlinkedListStr = companionTxs.map(c => formatTxSummary(c)).join('\n  ');
      logger.info('ledgerStore', `解除交易关联成功: 标签 ^${linkTag} (同步解绑 ${companionTxs.length} 笔相关交易)\n  解绑交易列表:\n  ${unlinkedListStr}`, {
        linkTag,
        unlinkedCount: companionTxs.length,
        unlinkedTransactions: companionTxs.map(c => ({
          id: c.id,
          date: c.date,
          payee: c.payee,
          narration: c.narration,
          postings: c.postings,
        })),
      });
      
      // 解决 race condition：直接使用 hash() 算法计算新 ID
      const newId = hash(`main.bean:${newCurrentRaw}`);
      if (newId && newId !== id) {
        router.replace(`/transaction/${newId}`);
      }
      Alert.alert(t('transaction.unlinkSuccess'), t('transaction.unlinkSuccessDesc', { tag: linkTag }));
    } catch (e) {
      logger.error('ledgerStore', `解除交易关联失败 (Tag: ^${linkTag})`, e);
      Alert.alert(t('transaction.unlinkFail'), String(e));
    }
  };

  if (!tx) {
    return (
      <SafeAreaView style={[styles.page, { backgroundColor: theme.colors.bgPrimary }]}>
        <ScreenHeader title={t('common.notFound')} />
        <View style={styles.content}>
          <Card title={t('transaction.notFoundTitle')}>
            <Text style={[theme.typography.body, { color: theme.colors.fgSecondary }]}>
              {t('transaction.notFoundDesc', { id })}
            </Text>
          </Card>
        </View>
      </SafeAreaView>
    );
  }

  const isExpense = tx.postings.some(p => p.account.startsWith('Expenses'));
  const isIncome = tx.postings.some(p => p.account.startsWith('Income'));
  const directionLabel = isExpense ? t('transaction.directionExpense') : isIncome ? t('transaction.directionIncome') : t('transaction.directionTransfer');
  const directionColor = isExpense ? theme.colors.financial.expense
    : isIncome ? theme.colors.financial.income
    : theme.colors.financial.transfer;

  return (
    <SafeAreaView style={[styles.page, { backgroundColor: theme.colors.bgPrimary }]}>
      <ScreenHeader title={t('transaction.detailTitle')} />
      <ScrollView contentContainerStyle={[styles.content, { gap: 12 }]}>
        {/* 摘要卡片 */}
        <Card title={t('transaction.summary')}>
          <View style={styles.summaryRow}>
            <View style={{ flex: 1 }}>
              <Text style={[theme.typography.h3, { color: theme.colors.fgPrimary }]}>
                {tx.narration || tx.payee || t('transaction.noSummary')}
              </Text>
              <Text style={[theme.typography.caption, { color: theme.colors.fgSecondary, marginTop: 4 }]}>
                {tx.date.slice(0, 10)}{tx.payee ? ` · ${tx.payee}` : ''}
              </Text>
            </View>
            <View style={[styles.directionBadge, { backgroundColor: directionColor }]}>
              <Text style={{ color: theme.colors.fgInverse, fontSize: 12, fontWeight: '700' }}>{directionLabel}</Text>
            </View>
          </View>
        </Card>

        {/* 资金流向 */}
        <Card title={`${t('transaction.postings')} (${tx.postings.length})`}>
          <View style={{ gap: 8 }}>
            {tx.postings.map((p, i) => {
              const parts = p.account.split(':');
              const rootType = parts[0];
              const accountShortName = parts.slice(1).join(':') || p.account;

              let categoryTag = t('account.title');
              let iconName: keyof typeof Ionicons.glyphMap = 'swap-horizontal-outline';
              let tagBg = `${theme.colors.accent}15`;
              let tagColor = theme.colors.accent;

              if (rootType === 'Assets') {
                categoryTag = t('account.rootTypes.Assets');
                iconName = 'wallet-outline';
                tagBg = `${theme.colors.financial.income}15`;
                tagColor = theme.colors.financial.income;
              } else if (rootType === 'Expenses') {
                categoryTag = t('account.rootTypes.Expenses');
                iconName = 'cart-outline';
                tagBg = `${theme.colors.financial.expense}15`;
                tagColor = theme.colors.financial.expense;
              } else if (rootType === 'Income') {
                categoryTag = t('account.rootTypes.Income');
                iconName = 'cash-outline';
                tagBg = `${theme.colors.financial.income}15`;
                tagColor = theme.colors.financial.income;
              } else if (rootType === 'Liabilities') {
                categoryTag = t('account.rootTypes.Liabilities');
                iconName = 'card-outline';
                tagBg = `${theme.colors.warning}15`;
                tagColor = theme.colors.warning;
              } else if (rootType === 'Equity') {
                categoryTag = t('account.rootTypes.Equity');
                iconName = 'options-outline';
              }

              const amountVal = parseFloat(p.amount ?? '0');
              const isNegative = amountVal < 0;

              return (
                <View
                  key={i}
                  style={[
                    styles.flowCardItem,
                    {
                      backgroundColor: theme.colors.bgTertiary,
                      borderRadius: theme.radii.lg,
                    },
                  ]}
                >
                  <View style={[styles.flowIconBox, { backgroundColor: tagBg }]}>
                    <Ionicons name={iconName} size={18} color={tagColor} />
                  </View>

                  <View style={{ flex: 1, marginLeft: 10 }}>
                    <View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
                      <View style={[styles.miniTypeTag, { backgroundColor: `${theme.colors.fgSecondary}15` }]}>
                        <Text style={{ fontSize: 10, color: theme.colors.fgSecondary, fontWeight: '600' }}>
                          {categoryTag}
                        </Text>
                      </View>
                    </View>

                    <Text style={[theme.typography.body, { color: theme.colors.fgPrimary, fontWeight: '700', marginTop: 2 }]}>
                      {accountShortName}
                    </Text>

                    {p.metadata && Object.entries(p.metadata).map(([k, v]) => (
                      <Text key={k} style={[theme.typography.caption, { color: theme.colors.fgSecondary, marginTop: 2 }]}>
                        {k}: {v}
                      </Text>
                    ))}
                  </View>

                  <View style={{ alignItems: 'flex-end', justifyContent: 'center' }}>
                    {p.amount && (
                      <Text
                        style={[
                          theme.typography.body,
                          {
                            color: isNegative ? theme.colors.financial.expense : theme.colors.fgPrimary,
                            fontWeight: '700',
                          },
                        ]}
                      >
                        {p.amount} {p.currency ?? ''}
                      </Text>
                    )}
                    {p.cost && (
                      <Text style={[theme.typography.caption, { color: theme.colors.fgSecondary }]}>
                        成本: {p.cost}
                      </Text>
                    )}
                    {p.price && (
                      <Text style={[theme.typography.caption, { color: theme.colors.fgSecondary }]}>
                        单价: @ {p.price}
                      </Text>
                    )}
                  </View>
                </View>
              );
            })}
          </View>
        </Card>

        {/* 标签 */}
        {tx.tags.length > 0 && (
          <Card title={t('transaction.tags')}>
            <View style={styles.tagRow}>
              {tx.tags.map(tag => (
                <View key={tag} style={[styles.tag, { backgroundColor: theme.colors.accentLight }]}>
                  <Text style={[theme.typography.caption, { color: theme.colors.accentDark }]}>#{tag}</Text>
                </View>
              ))}
            </View>
          </Card>
        )}

        {/* 链接 */}
        {(tx.links.length > 0 || isEditable) && (
          <Card title={t('transaction.links')}>
            <View style={styles.tagRow}>
              {tx.links.map(link => (
                <View key={link} style={[styles.tagContainer, { backgroundColor: theme.colors.accentLight }]}>
                  <Text style={[theme.typography.caption, { color: theme.colors.accentDark, fontWeight: '700' }]}>^{link}</Text>
                  {isEditable && (
                    <Pressable onPress={() => handleUnlink(link)} style={{ marginLeft: 6 }}>
                      <Ionicons name="close-circle" size={14} color={theme.colors.accentDark} />
                    </Pressable>
                  )}
                </View>
              ))}
            </View>
            
            {isEditable && (
              <Pressable
                onPress={() => setLinkModalVisible(true)}
                style={[styles.linkBtn, { borderColor: theme.colors.accent, marginTop: tx.links.length > 0 ? 12 : 0 }]}
              >
                <Ionicons name="link-outline" size={16} color={theme.colors.accent} />
                <Text style={[theme.typography.bodySmall, { color: theme.colors.accent, marginLeft: 6, fontWeight: '700' }]}>
                  {t('transaction.linkTransaction')}
                </Text>
              </Pressable>
            )}
            
            {!isEditable && tx.links.length === 0 && (
              <Text style={[theme.typography.caption, { color: theme.colors.fgSecondary }]}>
                {t('transaction.readOnlyLinks')}
              </Text>
            )}
          </Card>
        )}

        {/* 关联的交易列表 */}
        {relatedTransactions.length > 0 && (
          <Card title={t('transaction.relatedTransactions')}>
            {relatedTransactions.map(item => (
              <TransactionCard
                key={item.id}
                transaction={item}
                onPress={(target) => router.push(`/transaction/${target.id}`)}
              />
            ))}
          </Card>
        )}

        {/* 元数据 / 附加信息 */}
        {tx.metadata && Object.keys(tx.metadata).length > 0 && (
          <Card
            title={`${t('transaction.metadata')} (${Object.keys(tx.metadata).length})`}
            collapsible
            defaultCollapsed
          >
            {Object.entries(tx.metadata).map(([k, v]) => (
              <View key={k} style={styles.metaRow}>
                <Text style={[theme.typography.caption, { color: theme.colors.fgSecondary }]}>{k}</Text>
                <Text style={[theme.typography.bodySmall, { color: theme.colors.fgPrimary }]}>{v}</Text>
              </View>
            ))}
          </Card>
        )}

        {/* 原始 .bean */}
        <Card
          title={t('transaction.rawBean')}
          collapsible
          defaultCollapsed
        >
          <Text style={[theme.typography.bodySmall, { color: theme.colors.fgPrimary, fontVariant: ['tabular-nums'], lineHeight: 20 }]}>
            {tx.raw}
          </Text>
          <Text style={[theme.typography.caption, { color: theme.colors.fgSecondary, marginTop: 8 }]}>
            {t('transaction.source')}: {tx.source}
          </Text>
        </Card>

        {/* 编辑/删除按钮（所有本地 main.bean 交易均可操作） */}
        {isEditable && (
          <View style={styles.editActions}>
            <Pressable
              onPress={() => useNumpadUiStore.getState().open({ editId: id })}
              style={({ pressed }) => [styles.editBtn, { borderColor: theme.colors.accent, opacity: pressed ? 0.7 : 1 }]}
            >
              <Ionicons name="create-outline" size={16} color={theme.colors.accent} />
              <Text style={[theme.typography.bodySmall, { color: theme.colors.accent, marginLeft: 4, fontWeight: '700' }]}>
                {t('transaction.edit')}
              </Text>
            </Pressable>
            <Pressable
              onPress={() => {
                Alert.alert(t('transaction.deleteTitle'), t('transaction.deleteConfirm'), [
                  { text: t('common.cancel'), style: 'cancel' },
                  {
                    text: t('common.delete'), style: 'destructive',
                    onPress: async () => {
                      try {
                        await useLedgerStore.getState().deleteTransaction(tx.raw);
                        Alert.alert(t('transaction.deleteSuccess'));
                        router.back();
                      } catch (e) {
                        Alert.alert('Error', String(e));
                      }
                    },
                  },
                ]);
              }}
              style={({ pressed }) => [styles.editBtn, { borderColor: theme.colors.error, opacity: pressed ? 0.7 : 1 }]}
            >
              <Ionicons name="trash-outline" size={16} color={theme.colors.error} />
              <Text style={[theme.typography.bodySmall, { color: theme.colors.error, marginLeft: 4, fontWeight: '700' }]}>
                {t('transaction.delete')}
              </Text>
            </Pressable>
          </View>
        )}
      </ScrollView>

      {/* 关联交易筛选模态框 */}
      <Modal
        visible={linkModalVisible}
        animationType="slide"
        transparent={false}
        onRequestClose={() => setLinkModalVisible(false)}
      >
        <SafeAreaView style={[styles.page, { backgroundColor: theme.colors.bgPrimary }]} edges={['top']}>
          <View style={styles.header}>
            <Pressable onPress={() => setLinkModalVisible(false)}>
              <Ionicons name="close" size={24} color={theme.colors.fgPrimary} />
            </Pressable>
            <Text style={[theme.typography.h2, { color: theme.colors.fgPrimary, flex: 1, marginLeft: 8 }]}>
              {t('transaction.linkMobileTx')}
            </Text>
          </View>
          
          <View style={styles.searchBarContainer}>
            <TextInput
              style={[commonStyles.input, { height: 40 }]}
              placeholder={t('transaction.searchTxPlaceholder')}
              placeholderTextColor={theme.colors.fgSecondary}
              value={searchQuery}
              onChangeText={setSearchQuery}
            />
          </View>

          <FlatList
            data={linkableTransactions}
            keyExtractor={(item) => item.id}
            renderItem={({ item }) => (
              <View style={{ paddingHorizontal: 16, paddingVertical: 4 }}>
                <TransactionCard
                  transaction={item}
                  onPress={() => handleLinkTransaction(item)}
                />
              </View>
            )}
            ListEmptyComponent={
              <Text style={[theme.typography.caption, { color: theme.colors.fgSecondary, textAlign: 'center', marginTop: 40 }]}>
                {t('transaction.noLinkableTx')}
              </Text>
            }
          />
        </SafeAreaView>
      </Modal>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  page: { flex: 1 },
  header: { flexDirection: 'row', alignItems: 'center', paddingHorizontal: 16, paddingTop: 8, paddingBottom: 12 },
  content: { padding: 16 },
  summaryRow: { flexDirection: 'row', alignItems: 'center', gap: 8 },
  directionBadge: { paddingVertical: 4, paddingHorizontal: 10, borderRadius: 12 },
  postingRow: { flexDirection: 'row', paddingTop: 10, gap: 8 },
  tagRow: { flexDirection: 'row', flexWrap: 'wrap', gap: 6 },
  tag: { paddingVertical: 4, paddingHorizontal: 8, borderRadius: 4 },
  tagContainer: { flexDirection: 'row', alignItems: 'center', paddingVertical: 4, paddingHorizontal: 8, borderRadius: 4 },
  linkBtn: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', borderWidth: StyleSheet.hairlineWidth, borderRadius: 16, paddingVertical: 8 },
  searchBarContainer: { paddingHorizontal: 16, paddingBottom: 8 },
  searchInput: { height: 40, borderWidth: StyleSheet.hairlineWidth, borderRadius: 8, paddingHorizontal: 12, fontSize: 14 },
  metaRow: { flexDirection: 'row', justifyContent: 'space-between', paddingVertical: 3 },
  editActions: { flexDirection: 'row', gap: 12, justifyContent: 'center' },
  editBtn: { flexDirection: 'row', alignItems: 'center', borderWidth: StyleSheet.hairlineWidth, borderRadius: 16, paddingVertical: 10, paddingHorizontal: 20 },
  flowCardItem: { flexDirection: 'row', alignItems: 'center', padding: 10 },
  flowIconBox: { width: 34, height: 34, borderRadius: 17, alignItems: 'center', justifyContent: 'center' },
  miniTypeTag: { paddingHorizontal: 6, paddingVertical: 2, borderRadius: 4 },
});
