package cmd

import (
	"fmt"
	"net/url"
	"os"
	"path/filepath"
	"strings"

	"github.com/spf13/cobra"

	"salsa.debian.org/otto/debpkg/internal/apt"
	"salsa.debian.org/otto/debpkg/internal/download"
	"salsa.debian.org/otto/debpkg/internal/ui"
)

var installCmd = &cobra.Command{
	Use:   "install <url>",
	Short: "Download and install a Debian package from URL",
	Long: `Download a .deb package from the specified URL and install it using apt.

The URL must point to a valid .deb file. The file will be downloaded to a
temporary location and then installed using 'sudo apt install'.`,
	Example: `  debpkg install https://example.com/package.deb
  debpkg install https://github.com/user/repo/releases/download/v1.0.0/package.deb`,
	Args: cobra.ExactArgs(1),
	RunE: runInstall,
}

func init() {
	rootCmd.AddCommand(installCmd)
}

func runInstall(cmd *cobra.Command, args []string) error {
	packageURL := args[0]

	// Validate URL
	if err := validateURL(packageURL); err != nil {
		PrintError(fmt.Sprintf("Invalid URL: %v", err))
		return err
	}

	// Check if running with appropriate permissions
	if err := apt.CheckPermissions(); err != nil {
		PrintError(err.Error())
		return err
	}

	// Extract filename from URL
	filename, err := extractFilename(packageURL)
	if err != nil {
		PrintError(fmt.Sprintf("Could not determine filename from URL: %v", err))
		return err
	}

	// Create temporary directory
	tempDir, err := os.MkdirTemp("", "debpkg-*")
	if err != nil {
		PrintError(fmt.Sprintf("Failed to create temporary directory: %v", err))
		return err
	}
	defer os.RemoveAll(tempDir)

	debFile := filepath.Join(tempDir, filename)

	// Show what we're about to do
	ui.ShowHeader("Installing Debian Package")
	PrintInfo(fmt.Sprintf("URL: %s", packageURL))
	PrintInfo(fmt.Sprintf("File: %s", filename))
	fmt.Println()

	// Download the file
	PrintInfo("Downloading package...")
	if err := download.File(packageURL, debFile); err != nil {
		PrintError(fmt.Sprintf("Download failed: %v", err))
		return err
	}
	PrintSuccess("Package downloaded successfully")
	fmt.Println()

	// Install the package
	PrintInfo("Installing package with apt...")
	if err := apt.InstallDeb(debFile); err != nil {
		PrintError(fmt.Sprintf("Installation failed: %v", err))
		return err
	}

	PrintSuccess("Package installed successfully!")
	return nil
}

func validateURL(rawURL string) error {
	parsedURL, err := url.Parse(rawURL)
	if err != nil {
		return fmt.Errorf("malformed URL: %w", err)
	}

	if parsedURL.Scheme != "http" && parsedURL.Scheme != "https" {
		return fmt.Errorf("only HTTP and HTTPS URLs are supported")
	}

	if parsedURL.Host == "" {
		return fmt.Errorf("URL must have a host")
	}

	// Check if URL looks like it points to a .deb file
	path := parsedURL.Path
	if !strings.HasSuffix(strings.ToLower(path), ".deb") {
		return fmt.Errorf("URL must point to a .deb file")
	}

	return nil
}

func extractFilename(rawURL string) (string, error) {
	parsedURL, err := url.Parse(rawURL)
	if err != nil {
		return "", err
	}

	filename := filepath.Base(parsedURL.Path)
	if filename == "" || filename == "." || filename == "/" {
		return "", fmt.Errorf("could not extract filename from URL")
	}

	return filename, nil
}
