package cmd

import (
	"encoding/json"
	"flag"
	"fmt"
	"os"

	"skraak/tools"
)

// RunIsNight handles the "isnight" subcommand
//
// JSON output schema (full):
//
//	{
//	  "file_path": string,          // Path to the WAV file
//	  "timestamp_utc": string,      // Recording start timestamp (UTC)
//	  "solar_night": bool,          // True if recorded during solar night
//	  "civil_night": bool,          // True if recorded during civil night
//	  "diurnal_active": bool,       // True if during diurnal active period
//	  "moon_phase": float,          // Moon phase (0.0=new, 1.0=full)
//	  "duration_seconds": float,    // Recording duration in seconds
//	  "timestamp_source": string,   // How timestamp was derived (comment/filename/mtime)
//	  "midpoint_utc": string,       // Recording midpoint timestamp (UTC)
//	  "sunrise_utc": string,        // Sunrise time (UTC), omitted if not applicable
//	  "sunset_utc": string,         // Sunset time (UTC), omitted if not applicable
//	  "dawn_utc": string,           // Civil dawn time (UTC), omitted if not applicable
//	  "dusk_utc": string            // Civil dusk time (UTC), omitted if not applicable
//	}
//
// JSON output schema (--brief):
//
//	{
//	  "file_path": string,   // Path to the WAV file
//	  "solar_night": bool    // True if recorded during solar night
//	}
func RunIsNight(args []string) {
	fs := flag.NewFlagSet("isnight", flag.ExitOnError)
	filePath := fs.String("file", "", "Path to WAV file (required)")
	lat := fs.Float64("lat", 0, "Latitude in decimal degrees (required)")
	lng := fs.Float64("lng", 0, "Longitude in decimal degrees (required)")
	timezone := fs.String("timezone", "UTC", "IANA timezone ID for filename timestamps (e.g. Pacific/Auckland)")
	brief := fs.Bool("brief", false, "Output only file_path and solar_night (saves tokens for batch use)")

	fs.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: skraak isnight --file <path> --lat <lat> --lng <lng> [--timezone <tz>] [--brief]\n\n")
		fmt.Fprintf(os.Stderr, "Determine if a WAV file was recorded at night based on file metadata and GPS coordinates.\n\n")
		fmt.Fprintf(os.Stderr, "Uses the recording midpoint (not start time) for astronomical calculations.\n")
		fmt.Fprintf(os.Stderr, "Timestamp resolution: AudioMoth comment → filename → file modification time.\n\n")
		fmt.Fprintf(os.Stderr, "Options:\n")
		fs.PrintDefaults()
		fmt.Fprintf(os.Stderr, "\nExamples:\n")
		fmt.Fprintf(os.Stderr, "  skraak isnight --file recording.wav --lat -36.85 --lng 174.76\n")
		fmt.Fprintf(os.Stderr, "  skraak isnight --file recording.wav --lat -36.85 --lng 174.76 --timezone Pacific/Auckland\n")
		fmt.Fprintf(os.Stderr, "  skraak isnight --file recording.wav --lat 51.51 --lng -0.13 | jq '.solar_night'\n")
	}

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

	if *filePath == "" {
		fmt.Fprintf(os.Stderr, "Error: --file is required\n\n")
		fs.Usage()
		os.Exit(1)
	}
	if *lat == 0 && *lng == 0 {
		fmt.Fprintf(os.Stderr, "Error: --lat and --lng are required\n\n")
		fs.Usage()
		os.Exit(1)
	}

	output, err := tools.IsNight(tools.IsNightInput{
		FilePath: *filePath,
		Lat:      *lat,
		Lng:      *lng,
		Timezone: *timezone,
	})
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error: %v\n", err)
		os.Exit(1)
	}

	var encErr error
	if *brief {
		enc := json.NewEncoder(os.Stdout)
		encErr = enc.Encode(map[string]any{
			"file_path":   output.FilePath,
			"solar_night": output.SolarNight,
		})
	} else {
		enc := json.NewEncoder(os.Stdout)
		enc.SetIndent("", "  ")
		encErr = enc.Encode(output)
	}
	if encErr != nil {
		fmt.Fprintf(os.Stderr, "Error encoding output: %v\n", encErr)
		os.Exit(1)
	}
}