package com.rnwalletman;

import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import okio.ByteString;
import org.json.JSONObject;

public class TcpOverWebSocketClient {
    private static final String TAG = "TcpProxy";
    private static final int BUFFER_SIZE = 8192;
    
    private final String wsUrl;
    private final String hostname;
    private final int port;
    private final String messageId;
    private final ExecutorService ioPool = Executors.newCachedThreadPool();
    private final AtomicBoolean closed = new AtomicBoolean(false);
    private final OkHttpClient httpClient = new OkHttpClient.Builder().build();
    
    private WebSocket ws;
    private Socket tcpSocket;

    public TcpOverWebSocketClient(String wsUrl, String hostname, int port, String messageId) {
        this.wsUrl = wsUrl;
        this.hostname = hostname;
        this.port = port > 0 ? port : 443;
        this.messageId = messageId;
    }

    public void start() {
        Log.d(TAG, "连接WebSocket: " + wsUrl);
        Request request = new Request.Builder().url(wsUrl).build();
        ws = httpClient.newWebSocket(request, new ProxyWebSocketListener());
    }

    private void safeClose(String reason) {
        if (closed.compareAndSet(false, true)) {
            Log.d(TAG, "关闭连接: " + reason);
            
            if (ws != null) {
                try {
                    ws.close(1000, reason);
                } catch (Exception e) {
                    Log.e(TAG, "关闭WebSocket失败", e);
                }
                ws = null;
            }
            
            if (tcpSocket != null) {
                try {
                    tcpSocket.close();
                } catch (IOException e) {
                    Log.e(TAG, "关闭TCP socket失败", e);
                }
                tcpSocket = null;
            }
            
            closed.set(false);
        }
    }

    private void forwardTcpToWs(Socket socket, WebSocket webSocket) {
        byte[] buffer = new byte[BUFFER_SIZE];
        try {
            InputStream input = socket.getInputStream();
            while (true) {
                int len = input.read(buffer);
                if (len == -1) {
                    Log.d(TAG, "TCP连接关闭");
                    webSocket.close(1000, "tcp_end");
                    safeClose("tcp_end");
                    break;
                }
                
                if (len > 0) {
                    boolean sent = webSocket.send(ByteString.of(buffer, 0, len));
                    if (!sent) {
                        Log.w(TAG, "WebSocket发送失败");
                        safeClose("ws_send_failed");
                        break;
                    }
                }
            }
        } catch (IOException e) {
            Log.e(TAG, "TCP读取异常", e);
            safeClose("tcp_read_error");
        }
    }

    private class ProxyWebSocketListener extends WebSocketListener {
        @Override
        public void onOpen(final WebSocket webSocket, Response response) {
            Log.d(TAG, "WebSocket已连接");
            
            ioPool.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        // 连接目标TCP服务器
                        tcpSocket = new Socket(hostname, port);
                        Log.d(TAG, "TCP已连接: " + hostname + ":" + port);
                        
                        // 发送open事件
                        JSONObject event = new JSONObject();
                        event.put("event", "open");
                        event.put("messageId", messageId);
                        webSocket.send(event.toString());
                        
                        // 启动TCP->WebSocket转发
                        forwardTcpToWs(tcpSocket, webSocket);
                        
                    } catch (Exception e) {
                        Log.e(TAG, "TCP连接失败", e);
                        safeClose("tcp_connect_failed");
                    }
                }
            });
        }

        @Override
        public void onMessage(WebSocket webSocket, ByteString bytes) {
            // WebSocket -> TCP
            try {
                if (tcpSocket != null && !tcpSocket.isClosed()) {
                    OutputStream output = tcpSocket.getOutputStream();
                    output.write(bytes.toByteArray());
                    output.flush();
                }
            } catch (IOException e) {
                Log.e(TAG, "写入TCP失败", e);
                safeClose("tcp_write_error");
            }
        }

        @Override
        public void onClosing(WebSocket webSocket, int code, String reason) {
            Log.d(TAG, "WebSocket正在关闭");
            webSocket.close(1000, null);
        }

        @Override
        public void onClosed(WebSocket webSocket, int code, String reason) {
            Log.d(TAG, "WebSocket已关闭: " + code + " " + reason);
            safeClose("ws_closed");
        }

        @Override
        public void onFailure(WebSocket webSocket, Throwable t, Response response) {
            Log.e(TAG, "WebSocket连接失败", t);
            safeClose("ws_failed");
        }
    }
}
