{ config, pkgs, lib, ... }:

{
  options.vpnProxy = {
    enable = lib.mkEnableOption "VPN SOCKS proxy script";
    
    vmUser = lib.mkOption {
      type = lib.types.str;
      default = "nate";
      description = "Username for VM SSH connection";
    };
    
    vmIp = lib.mkOption {
      type = lib.types.str;
      default = "192.168.122.241";
      description = "IP address of the VM";
    };
    
    socksPort = lib.mkOption {
      type = lib.types.int;
      default = 1080;
      description = "Local SOCKS proxy port";
    };
    
    vpnTestUrl = lib.mkOption {
      type = lib.types.str;
      default = "https://doc-aut.app.vasionnow.com/";
      description = "URL to test VPN connectivity";
    };
  };

  config = lib.mkIf config.vpnProxy.enable {
    home.packages = [
      (pkgs.writeShellApplication {
        name = "vpn-proxy";
        runtimeInputs = with pkgs; [ 
          openssh 
          procps 
          lsof 
          gnused 
          coreutils 
          curl 
          glib  # for gsettings
          nettools  # for ss command
        ];
        text = ''
          VM_USER="${config.vpnProxy.vmUser}"
          VM_IP="${config.vpnProxy.vmIp}"
          SOCKS_PORT=${toString config.vpnProxy.socksPort}
          PID_FILE="/tmp/vpn-socks.pid"
          VPN_TEST_URL="${config.vpnProxy.vpnTestUrl}"

          check_ssh_agent() {
              # Check if SSH agent is available
              if [ -z "$SSH_AUTH_SOCK" ]; then
                  echo "Error: SSH agent not running (SSH_AUTH_SOCK not set)"
                  return 1
              fi

              # Check if any SSH keys are loaded
              if ! ssh-add -l >/dev/null 2>&1; then
                  echo "Error: No SSH keys are loaded in the agent"
                  echo "Please add your SSH key first with: ssh-add ~/.ssh/id_ed25519"
                  echo ""
                  echo "Agent status: SSH_AUTH_SOCK=$SSH_AUTH_SOCK"
                  return 1
              fi

              # Show loaded keys for confirmation
              echo "✓ SSH agent has loaded keys:"
              ssh-add -l | sed 's/^/  /'
              return 0
          }

          start_proxy() {
              # Check if proxy is already running
              if [ -f "$PID_FILE" ]; then
                  local pid
                  pid=$(cat "$PID_FILE" 2>/dev/null)
                  if [ -n "$pid" ] && ps -p "$pid" > /dev/null 2>&1; then
                      echo "Proxy already running (PID: $pid)"
                      return 1
                  else
                      echo "Stale PID file found, cleaning up..."
                      rm -f "$PID_FILE"
                  fi
              fi
              
              # Check SSH agent and keys
              echo "Checking SSH agent..."
              if ! check_ssh_agent; then
                  return 1
              fi
              echo ""
              
              # Test SSH connectivity first
              echo "Testing SSH connection to VM..."
              if ! ssh -o ConnectTimeout=5 -o BatchMode=yes -o StrictHostKeyChecking=no "$VM_USER@$VM_IP" exit 2>/dev/null; then
                  echo "Error: Cannot connect to VM: $VM_USER @ $VM_IP"
                  echo "Make sure:"
                  echo "  1. VM is running"
                  echo "  2. SSH service is running in VM"
                  echo "  3. SSH key authentication is set up"
                  return 1
              fi
              
              # Start SSH tunnel in background
              echo "Starting SSH SOCKS proxy..."
              ssh -D $SOCKS_PORT -f -N -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -o ExitOnForwardFailure=yes "$VM_USER@$VM_IP"
              local ssh_exit=$?
              
              if [ $ssh_exit -ne 0 ]; then
                  echo "Error: SSH tunnel failed to start (exit code: $ssh_exit)"
                  return 1
              fi
              
              # Wait a moment for SSH to fully establish
              sleep 1
              
              # Find and save the SSH process PID
              local pid
              pid=$(pgrep -f "ssh -D $SOCKS_PORT.*$VM_USER@$VM_IP" | head -1)
              if [ -z "$pid" ]; then
                  echo "Error: SSH process not found after startup"
                  return 1
              fi
              echo "$pid" > "$PID_FILE"
              
              # Verify port is listening
              echo "Verifying SOCKS proxy is listening on port $SOCKS_PORT..."
              local retry=0
              while [ $retry -lt 5 ]; do
                  if lsof -i :"$SOCKS_PORT" > /dev/null 2>&1 || ss -tln | grep -q ":$SOCKS_PORT "; then
                      break
                  fi
                  sleep 1
                  retry=$((retry + 1))
              done
              
              if [ $retry -eq 5 ]; then
                  echo "Error: SOCKS proxy port $SOCKS_PORT is not listening"
                  pkill -P "$pid" 2>/dev/null
                  kill "$pid" 2>/dev/null
                  rm -f "$PID_FILE"
                  return 1
              fi
              
              # Configure system proxy
              gsettings set org.gnome.system.proxy mode 'manual'
              gsettings set org.gnome.system.proxy.socks host 'localhost'
              gsettings set org.gnome.system.proxy.socks port $SOCKS_PORT
              
              echo "✓ VPN proxy started successfully on localhost:$SOCKS_PORT (PID: $pid)"
              
              # Test VPN connectivity
              echo "Testing VPN connectivity..."
              if curl -s -m 10 --socks5-hostname localhost:"$SOCKS_PORT" "$VPN_TEST_URL" > /dev/null 2>&1; then
                  echo "✓ VPN connection verified - can reach $VPN_TEST_URL"
              else
                  echo "⚠ Warning: Could not reach $VPN_TEST_URL through proxy"
                  echo "  The SOCKS proxy is running but VPN connection may not be active in the VM"
              fi
          }

          stop_proxy() {
              if [ -f "$PID_FILE" ]; then
                  local pid
                  pid=$(cat "$PID_FILE" 2>/dev/null)
                  
                  # Kill the specific SSH process
                  if [ -n "$pid" ] && ps -p "$pid" > /dev/null 2>&1; then
                      echo "Stopping VPN proxy (PID: $pid)..."
                      kill "$pid" 2>/dev/null
                      
                      # Wait for process to die
                      local retry=0
                      while [ $retry -lt 5 ] && ps -p "$pid" > /dev/null 2>&1; do
                          sleep 1
                          retry=$((retry + 1))
                      done
                      
                      # Force kill if still alive
                      if ps -p "$pid" > /dev/null 2>&1; then
                          echo "Process didn't stop gracefully, force killing..."
                          kill -9 "$pid" 2>/dev/null
                      fi
                  else
                      echo "PID $pid not found in process list"
                  fi
                  
                  rm -f "$PID_FILE"
              else
                  echo "Proxy not running (no PID file found)"
              fi
              
              # Always clean up orphaned SSH processes
              if pgrep -f "ssh -D $SOCKS_PORT" > /dev/null 2>&1; then
                  echo "Cleaning up orphaned SSH processes..."
                  pkill -f "ssh -D $SOCKS_PORT"
              fi
              
              # Always disable system proxy and clear SOCKS settings
              echo "Clearing proxy settings..."
              gsettings set org.gnome.system.proxy mode 'none'
              gsettings set org.gnome.system.proxy.socks host ""
              gsettings set org.gnome.system.proxy.socks port 0
              
              # Verify settings are cleared
              local proxy_mode
              proxy_mode=$(gsettings get org.gnome.system.proxy mode 2>/dev/null)
              if [ "$proxy_mode" = "'none'" ]; then
                  echo "✓ System proxy disabled"
              else
                  echo "⚠ Warning: Could not verify proxy was disabled (current mode: $proxy_mode)"
              fi
              
              echo "✓ VPN proxy stopped and proxy settings cleared"
              
              # Return success even if there was no PID file
              return 0
          }

          status_proxy() {
              if [ -f "$PID_FILE" ]; then
                  local pid
                  pid=$(cat "$PID_FILE" 2>/dev/null)
                  if [ -n "$pid" ] && ps -p "$pid" > /dev/null 2>&1; then
                      echo "✓ Proxy running on localhost:$SOCKS_PORT (PID: $pid)"
                      
                      # Check if port is actually listening
                      if lsof -i :"$SOCKS_PORT" > /dev/null 2>&1 || ss -tln | grep -q ":$SOCKS_PORT "; then
                          echo "✓ Port $SOCKS_PORT is listening"
                      else
                          echo "⚠ Warning: Process running but port not listening"
                      fi
                      
                      # Check system proxy settings
                      local proxy_mode
                      proxy_mode=$(gsettings get org.gnome.system.proxy mode 2>/dev/null)
                      if [ "$proxy_mode" = "'manual'" ]; then
                          echo "✓ System proxy configured"
                      else
                          echo "⚠ System proxy not configured (mode: $proxy_mode)"
                      fi
                      
                      # Quick connectivity test
                      if curl -s -m 5 --socks5-hostname localhost:"$SOCKS_PORT" "$VPN_TEST_URL" > /dev/null 2>&1; then
                          echo "✓ VPN connectivity verified"
                      else
                          echo "⚠ Cannot reach VPN resources"
                      fi
                      
                      return 0
                  else
                      echo "✗ Proxy not running (stale PID file)"
                      return 1
                  fi
              else
                  echo "✗ Proxy not running"
                  
                  # Check for orphaned processes
                  if pgrep -f "ssh -D $SOCKS_PORT" > /dev/null 2>&1; then
                      echo "⚠ Warning: Found SSH process without PID file"
                      echo "  Run 'vpn-proxy stop' to clean up"
                  fi
                  
                  return 1
              fi
          }

          case "''${1:-}" in
              start)
                  start_proxy
                  ;;
              stop)
                  stop_proxy
                  ;;
              restart)
                  stop_proxy
                  sleep 1
                  start_proxy
                  ;;
              status)
                  status_proxy
                  ;;
              test)
                  # Quick VPN test without starting/stopping
                  if curl -s -m 10 --socks5-hostname localhost:"$SOCKS_PORT" "$VPN_TEST_URL" > /dev/null 2>&1; then
                      echo "✓ VPN connection working - can reach $VPN_TEST_URL"
                      exit 0
                  else
                      echo "✗ Cannot reach $VPN_TEST_URL through proxy"
                      exit 1
                  fi
                  ;;
              *)
                  echo "Usage: vpn-proxy {start|stop|restart|status|test}"
                  exit 1
                  ;;
          esac
        '';
      })
    ];
  };
}
