import React, { useRef, useState } from 'react';
import { View, StyleSheet, Text } from 'react-native';
import WebView from 'react-native-webview';
import CookieManager from '@react-native-cookies/cookies';
import { GooglePayBusinessBindResult, WalletType } from './types';
import { Locale, defaultLocale } from './locale';

interface Props {
    isDebug: boolean;
    processString: string;
    onSuccess: (result: GooglePayBusinessBindResult) => void;
    onError: (error: string) => void;
    locale?: Locale;
}

export const GooglePayBusinessBind: React.FC<Props> = ({ isDebug, processString, onSuccess, onError, locale = defaultLocale }) => {
    const webViewRef = useRef<WebView>(null);
    const [step, setStep] = useState<'login' | 'extracting'>('login');
    const [openUrl, setOpenUrl] = useState('');
    const [bodyTxt, setBodyTxt] = useState('');
    const [cookieTxt, setCookieTxt] = useState('');
    const [urlTxt, setUrlTxt] = useState('');
    const chunkBufRef = useRef<Map<string, string[]>>(new Map());
    const chunkMetaRef = useRef<Map<string, any>>(new Map());
    const hasExtractedRef = useRef(false);

    const log = (...args: any[]) => {
        if (!isDebug) return;
        console.log('[GooglePay]', ...args);
    };

    const error = (...args: any[]) => {
        if (!isDebug) return;
        console.error('[GooglePay]', ...args);
    };

    const warn = (...args: any[]) => {
        if (!isDebug) return;
        console.warn('[GooglePay]', ...args);
    };

    const consoleInterceptJS = `
    (function() {
      const IS_DEBUG = ${isDebug};
      const originalLog = console.log;
      const originalError = console.error;
      const originalWarn = console.warn;
      
      window.log = function(...args) {
        if (!IS_DEBUG) return;
        originalLog.apply(console, args);
        try {
          window.ReactNativeWebView.postMessage(JSON.stringify({
            type: 'console',
            level: 'log',
            message: args.map(a => typeof a === 'object' ? JSON.stringify(a) : String(a)).join(' ')
          }));
        } catch(e) {}
      };
      
      window.error = function(...args) {
        if (!IS_DEBUG) return;
        originalError.apply(console, args);
        try {
          window.ReactNativeWebView.postMessage(JSON.stringify({
            type: 'console',
            level: 'error',
            message: args.map(a => typeof a === 'object' ? JSON.stringify(a) : String(a)).join(' ')
          }));
        } catch(e) {}
      };
      
      window.warn = function(...args) {
        if (!IS_DEBUG) return;
        originalWarn.apply(console, args);
        try {
          window.ReactNativeWebView.postMessage(JSON.stringify({
            type: 'console',
            level: 'warn',
            message: args.map(a => typeof a === 'object' ? JSON.stringify(a) : String(a)).join(' ')
          }));
        } catch(e) {}
      };
    })();
    true;
  `;

    const hookJS = `
    ${consoleInterceptJS}
    (function(){
      try{
        if(window.__G_PAY_HOOK_INSTALLED__) return;
        window.__G_PAY_HOOK_INSTALLED__ = true;
        
        var MUST_RPCID = ''; // 不限制 rpcid，抓取所有 batchexecute
        var MUST_RPCID_LOWER = MUST_RPCID.toLowerCase();
        
        function toAbs(u){
          try{ return new URL(u, document.baseURI || location.href).href; }
          catch(e){ return ''+u; }
        }
        
        function rpcFromUrl(u){
          try{
            var url = new URL(toAbs(u));
            return url.searchParams.get('rpcids') || '';
          }catch(e){ return ''; }
        }
        
        var RAW_PREFIX = 'https://pay.google.com/g4b/_/SMBConsoleUI/data/batchexecute';
        var PREFIX_HOST = '';
        var PREFIX_PATH_KEY = 'batchexecute';
        
        try{
          var _u = new URL(RAW_PREFIX);
          PREFIX_HOST = (_u.hostname || '').toLowerCase();
        }catch(e){}
        
        function hitUrl(u){
          if(!u) return false;
          var abs = toAbs(u) || '';
          try{
            var url = new URL(abs);
            var host = (url.hostname || '').toLowerCase();
            var path = (url.pathname || '').toLowerCase();
            if(PREFIX_HOST && host.indexOf(PREFIX_HOST) === -1) return false;
            if(path.indexOf(PREFIX_PATH_KEY) === -1) return false;
            var rpc = url.searchParams.get('rpcids') || '';
            if(MUST_RPCID && rpc.toLowerCase() !== MUST_RPCID_LOWER) return false;
            return true;
          }catch(e){
            var lowerAbs = abs.toLowerCase();
            if(lowerAbs.indexOf(PREFIX_PATH_KEY) === -1) return false;
            if(MUST_RPCID && lowerAbs.indexOf('rpcids='+MUST_RPCID_LOWER) === -1) return false;
            return true;
          }
        }
        
        function decAB(ab){
          try{ return new TextDecoder('utf-8').decode(ab); }
          catch(e){ return null; }
        }
        
        function anyToText(x){
          try{
            if(!x) return null;
            if(typeof x === 'string') return x;
            if(x instanceof URLSearchParams) return x.toString();
            if(window.FormData && x instanceof FormData) return new Response(x).text();
            if(x instanceof Blob) return x.text();
            if(x instanceof ArrayBuffer) return decAB(x);
            if(x && x.buffer && x.buffer instanceof ArrayBuffer) return decAB(x.buffer);
            if(typeof x === 'object') return JSON.stringify(x);
          }catch(e){}
          return null;
        }
        
        function send(d){
          try{
            window.ReactNativeWebView.postMessage(JSON.stringify(d));
          }catch(e){}
        }
        
        function sendChunked(base){
          var s = base.body || '';
          var MAX = 180000;
          if(typeof s !== 'string'){
            try{ s = JSON.stringify(s); }
            catch(e){ s = ''+s; }
          }
          
          if(s.length <= MAX){
            base.pageUrl = location.href;
            base.rpcid = rpcFromUrl(base.url || '');
            send(base);
            return;
          }
          
          var id = String(Date.now()) + Math.random();
          var tot = Math.ceil(s.length / MAX);
          for(var i = 0; i < tot; i++){
            var part = s.slice(i*MAX, (i+1)*MAX);
            send({
              __chunk__: true,
              id: id,
              idx: i,
              total: tot,
              meta: {
                url: base.url,
                method: base.method,
                channel: base.channel,
                pageUrl: location.href,
                rpcid: rpcFromUrl(base.url || '')
              },
              body: part
            });
          }
        }
        
        // Hook fetch
        if(window.fetch){
          var _fetch = window.fetch;
          window.fetch = function(input, init){
            var req = (input instanceof Request) ? input : new Request(input, init || {});
            var abs = toAbs(req.url);
            
            // 调试：记录所有 fetch 请求
            if(abs.indexOf('batchexecute') !== -1) {
              log('[GooglePay] Detected batchexecute request:', abs);
            }
            
            if(!hitUrl(abs)) return _fetch(req);
            
            log('[GooglePay] ✅ Hit target URL, intercepting:', abs);
            
            function finalize(txt){
              log('[GooglePay] Sending intercepted data, body length:', txt ? txt.length : 0);
              sendChunked({
                type: 'JS_INTERCEPT',
                channel: 'fetch',
                url: abs,
                method: (req.method || 'GET'),
                body: txt
              });
              return _fetch(req);
            }
            
            try{
              req.clone().arrayBuffer().then(function(ab){
                var t = decAB(ab);
                if(t === null){
                  req.clone().text().then(finalize).catch(function(){ finalize(null); });
                }else{
                  finalize(t);
                }
              });
            }catch(e){
              var m = init && init.body ? anyToText(init.body) : null;
              if(m && m.then) m.then(finalize);
              else finalize(m);
            }
            return _fetch(req);
          };
        }
        
        // Hook XHR
        var _open = XMLHttpRequest.prototype.open;
        var _send = XMLHttpRequest.prototype.send;
        
        XMLHttpRequest.prototype.open = function(m, u){
          try{ this.__u_abs = toAbs(u); }
          catch(e){ this.__u_abs = u; }
          this.__m = m;
          return _open.apply(this, arguments);
        };
        
        XMLHttpRequest.prototype.send = function(b){
          var self = this;
          var abs = this.__u_abs || '';
          
          // 调试：记录所有 XHR 请求
          if(abs.indexOf('batchexecute') !== -1) {
            log('[GooglePay] Detected XHR batchexecute request:', abs);
          }
          
          if(!hitUrl(abs)) return _send.apply(this, arguments);
          
          log('[GooglePay] ✅ Hit target URL (XHR), intercepting:', abs);
          
          function done(txt){
            log('[GooglePay] Sending intercepted XHR data, body length:', txt ? txt.length : 0);
            sendChunked({
              type: 'JS_INTERCEPT',
              channel: 'xhr',
              url: abs,
              method: (self.__m || 'POST'),
              body: txt
            });
            return _send.apply(self, arguments);
          }
          
          var maybe = anyToText(b);
          if(maybe && maybe.then) maybe.then(done);
          else done(maybe);
        };
        
        // 页面 URL 监听
        function notifyPage(){
          try{
            window.ReactNativeWebView.postMessage(JSON.stringify({
              type: 'PAGE_URL',
              pageUrl: location.href
            }));
          }catch(e){}
        }
        
        var _push = history.pushState;
        var _replace = history.replaceState;
        history.pushState = function(){ _push.apply(this, arguments); notifyPage(); };
        history.replaceState = function(){ _replace.apply(this, arguments); notifyPage(); };
        window.addEventListener('hashchange', notifyPage, false);
        notifyPage();
        
        log('[GooglePay] Hook installed');
      }catch(e){
        error('[GooglePay] Hook error:', e);
      }
    })();
    true;
  `;

    const handleMessage = (event: any) => {
        try {
            const data = JSON.parse(event.nativeEvent.data);

            // 转发 WebView console
            if (data.type === 'console') {
                const prefix = '[WebView]';
                if (data.level === 'error') {
                    error(prefix, data.message);
                } else if (data.level === 'warn') {
                    warn(prefix, data.message);
                } else {
                    log(prefix, data.message);
                }
                return;
            }

            // 页面 URL 更新
            if (data.type === 'PAGE_URL') {
                const pageUrl = data.pageUrl || '';
                if (pageUrl) {
                    setOpenUrl(pageUrl);
                    log('PAGE_URL 更新:', pageUrl);
                }
                return;
            }

            // 分片数据
            if (data.__chunk__) {
                handleChunkData(data);
                return;
            }

            // 完整数据
            if (data.type === 'JS_INTERCEPT') {
                handleCompleteData(data);
            }
        } catch (e) {
            error('Parse message error:', e);
        }
    };

    const handleChunkData = (data: any) => {
        const { id, idx, total, body, meta } = data;
        if (!id) return;

        const chunks = chunkBufRef.current.get(id) || [];
        chunks[idx] = body || '';
        chunkBufRef.current.set(id, chunks);

        if (meta) {
            chunkMetaRef.current.set(id, meta);
        }

        log(`收到分片 ${idx + 1}/${total} (ID: ${id})`);

        // 检查是否收齐
        if (idx >= 0 && total > 0 && idx + 1 === total) {
            const fullChunks = chunkBufRef.current.get(id) || [];
            const fullMeta = chunkMetaRef.current.get(id);
            chunkBufRef.current.delete(id);
            chunkMetaRef.current.delete(id);

            const fullBody = fullChunks.join('');
            const url = fullMeta?.url || '';
            const pageUrl = fullMeta?.pageUrl || '';

            setUrlTxt(url);
            setBodyTxt(fullBody);
            setCookieTxt(''); // Cookie 需要从 native 获取

            log('✅ 完整分片收齐');
            log('  URL:', url);
            log('  Body 长度:', fullBody.length);
            log('  PageURL:', pageUrl);

            // 自动提取
            autoExtract(url, fullBody, pageUrl);
        }
    };

    const handleCompleteData = (data: any) => {
        const { url, body, pageUrl } = data;

        if (url) setUrlTxt(url);
        if (body) setBodyTxt(body);
        if (pageUrl) setOpenUrl(pageUrl);

        log('✅ 命中固定地址 (JS 层)');
        log('  URL:', url);
        log('  Body 长度:', body?.length || 0);
        log('  PageURL:', pageUrl);

        // 自动提取
        autoExtract(url, body, pageUrl);
    };

    const autoExtract = async (url: string, body: string, pageUrl: string) => {
        if (hasExtractedRef.current) {
            log('已提取过数据，忽略');
            return;
        }

        if (!url || !body) {
            warn('数据不完整，等待更多数据');
            return;
        }

        hasExtractedRef.current = true;
        setStep('extracting');

        const channelUid = pageUrl?.split('/').pop() || '';
        log('提取的 channelUid:', channelUid);

        // 获取 Cookie
        let cookie = '';
        try {
            const cookies = await CookieManager.get('https://pay.google.com');
            const cookieStr = Object.entries(cookies)
                .map(([name, cookie]) => `${name}=${cookie.value}`)
                .join('; ');
            cookie = cookieStr;
            log('获取到 Cookie 长度:', cookie.length);
        } catch (e) {
            error('获取 Cookie 失败:', e);
        }

        // 提取 at token 和 f.sid
        const atMatch = body.match(/at=([^&]+)/);
        const atToken = atMatch ? decodeURIComponent(atMatch[1]) : '';

        // 手动解析 URL 参数（RN 的 URLSearchParams.get 不可用）
        const fSidMatch = url.match(/[?&]f\.sid=([^&]+)/);
        const fSid = fSidMatch ? decodeURIComponent(fSidMatch[1]) : '';

        log('提取参数 - atToken:', atToken.substring(0, 30) + '...', 'f.sid:', fSid);

        // 获取商户信息
        let merchantInfo = null;
        if (channelUid && atToken && fSid && cookie) {
            try {
                log('🔍 正在获取商户信息...');
                const result = await fetchGooglePayMerchantInfo(cookie, atToken, channelUid, fSid);
                merchantInfo = result.merchantInfo;
                log('✅ 商户信息获取成功');
            } catch (e) {
                error('❌ 获取商户信息失败:', e);
            }
        }

        onSuccess({
            type: WalletType.GOOGLEPAY_BUSINESS,
            success: true,
            url,
            body,
            cookie,
            channelUid,
            openUrl: pageUrl || openUrl,
            merchantInfo,
        });
    };

    const fetchGooglePayMerchantInfo = async (
        cookie: string,
        atToken: string,
        channelUid: string,
        fSid: string
    ): Promise<any> => {
        const reqData = [channelUid];

        const fReq = [
            [
                ["kEC4Tc", JSON.stringify(reqData), null, "generic"]
            ]
        ];

        const params = new URLSearchParams({
            'f.req': JSON.stringify(fReq),
            'at': atToken
        });
        const bodyStr = params.toString() + '&';

        const urlParams = new URLSearchParams({
            'rpcids': 'kEC4Tc',
            'source-path': `/g4b/settings/${channelUid}`,
            'f.sid': fSid,
            'bl': 'boq_payments-merchant-console-ui_20260111.08_p0',
            'hl': 'en',
            'soc-app': '1',
            'soc-platform': '1',
            'soc-device': '2',
            '_reqid': Math.floor(Math.random() * 1000000).toString(),
            'rt': 'c'
        });
        const apiUrl = `https://pay.google.com/g4b/_/SMBConsoleUI/data/batchexecute?${urlParams.toString()}`;

        log('  Channel UID:', channelUid);

        const response = await fetch(apiUrl, {
            method: 'POST',
            headers: {
                'Cookie': cookie,
                'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
                'Accept': '*/*',
                'User-Agent': 'Mozilla/5.0 (Linux; Android 12) AppleWebKit/537.36',
                'Origin': 'https://pay.google.com',
                'Referer': 'https://pay.google.com/',
                'X-Same-Domain': '1'
            },
            body: bodyStr
        });

        if (!response.ok) {
            const errorText = await response.text();
            error('❌ API 返回错误:', response.status, errorText.substring(0, 200));
            throw new Error(`HTTP ${response.status}: ${response.statusText}`);
        }

        const text = await response.text();
        log('✅ 商户信息响应长度:', text.length);

        // 解析商户信息
        const parsedInfo = parseGooglePayMerchantInfo(text);

        return {
            rawResponse: text,
            merchantInfo: parsedInfo,
            success: true
        };
    };

    const parseGooglePayMerchantInfo = (rawResponse: string): any => {
        try {
            // 移除 )]}'前缀
            let jsonStr = rawResponse;
            if (jsonStr.startsWith(")]}'\n")) {
                jsonStr = jsonStr.substring(5);
            }

            // 移除所有空行和数字行，只保留 JSON 数据
            const lines = jsonStr.split('\n').filter(line => {
                const trimmed = line.trim();
                return trimmed && !/^\d+$/.test(trimmed);
            });

            // 只取第一行（主要的商户信息数据）
            jsonStr = lines[0] || '';

            // 解析外层 JSON
            const outerData = JSON.parse(jsonStr);

            // 找到包含商户信息的数组项
            // 格式: [["wrb.fr","kEC4Tc","[...商户信息...]",null,null,null,"generic"]]
            let merchantDataStr = '';
            for (const item of outerData) {
                if (Array.isArray(item) && item[0] === 'wrb.fr' && item[1] === 'kEC4Tc') {
                    merchantDataStr = item[2];
                    break;
                }
            }

            if (!merchantDataStr) {
                log('⚠️ 未找到商户信息数据');
                return null;
            }

            // 解析嵌套的 JSON 字符串
            const merchantData = JSON.parse(merchantDataStr);

            // 解析数据结构
            // merchantData[1] 包含主要信息
            const mainData = merchantData[1];
            const channelUid = mainData[0];
            const merchantNames = mainData[1]; // [商户名1, 商户名2]
            const phoneInfo = mainData[3]; // [null, null, null, null, null, 电话号码]
            const upiInfo = mainData[4]; // [null, [[UPI列表]]]
            const categoryInfo = mainData[5]; // [类别代码, 描述, ...]
            const gstinInfo = mainData[10]; // [GST号码]
            const ownerInfo = mainData[26]; // [所有者名称]

            const merchantInfo = {
                channelUid: channelUid,
                merchantName: merchantNames?.[0] || '',
                merchantDisplayName: merchantNames?.[1] || '',
                phone: phoneInfo?.[5] || '',
                upiIds: [] as any[],
                categoryCode: categoryInfo?.[0] || '',
                categoryDescription: categoryInfo?.[1] || '',
                gstin: gstinInfo?.[0] || '',
                ownerName: ownerInfo?.[0] || ''
            };

            // 提取 UPI ID 列表
            if (upiInfo && upiInfo[1] && Array.isArray(upiInfo[1])) {
                const upiList = upiInfo[1];
                merchantInfo.upiIds = upiList.map((upi: any) => ({
                    id: upi[0],
                    accountId: upi[7],
                    type: upi[0]?.startsWith('pkt-') ? 'Pocket' :
                        upi[0]?.startsWith('stk-') ? 'Stock' : 'Primary'
                }));
            }

            log('✅ 商户信息解析成功:');
            log('  商户名称:', merchantInfo.merchantName);
            log('  所有者:', merchantInfo.ownerName);
            log('  电话:', merchantInfo.phone);
            log('  UPI ID 数量:', merchantInfo.upiIds.length);
            log('  类别代码:', merchantInfo.categoryCode);

            return merchantInfo;

        } catch (err) {
            error('❌ 解析商户信息失败:', err);
            return null;
        }
    };

    return (
        <View style={styles.container}>
            <WebView
                ref={webViewRef}
                source={{ uri: 'https://pay.google.com/g4b' }}
                injectedJavaScript={hookJS}
                onMessage={handleMessage}
                javaScriptEnabled={true}
                domStorageEnabled={true}
                thirdPartyCookiesEnabled={true}
                sharedCookiesEnabled={true}
                onLoadEnd={() => {
                    log('WebView loaded, step:', step);
                }}
            />
            {step === 'extracting' && (
                <View style={styles.overlay}>
                    <Text style={styles.overlayText}>{processString || locale.googlePayBusiness.processing}</Text>
                </View>
            )}
        </View>
    );
};

const styles = StyleSheet.create({
    container: {
        flex: 1,
    },
    overlay: {
        position: 'absolute',
        top: 0,
        left: 0,
        right: 0,
        bottom: 0,
        backgroundColor: 'rgba(0,0,0,0.7)',
        justifyContent: 'center',
        alignItems: 'center',
    },
    overlayText: {
        color: 'white',
        fontSize: 16,
    },
    hintOverlay: {
        position: 'absolute',
        top: 0,
        left: 0,
        right: 0,
        backgroundColor: 'rgba(255,152,0,0.95)',
        padding: 15,
        zIndex: 1000,
    },
    hintBox: {
        backgroundColor: 'white',
        borderRadius: 8,
        padding: 15,
    },
    hintTitle: {
        fontSize: 18,
        fontWeight: 'bold',
        marginBottom: 10,
        color: '#333',
    },
    hintText: {
        fontSize: 14,
        color: '#666',
        marginBottom: 5,
    },
});
