import React, { useState } from 'react';
import type { DuplicateDetail, DedupConfidence } from '../../domain/transaction/dedup';
import { FlatList, StyleSheet, Text, View, Pressable, Alert } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { Ionicons } from '@expo/vector-icons';
import * as DocumentPicker from 'expo-document-picker';
import * as FileSystem from 'expo-file-system/legacy';
import * as XLSX from 'xlsx';

// 实例化纯 JS GBK 解码器（Hermes 原生 TextDecoder 仅支持 UTF-8，需强迫 text-encoding-gbk 返回其纯 JS 实现）
const GbkTextDecoder = (() => {
  const g = globalThis as Record<string, unknown>;
  const origDecoder = g.TextDecoder;
  const origEncoder = g.TextEncoder;
  try {
    g.TextDecoder = undefined;
    g.TextEncoder = undefined;
    const dec = require('text-encoding-gbk').TextDecoder;
    return dec;
  } catch {
    return origDecoder;
  } finally {
    g.TextDecoder = origDecoder;
    g.TextEncoder = origEncoder;
  }
})();

import { useLedgerStore } from '../../store/ledgerStore';
import { useImportStore } from '../../store/importStore';
import { useMetadataStore } from '../../store/metadataStore';
import { useTheme } from '../../theme';
import { useT } from '../../i18n';
import { Card } from '../../components/ui/Card';
import { Button } from '../../components/ui/Button';
import { DedupBanner } from '../../components/transaction/DedupBanner';
import { ScreenHeader } from '../../components/layout/ScreenHeader';
import { classifyWithCategories } from '../../domain/rules/rules';
import { validateTransaction } from '../../domain/core/ledger';
import type { ImportedEvent } from '../../domain/core/types';


// 纯 JS 实现 Base64 解码为字节数组
function base64ToBytes(base64: string): Uint8Array {
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
  const lookup = new Uint8Array(256);
  for (let i = 0; i < chars.length; i++) {
    lookup[chars.charCodeAt(i)] = i;
  }
  let bufferLength = base64.length * 0.75;
  if (base64[base64.length - 1] === '=') {
    bufferLength--;
    if (base64[base64.length - 2] === '=') {
      bufferLength--;
    }
  }
  const bytes = new Uint8Array(bufferLength);
  let p = 0;
  for (let i = 0; i < base64.length; i += 4) {
    const base64code1 = lookup[base64.charCodeAt(i)];
    const base64code2 = lookup[base64.charCodeAt(i + 1)];
    const base64code3 = lookup[base64.charCodeAt(i + 2)];
    const base64code4 = lookup[base64.charCodeAt(i + 3)];
    bytes[p++] = (base64code1 << 2) | (base64code2 >> 4);
    if (p < bufferLength) bytes[p++] = ((base64code2 & 15) << 4) | (base64code3 >> 2);
    if (p < bufferLength) bytes[p++] = ((base64code3 & 3) << 6) | (base64code4 & 63);
  }
  return bytes;
}

