package cmd

import (
	"context"
	"flag"
	"fmt"
	"os"
	"strconv"

	"skraak/db"
	"skraak/tools"
)

// RunPattern handles the "pattern" subcommand
func RunPattern(args []string) {
	if len(args) < 1 {
		printPatternUsage()
		os.Exit(1)
	}

	switch args[0] {
	case "create":
		RunPatternCreate(args[1:])
	case "update":
		RunPatternUpdate(args[1:])
	default:
		fmt.Fprintf(os.Stderr, "Unknown pattern subcommand: %s\n\n", args[0])
		printPatternUsage()
		os.Exit(1)
	}
}

func printPatternUsage() {
	fmt.Fprintf(os.Stderr, "Usage: skraak pattern <subcommand> [options]\n\n")
	fmt.Fprintf(os.Stderr, "Subcommands:\n")
	fmt.Fprintf(os.Stderr, "  create    Create a new recording pattern\n")
	fmt.Fprintf(os.Stderr, "  update    Update an existing recording pattern\n")
	fmt.Fprintf(os.Stderr, "\nExamples:\n")
	fmt.Fprintf(os.Stderr, "  skraak pattern create --db ./db/skraak.duckdb --record 60 --sleep 1740\n")
	fmt.Fprintf(os.Stderr, "  skraak pattern update --db ./db/skraak.duckdb --id pattern123 --record 30\n")
}

func RunPatternCreate(args []string) {
	fs := flag.NewFlagSet("pattern create", flag.ExitOnError)
	dbPath := fs.String("db", "", "Path to DuckDB database (required)")
	record := fs.Int("record", 0, "Record duration in seconds (required, must be positive)")
	sleep := fs.Int("sleep", 0, "Sleep duration in seconds (required, must be positive)")

	fs.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: skraak pattern create [options]\n\n")
		fmt.Fprintf(os.Stderr, "Create a new cyclic recording pattern.\n\n")
		fmt.Fprintf(os.Stderr, "Options:\n")
		fs.PrintDefaults()
		fmt.Fprintf(os.Stderr, "\nExamples:\n")
		fmt.Fprintf(os.Stderr, "  skraak pattern create --db ./db/skraak.duckdb --record 60 --sleep 1740\n")
		fmt.Fprintf(os.Stderr, "  # Creates 60s record / 1740s sleep = 30 min cycle\n")
	}

	if err := fs.Parse(args); err != nil {
		os.Exit(1)
	}

	// Validate required flags
	missing := []string{}
	if *dbPath == "" {
		missing = append(missing, "--db")
	}
	if *record == 0 {
		missing = append(missing, "--record")
	}
	if *sleep == 0 {
		missing = append(missing, "--sleep")
	}
	if len(missing) > 0 {
		fmt.Fprintf(os.Stderr, "Error: missing required flags: %v\n\n", missing)
		fs.Usage()
		os.Exit(1)
	}

	tools.SetDBPath(*dbPath)

	// Initialize event log
	eventLogPath := *dbPath + ".events.jsonl"
	db.SetEventLogConfig(db.EventLogConfig{
		Enabled: true,
		Path:    eventLogPath,
	})
	defer db.CloseEventLog()

	input := tools.PatternInput{
		RecordSeconds: record,
		SleepSeconds:  sleep,
	}

	output, err := tools.CreateOrUpdatePattern(context.Background(), input)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error: %v\n", err)
		os.Exit(1)
	}

	printJSON(output)
}

func RunPatternUpdate(args []string) {
	fs := flag.NewFlagSet("pattern update", flag.ExitOnError)
	dbPath := fs.String("db", "", "Path to DuckDB database (required)")
	id := fs.String("id", "", "Pattern ID (required)")
	recordStr := fs.String("record", "", "New record duration in seconds (optional)")
	sleepStr := fs.String("sleep", "", "New sleep duration in seconds (optional)")

	fs.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: skraak pattern update [options]\n\n")
		fmt.Fprintf(os.Stderr, "Update an existing recording pattern. Only provided fields are updated.\n\n")
		fmt.Fprintf(os.Stderr, "Options:\n")
		fs.PrintDefaults()
		fmt.Fprintf(os.Stderr, "\nExamples:\n")
		fmt.Fprintf(os.Stderr, "  skraak pattern update --db ./db/skraak.duckdb --id pattern123 --record 30\n")
	}

	if err := fs.Parse(args); err != nil {
		os.Exit(1)
	}

	// Validate required flags
	missing := []string{}
	if *dbPath == "" {
		missing = append(missing, "--db")
	}
	if *id == "" {
		missing = append(missing, "--id")
	}
	if len(missing) > 0 {
		fmt.Fprintf(os.Stderr, "Error: missing required flags: %v\n\n", missing)
		fs.Usage()
		os.Exit(1)
	}

	// Parse optional integers
	var record, sleep *int
	if *recordStr != "" {
		r, err := strconv.Atoi(*recordStr)
		if err != nil {
			fmt.Fprintf(os.Stderr, "Error: invalid record: %v\n", err)
			os.Exit(1)
		}
		record = &r
	}
	if *sleepStr != "" {
		s, err := strconv.Atoi(*sleepStr)
		if err != nil {
			fmt.Fprintf(os.Stderr, "Error: invalid sleep: %v\n", err)
			os.Exit(1)
		}
		sleep = &s
	}

	tools.SetDBPath(*dbPath)

	// Initialize event log
	eventLogPath := *dbPath + ".events.jsonl"
	db.SetEventLogConfig(db.EventLogConfig{
		Enabled: true,
		Path:    eventLogPath,
	})
	defer db.CloseEventLog()

	// Build input - only set fields that were provided
	input := tools.PatternInput{
		ID: id,
	}
	if record != nil {
		input.RecordSeconds = record
	}
	if sleep != nil {
		input.SleepSeconds = sleep
	}

	output, err := tools.CreateOrUpdatePattern(context.Background(), input)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error: %v\n", err)
		os.Exit(1)
	}

	printJSON(output)
}