package cmd

import (
	"context"
	"fmt"
	"net/url"
	"os"
	"strings"

	"github.com/spf13/cobra"
	"github.com/yourorg/devour/internal/scraper"
	"github.com/yourorg/devour/internal/search"
	"github.com/yourorg/devour/internal/storage"
)

var pushCmd = &cobra.Command{
	Use:   "push <path>",
	Short: "Import local documents into Devour storage/index",
	Long: `Push local documents into your Devour local workspace.

Current stable behavior:
  - local ingest into docs storage
  - local reindex for query/ask/status

Remote push is experimental and not enabled by default.

Examples:
  devour push ./docs
  devour push ./docs --project my-project`,
	Args: cobra.ExactArgs(1),
	RunE: runPush,
}

var (
	pushServer  string
	pushProject string
)

func init() {
	pushCmd.Flags().StringVar(&pushServer, "server", "", "remote Devour server URL (experimental)")
	pushCmd.Flags().StringVarP(&pushProject, "project", "p", "", "project name label")
}

func runPush(cmd *cobra.Command, args []string) error {
	path := args[0]
	if _, err := os.Stat(path); err != nil {
		return fmt.Errorf("path does not exist: %s", path)
	}

	cfg, err := loadAppConfig()
	if err != nil {
		return fmt.Errorf("load app config for push command: %w", err)
	}

	server := strings.TrimSpace(pushServer)
	if server != "" && !isLocalServer(server) {
		return fmt.Errorf("remote push is experimental and not enabled in this build; use local push without --server")
	}

	projectName := strings.TrimSpace(pushProject)
	if projectName == "" {
		projectName = "local-push"
	}

	fmt.Printf("📤 Ingesting local docs from: %s\n", path)
	fmt.Printf("   Project: %s\n", projectName)
	fmt.Printf("   Target docs dir: %s\n", cfg.Storage.DocsDir)

	s := scraper.NewScraper(scraper.SourceTypeLocal, toScraperConfig(cfg, 0))
	if s == nil {
		return fmt.Errorf("local scraper not available")
	}

	docs, err := s.Scrape(context.Background(), &scraper.Source{
		Name:    projectName,
		Type:    scraper.SourceTypeLocal,
		Path:    path,
		Include: []string{`.*`},
	})
	if err != nil {
		return fmt.Errorf("local ingest failed: %w", err)
	}

	saved, err := storage.SaveDocuments(docs, storage.SaveOptions{
		Format:      "json",
		OutputDir:   cfg.Storage.DocsDir,
		AllowEmpty:  false,
		PrintWriter: nil,
	})
	if err != nil {
		return fmt.Errorf("save docs failed: %w", err)
	}

	engine := search.NewEngine(cfg)
	stats, err := engine.Rebuild(context.Background())
	if err != nil {
		return fmt.Errorf("reindex failed: %w", err)
	}

	fmt.Println("\n✓ Push complete")
	fmt.Printf("   Documents imported: %d\n", saved.Count)
	fmt.Printf("   Index docs: %d\n", stats.Documents)
	fmt.Printf("   Index path: %s\n", stats.IndexPath)
	return nil
}

func isLocalServer(raw string) bool {
	u, err := url.Parse(raw)
	if err != nil {
		return false
	}
	host := strings.ToLower(u.Hostname())
	return host == "" || host == "localhost" || host == "127.0.0.1"
}