export default function ImportScreen() {
  const { theme } = useTheme();
  const t = useT();
  const ledger = useLedgerStore(s => s.ledger);
  const addTransaction = useLedgerStore(s => s.addTransaction);
  const autoOpenAccounts = useLedgerStore(s => s.autoOpenAccounts);
  const events = useImportStore(s => s.events);
  const pendingDrafts = useImportStore(s => s.pendingDrafts);
  const lastResult = useImportStore(s => s.lastResult);
  const importCsv = useImportStore(s => s.importCsv);
  const processEvents = useImportStore(s => s.process);
  const confirmDraft = useImportStore(s => s.confirmDraft);
  const confirmDrafts = useImportStore(s => s.confirmDrafts);
  const [status, setStatus] = useState('');
  
  // 疑似重复账单交互状态
  const [manualDuplicates, setManualDuplicates] = useState<ImportedEvent[]>([]);
  const [showDuplicates, setShowDuplicates] = useState(false);


  const handleSelectFile = async () => {
    try {
      const res = await DocumentPicker.getDocumentAsync({
        type: '*/*', // 允许所有类型，防部分手机系统限制
        copyToCacheDirectory: true,
      });
      if (res.canceled) return;
      
      const file = res.assets[0];
      const isExcel = file.name.toLowerCase().endsWith('.xlsx') || file.name.toLowerCase().endsWith('.xls');

      // 1. 读取为 Base64 以保证字节完整
      const base64 = await FileSystem.readAsStringAsync(file.uri, {
        encoding: FileSystem.EncodingType.Base64,
      });

      let content = '';

      if (isExcel) {
        // 2a. Excel 格式：直接使用 xlsx 库解析并转换为内存中的 CSV 字符串
        const workbook = XLSX.read(base64, { type: 'base64' });
        const firstSheetName = workbook.SheetNames[0];
        const worksheet = workbook.Sheets[firstSheetName];
        content = XLSX.utils.sheet_to_csv(worksheet);
      } else {
        // 2b. 解码为 Uint8Array 进行 CSV 文本处理
        const bytes = base64ToBytes(base64);

        // 3. 编码自适应解码：优先尝试 UTF-8，若出错则回退至中文 GBK
        try {
          const utf8Decoder = new TextDecoder('utf-8', { fatal: true });
          content = utf8Decoder.decode(bytes);
        } catch {
          // UTF-8 校验失败，回退到国标 GBK 解码（利用 text-encoding-gbk 保证 Hermes 兼容）
          try {
            const gbkDecoder = new GbkTextDecoder('gbk');
            content = gbkDecoder.decode(bytes);
          } catch (err) {
            throw new Error(t('importFlow.decodeFail', { error: err instanceof Error ? err.message : String(err) }));
          }
        }
      }

      // 4. 自适应解析通道：根据文件名或内容关键字区分微信/支付宝
      const isWeChat = file.name.includes('微信') || file.name.toLowerCase().includes('wechat') || content.includes('微信支付');
      const adapter = isWeChat ? 'wechat-csv-v1' : 'alipay-csv-v1';

      // 5. 导入数据并清空历史状态
      importCsv(content, adapter);
      setManualDuplicates([]);
      setStatus(t('importFlow.importSuccess', {
        format: isExcel ? t('importFlow.formatExcel') : t('importFlow.formatCsv'),
        name: file.name,
      }));

      // 6. 自动执行 Pipeline，用户无需手动查找运行按钮
      if (ledger) {
        setStatus(t('importFlow.pipelineRunning'));
        processEvents(ledger, ledger.transactions || []).then(result => {
          setManualDuplicates(result.duplicates);
          setStatus(t('importFlow.pipelineDone', { drafts: result.drafts.length, duplicates: result.duplicates.length }));
        }).catch(e => {
          setStatus(t('importFlow.pipelineFail', { error: String(e) }));
        });
      }
    } catch (e) {
      setStatus(t('importFlow.pickFail', { error: e instanceof Error ? e.message : String(e) }));
      Alert.alert(t('importFlow.importFailTitle'), e instanceof Error ? e.message : String(e));
    }
  };

  const runPipeline = () => {
    if (!ledger) return;
    processEvents(ledger, ledger.transactions || []).then(result => {
      setManualDuplicates(result.duplicates);
      setStatus(t('importFlow.processed', { drafts: result.drafts.length, duplicates: result.duplicates.length, transfers: result.transferCount }));
    }).catch(e => setStatus(String(e)));
  };

  const onConfirm = async (index: number) => {
    if (!ledger) return;
    const item = pendingDrafts[index];
    if (!item) return;
    try {
      // 自动开户：收集所有草稿中的账户，检查哪些未 open
      const currentLedger = useLedgerStore.getState().ledger!;
      const unopened = item.draft.postings
        .map(p => p.account)
        .filter(acc => !currentLedger.accounts.has(acc));
      if (unopened.length > 0) {
        await autoOpenAccounts(unopened);
      }
      await addTransaction(item.draft);
      confirmDraft(index);
      setStatus(t('importFlow.confirmed'));
    } catch (e) {
      const errStr = e instanceof Error ? e.message : String(e);
      setStatus(t('importFlow.commitFail', { error: errStr }));
      Alert.alert(t('importFlow.commitFailTitle'), errStr);
    }
  };

  const onConfirmAll = async () => {
    const currentLedger = useLedgerStore.getState().ledger;
    if (!currentLedger || pendingDrafts.length === 0) return;
    setStatus(t('importFlow.batchPreparing'));

    // 1. 收集所有草稿中引用的账户，静默自动开户
    const allAccounts = new Set<string>();
    for (const item of pendingDrafts) {
      for (const posting of item.draft.postings) {
        allAccounts.add(posting.account);
      }
    }
    const unopened = Array.from(allAccounts).filter(acc => !currentLedger.accounts.has(acc));
    if (unopened.length > 0) {
      try {
        await autoOpenAccounts(unopened);
      } catch (err) {
        setStatus(t('importFlow.autoOpenFail', { error: err instanceof Error ? err.message : String(err) }));
        Alert.alert(t('importFlow.autoOpenFailTitle'), err instanceof Error ? err.message : String(err));
        return;
      }
    }

    // 2. 重新获取 ledger（开户后已更新），再次校验
    const updatedLedger = useLedgerStore.getState().ledger!;
    const validIndices: number[] = [];
    const validDrafts: typeof pendingDrafts = [];
    const failedPayees: string[] = [];

    for (let i = 0; i < pendingDrafts.length; i++) {
      const item = pendingDrafts[i];
      const validation = validateTransaction(item.draft, updatedLedger);
      if (validation.valid) {
        validIndices.push(i);
        validDrafts.push(item);
      } else {
        failedPayees.push(`${item.draft.payee || item.draft.narration || t('common.untitled')}: ${validation.errors.join('; ')}`);
      }
    }

    // 3. 执行真正的批量入账
    if (validDrafts.length > 0) {
      await commitBatch(validIndices, validDrafts, failedPayees);
    } else if (failedPayees.length > 0) {
      Alert.alert(t('importFlow.commitFailTitle'), t('importFlow.batchNoValid', { reasons: failedPayees.join('\n') }));
    }
  };

  const commitBatch = async (indices: number[], drafts: typeof pendingDrafts, failedPayees: string[]) => {
    try {
      // 使用 ledgerStore 的 appendTransactionsBatch（在互斥锁内完成读取+拼接+写入）
      const appendTransactionsBatch = useLedgerStore.getState().appendTransactionsBatch;
      await appendTransactionsBatch(drafts.map(d => d.draft));

      // 从待确认中批量移除
      confirmDrafts(indices);

      const successCount = drafts.length;
      const failCount = failedPayees.length;

      if (failCount === 0) {
        setStatus(t('importFlow.batchAllSuccess', { count: successCount }));
        Alert.alert(t('importFlow.confirmed'), t('importFlow.batchAllSuccess', { count: successCount }));
      } else {
        setStatus(t('importFlow.batchPartial', { success: successCount, fail: failCount }));
        Alert.alert(
          t('importFlow.batchResultTitle'),
          t('importFlow.batchResultBody', { success: successCount, fail: failCount, reasons: failedPayees.join('\n') })
        );
      }
    } catch (e) {
      setStatus(t('importFlow.batchFail', { error: e instanceof Error ? e.message : String(e) }));
      Alert.alert(t('importFlow.batchErrorTitle'), e instanceof Error ? e.message : String(e));
    }
  };

  const handleAcceptDuplicate = async (event: ImportedEvent) => {
    if (!ledger) return;
    try {
      const rules = useMetadataStore.getState().rules;
      const categories = useMetadataStore.getState().categories;
      const classification = classifyWithCategories(event, rules, categories, ledger);
      await addTransaction(classification.draft, undefined, true);
      setManualDuplicates(prev => prev.filter(ev => ev.id !== event.id));
      setStatus(t('importFlow.forcedImport'));
      Alert.alert('记账成功', `已成功将「${event.counterparty || event.memo || '交易'}」单独记入账本`);
    } catch (err) {
      setStatus(String(err));
      Alert.alert('记账失败', String(err));
    }
  };

  const handleLinkDuplicate = async (event: ImportedEvent) => {
    if (!ledger) return;
    try {
      const rules = useMetadataStore.getState().rules;
      const categories = useMetadataStore.getState().categories;
      const classification = classifyWithCategories(event, rules, categories, ledger);

      // 寻找对应的历史匹配交易
      const detail = lastResult?.duplicateDetails?.find((d: DuplicateDetail) => d.event.id === event.id);
      const matchedTx = detail?.matchedWith?.rawTransaction;

      const linkTag = matchedTx?.links?.[0] || 'lnk-' + Math.random().toString(36).slice(2, 8);

      // 为新草稿添加链接
      const newDraft = {
        ...classification.draft,
        links: Array.from(new Set([...(classification.draft.links || []), linkTag])),
      };

      await addTransaction(newDraft, undefined, true);

      // 如果有历史匹配交易且它还没有此 linkTag，同步写回历史交易 raw
      if (matchedTx && !matchedTx.links.includes(linkTag)) {
        const currentRaw = matchedTx.raw;
        const firstLineEnd = currentRaw.indexOf('\n');
        const header = firstLineEnd !== -1 ? currentRaw.slice(0, firstLineEnd) : currentRaw;
        const rest = firstLineEnd !== -1 ? currentRaw.slice(firstLineEnd) : '';
        const updatedHeader = `${header} ^${linkTag}`;
        const updatedRaw = `${updatedHeader}${rest}`;

        const { mobileBean, replaceMobileBean } = useLedgerStore.getState();
        if (mobileBean.includes(currentRaw)) {
          const newContent = mobileBean.replace(currentRaw, updatedRaw);
          await replaceMobileBean(newContent);
        }
      }

      setManualDuplicates(prev => prev.filter(ev => ev.id !== event.id));
      setStatus(`已成功关联交易 (标签 ^${linkTag})`);
      Alert.alert('关联成功', `已成功将「${event.counterparty || event.memo || '交易'}」与历史账单关联（关联标签 ^${linkTag}）`);
    } catch (err) {
      setStatus(String(err));
      Alert.alert('关联失败', String(err));
    }
  };

  const handleRejectDuplicate = (event: ImportedEvent) => {
    setManualDuplicates(prev => prev.filter(ev => ev.id !== event.id));
    setStatus(t('importFlow.ignored'));
  };

  return (
    <SafeAreaView style={[styles.page, { backgroundColor: theme.colors.bgPrimary }]} edges={['top', 'bottom']}>
      <ScreenHeader title={t('tab.import')} />
      <FlatList
        data={pendingDrafts}
        keyExtractor={(item, index) => `${item.draft.sourceEventIds?.[0] || index}-${index}`}
        renderItem={({ item, index }) => (
          <Card title={`${item.draft.date} · ${item.isTransfer ? t('importFlow.transfer') : t('importFlow.trade')} · ${item.draft.postings[0]?.amount ?? ''}`}>
            <Text style={[theme.typography.body, { color: theme.colors.fgPrimary }]}>{item.draft.narration}</Text>
            <Text style={[theme.typography.bodySmall, styles.mono, { color: theme.colors.fgSecondary }]}>
              {item.draft.postings.map(p => `${p.account} ${p.amount} ${p.currency ?? ''}`).join('\n')}
            </Text>
            {item.categoryFallbackReason && (
              <Text style={[theme.typography.caption, { color: theme.colors.warning, marginTop: 4 }]}>
                {t('importFlow.fallbackWarn', { reason: item.categoryFallbackReason })}
              </Text>
            )}
            <View style={{ marginTop: 8 }}>
              <Button label={t('importFlow.confirm')} onPress={() => onConfirm(index)} />
            </View>
          </Card>
        )}
        ListHeaderComponent={
          <View style={{ gap: 12, marginBottom: 12 }}>
            <Card title={t('importFlow.title')}>
              <Text style={[theme.typography.caption, { color: theme.colors.fgSecondary, marginBottom: 12 }]}>
                {t('importFlow.hint')}
              </Text>
              <View style={styles.buttonCol}>
                <Button label={t('importFlow.selectFile')} onPress={handleSelectFile} />
              </View>
              {events.length > 0 && (
                <View style={{ marginTop: 12, gap: 8 }}>
                  <Button label={t('importFlow.processButton', { count: events.length })} onPress={runPipeline} variant="secondary" />
                  {pendingDrafts.length > 0 && (
                    <Button label={t('importFlow.confirmAll', { count: pendingDrafts.length })} onPress={onConfirmAll} variant="primary" />
                  )}
                </View>
              )}
              {lastResult && (
                <Text style={[theme.typography.caption, { color: theme.colors.fgSecondary, marginTop: 8 }]}>
                  {t('importFlow.result', { drafts: lastResult.drafts.length, duplicates: lastResult.duplicates.length, transfers: lastResult.transferCount })}
                </Text>
              )}
            </Card>

            {/* 疑似重复账单展示面板 */}
            {manualDuplicates.length > 0 && (
              <Card title={t('importFlow.duplicatesTitle', { count: manualDuplicates.length })}>
                <Pressable
                  onPress={() => setShowDuplicates(!showDuplicates)}
                  style={styles.collapseHeader}
                >
                  <Text style={[theme.typography.bodySmall, { color: theme.colors.accent, fontWeight: '700' }]}>
                    {showDuplicates ? t('importFlow.collapseList') : t('importFlow.expandDuplicates')}
                  </Text>
                  <Ionicons name={showDuplicates ? 'chevron-up' : 'chevron-down'} size={16} color={theme.colors.accent} />
                </Pressable>

                {showDuplicates && (
                  <View style={styles.duplicatesList}>
                    {manualDuplicates.map((item) => {
                      const detail = lastResult?.duplicateDetails?.find((d: DuplicateDetail) => d.event.id === item.id);
                      const matchedTx = detail?.matchedWith?.rawTransaction;
                      const reason = detail?.reason || t('importFlow.duplicateReason', { date: item.occurredAt, payee: item.counterparty || t('importFlow.unknownPayee') });

                      const result = {
                        isDuplicate: true,
                        confidence: (detail?.confidence ?? 'medium') as DedupConfidence,
                        reason,
                      };

                      return (
                        <Card
                          key={item.id}
                          title={`${item.occurredAt} · ${item.counterparty || t('importFlow.unknownSource')}`}
                          onPress={() => handleLinkDuplicate(item)}
                        >
                          <Text style={[theme.typography.body, { color: theme.colors.fgPrimary }]}>
                            {item.memo || t('importFlow.noDesc')}
                          </Text>
                          <Text style={[theme.typography.bodySmall, { color: theme.colors.fgSecondary }]}>
                            {t('importFlow.duplicateAmount', { amount: item.amount, currency: item.currency })}
                          </Text>

                          {matchedTx && (
                            <View style={{ backgroundColor: `${theme.colors.accent}12`, padding: 8, borderRadius: 8, marginVertical: 4 }}>
                              <Text style={[theme.typography.caption, { color: theme.colors.accent, fontWeight: '700' }]}>
                                已匹配到的账本历史交易（可关联）：
                              </Text>
                              <Text style={[theme.typography.caption, { color: theme.colors.fgPrimary, marginTop: 2 }]}>
                                {matchedTx.date} {matchedTx.payee ? matchedTx.payee + ' - ' : ''}{matchedTx.narration} ({matchedTx.postings[0]?.amount} {matchedTx.postings[0]?.currency})
                              </Text>
                            </View>
                          )}

                          <DedupBanner
                            result={result}
                            onAccept={() => handleAcceptDuplicate(item)}
                            onReject={() => handleRejectDuplicate(item)}
                            onLink={() => handleLinkDuplicate(item)}
                          />
                        </Card>
                      );
                    })}
                  </View>
                )}
              </Card>
            )}
          </View>
        }
        ListFooterComponent={
          status ? <Text style={[theme.typography.bodySmall, { color: theme.colors.fgSecondary, textAlign: 'center', marginVertical: 20 }]}>{status}</Text> : null
        }
        contentContainerStyle={styles.content}
        initialNumToRender={10}
        maxToRenderPerBatch={10}
        windowSize={5}
      />
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  page: { flex: 1 },
  content: { padding: 16, paddingBottom: 64 },
  buttonCol: { gap: 8, marginTop: 4 },
  mono: { fontVariant: ['tabular-nums'], lineHeight: 20, marginTop: 8 },
  collapseHeader: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingVertical: 8 },
  duplicatesList: { gap: 12, marginTop: 8 },
});
