package com.change.freevpn;

import android.content.Intent;
import android.os.Bundle;
import android.provider.Settings;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.change.freevpn.adapters.ServerAdapter;
import com.change.freevpn.api.ApiClient;
import com.change.freevpn.api.VpnApiService;
import com.change.freevpn.models.ConnectRequest;
import com.change.freevpn.models.ConnectResponse;
import com.change.freevpn.models.ServersResponse;
import com.change.freevpn.models.VpnServer;
import com.change.freevpn.vpn.OpenVpnService;
import com.change.freevpn.vpn.VpnManager;

import java.util.ArrayList;
import java.util.List;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class MainActivity extends AppCompatActivity {
    private RecyclerView recyclerServers;
    private Button btnConnect;
    private ProgressBar progressBar;
    private TextView tvStatus;
    
    private ServerAdapter serverAdapter;
    private List<VpnServer> serverList = new ArrayList<>();
    private VpnServer selectedServer;
    
    private VpnManager vpnManager;
    private boolean isConnected = false;
    private String deviceId;
    private String currentOvpnConfig;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Get unique device ID
        deviceId = getUniqueDeviceId();
        
        // Initialize VPN Manager
        vpnManager = new VpnManager(this, this);

        initViews();
        setupRecyclerView();
        setupVpnCallbacks();
        loadServers();
    }

    private String getUniqueDeviceId() {
        return Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);
    }

    private void initViews() {
        recyclerServers = findViewById(R.id.recycler_servers);
        btnConnect = findViewById(R.id.btn_connect);
        progressBar = findViewById(R.id.progress_bar);
        tvStatus = findViewById(R.id.tv_status);

        btnConnect.setOnClickListener(v -> handleConnectionToggle());
    }

    private void setupRecyclerView() {
        serverAdapter = new ServerAdapter(serverList, server -> {
            selectedServer = server;
            serverAdapter.setSelectedServer(server);
            serverAdapter.notifyDataSetChanged();
        });
        
        recyclerServers.setLayoutManager(new LinearLayoutManager(this));
        recyclerServers.setAdapter(serverAdapter);
    }

    private void setupVpnCallbacks() {
        // Set VPN service callback
        OpenVpnService.setCallback(new OpenVpnService.ConnectionCallback() {
            @Override
            public void onConnected() {
                runOnUiThread(() -> {
                    isConnected = true;
                    vpnManager.setConnected(true);
                    updateConnectionUI(true);
                    Toast.makeText(MainActivity.this, "VPN Connected!", Toast.LENGTH_SHORT).show();
                });
            }

            @Override
            public void onDisconnected() {
                runOnUiThread(() -> {
                    isConnected = false;
                    vpnManager.setConnected(false);
                    updateConnectionUI(false);
                    Toast.makeText(MainActivity.this, "VPN Disconnected", Toast.LENGTH_SHORT).show();
                });
            }

            @Override
            public void onError(String error) {
                runOnUiThread(() -> {
                    Toast.makeText(MainActivity.this, "Error: " + error, Toast.LENGTH_LONG).show();
                    updateConnectionUI(false);
                });
            }
        });
    }

    private void loadServers() {
        tvStatus.setText("Loading servers...");
        progressBar.setVisibility(View.VISIBLE);

        VpnApiService apiService = ApiClient.getApiService();
        apiService.getServers().enqueue(new Callback<ServersResponse>() {
            @Override
            public void onResponse(Call<ServersResponse> call, Response<ServersResponse> response) {
                progressBar.setVisibility(View.GONE);
                
                if (response.isSuccessful() && response.body() != null && response.body().isSuccess()) {
                    serverList.clear();
                    serverList.addAll(response.body().getData().getServers());
                    serverAdapter.notifyDataSetChanged();
                    
                    tvStatus.setText("Select a server");
                    
                    if (!serverList.isEmpty()) {
                        selectedServer = serverList.get(0);
                        serverAdapter.setSelectedServer(selectedServer);
                    }
                } else {
                    tvStatus.setText("Error loading servers");
                    Toast.makeText(MainActivity.this, "Failed to load servers", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(Call<ServersResponse> call, Throwable t) {
                progressBar.setVisibility(View.GONE);
                tvStatus.setText("Error: Failed to load servers. Check your internet connection.");
                Toast.makeText(MainActivity.this, "Network error: " + t.getMessage(), Toast.LENGTH_LONG).show();
            }
        });
    }

    private void handleConnectionToggle() {
        if (isConnected) {
            disconnectVpn();
        } else {
            connectVpn();
        }
    }

    private void connectVpn() {
        if (selectedServer == null) {
            Toast.makeText(this, "Please select a server first", Toast.LENGTH_SHORT).show();
            return;
        }

        progressBar.setVisibility(View.VISIBLE);
        tvStatus.setText("Connecting...");
        btnConnect.setEnabled(false);

        // Get OpenVPN config from server
        VpnApiService apiService = ApiClient.getApiService();
        ConnectRequest request = new ConnectRequest(selectedServer.getId(), deviceId);
        
        apiService.connect(request).enqueue(new Callback<ConnectResponse>() {
            @Override
            public void onResponse(Call<ConnectResponse> call, Response<ConnectResponse> response) {
                progressBar.setVisibility(View.GONE);
                btnConnect.setEnabled(true);
                
                if (response.isSuccessful() && response.body() != null && response.body().isSuccess()) {
                    currentOvpnConfig = response.body().getData().getOvpnConfig();
                    
                    // Start VPN with config
                    vpnManager.connect(currentOvpnConfig, new VpnManager.VpnCallback() {
                        @Override
                        public void onPermissionRequired(Intent intent, int requestCode) {
                            // Request VPN permission
                            startActivityForResult(intent, requestCode);
                        }

                        @Override
                        public void onStarting() {
                            tvStatus.setText("✓ Connected to " + selectedServer.getServerName());
                        }

                        @Override
                        public void onConnected() {
                            isConnected = true;
                            updateConnectionUI(true);
                        }

                        @Override
                        public void onDisconnected() {
                            isConnected = false;
                            updateConnectionUI(false);
                        }

                        @Override
                        public void onError(String error) {
                            Toast.makeText(MainActivity.this, "Connection error: " + error, Toast.LENGTH_LONG).show();
                            updateConnectionUI(false);
                        }
                    });
                } else {
                    Toast.makeText(MainActivity.this, "Failed to connect", Toast.LENGTH_SHORT).show();
                    tvStatus.setText("Connection failed");
                }
            }

            @Override
            public void onFailure(Call<ConnectResponse> call, Throwable t) {
                progressBar.setVisibility(View.GONE);
                btnConnect.setEnabled(true);
                Toast.makeText(MainActivity.this, "Network error: " + t.getMessage(), Toast.LENGTH_LONG).show();
                tvStatus.setText("Connection failed");
            }
        });
    }

    private void disconnectVpn() {
        vpnManager.disconnect();
        isConnected = false;
        updateConnectionUI(false);
    }

    private void updateConnectionUI(boolean connected) {
        runOnUiThread(() -> {
            if (connected) {
                btnConnect.setText("DISCONNECT");
                btnConnect.setBackgroundResource(R.drawable.btn_disconnect);
                if (selectedServer != null) {
                    tvStatus.setText("✓ Connected to " + selectedServer.getServerName());
                }
            } else {
                btnConnect.setText("CONNECT");
                btnConnect.setBackgroundResource(R.drawable.btn_connect);
                tvStatus.setText("Select a server");
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        
        // Handle VPN permission result
        vpnManager.onActivityResult(requestCode, resultCode, new VpnManager.VpnCallback() {
            @Override
            public void onPermissionRequired(Intent intent, int requestCode) {
                // Not used here
            }

            @Override
            public void onStarting() {
                tvStatus.setText("✓ Connected to " + selectedServer.getServerName());
                isConnected = true;
                updateConnectionUI(true);
            }

            @Override
            public void onConnected() {
                isConnected = true;
                updateConnectionUI(true);
            }

            @Override
            public void onDisconnected() {
                isConnected = false;
                updateConnectionUI(false);
            }

            @Override
            public void onError(String error) {
                Toast.makeText(MainActivity.this, "Error: " + error, Toast.LENGTH_LONG).show();
                updateConnectionUI(false);
            }
        });
    }

    @Override
    protected void onDestroy() {
        if (isConnected) {
            disconnectVpn();
        }
        super.onDestroy();
    }
}