package cmd

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

	"skraak/tools"
)

// RunExport handles the "export" subcommand
//
// export dataset JSON output schema:
//
//	{
//	  "dataset_id": string,              // ID of the exported dataset
//	  "dataset_name": string,            // Name of the exported dataset
//	  "output_path": string,             // Path to the output database
//	  "row_counts": {string: int},       // Row counts per table (table_name -> count)
//	  "file_size_mb": float,             // Output file size in MB (omitted if dry run)
//	  "dry_run": bool,                   // Whether this was a dry run
//	  "message": string                  // Summary message
//	}
func RunExport(args []string) {
	if len(args) < 1 {
		printExportUsage()
		os.Exit(1)
	}

	switch args[0] {
	case "dataset":
		runExportDataset(args[1:])
	default:
		fmt.Fprintf(os.Stderr, "Unknown export subcommand: %s\n\n", args[0])
		printExportUsage()
		os.Exit(1)
	}
}

func printExportUsage() {
	fmt.Fprintf(os.Stderr, "Usage: skraak export <subcommand> [options]\n\n")
	fmt.Fprintf(os.Stderr, "Subcommands:\n")
	fmt.Fprintf(os.Stderr, "  dataset    Export a dataset with all related data\n")
	fmt.Fprintf(os.Stderr, "\nExamples:\n")
	fmt.Fprintf(os.Stderr, "  skraak export dataset --db ./db/skraak.duckdb --id abc123 --output export.duckdb\n")
	fmt.Fprintf(os.Stderr, "  skraak export dataset --db ./db/skraak.duckdb --id abc123 --output export.duckdb --dry-run\n")
}

func runExportDataset(args []string) {
	fs := flag.NewFlagSet("export dataset", flag.ExitOnError)
	dbPath := fs.String("db", "", "Path to source DuckDB database (required)")
	datasetID := fs.String("id", "", "Dataset ID to export (required)")
	output := fs.String("output", "", "Output database path (required)")
	dryRun := fs.Bool("dry-run", false, "Show what would be exported without creating file")
	force := fs.Bool("force", false, "Overwrite existing output file")

	fs.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: skraak export dataset --db <path> --id <dataset_id> --output <path> [options]\n\n")
		fmt.Fprintf(os.Stderr, "Export a dataset with all related data to a new DuckDB database.\n\n")
		fmt.Fprintf(os.Stderr, "Options:\n")
		fs.PrintDefaults()
		fmt.Fprintf(os.Stderr, "\nExamples:\n")
		fmt.Fprintf(os.Stderr, "  skraak export dataset --db ./db/skraak.duckdb --id abc123 --output export.duckdb\n")
		fmt.Fprintf(os.Stderr, "  skraak export dataset --db ./db/skraak.duckdb --id abc123 --output export.duckdb --dry-run\n")
		fmt.Fprintf(os.Stderr, "  skraak export dataset --db ./db/skraak.duckdb --id abc123 --output export.duckdb --force\n")
	}

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

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

	tools.SetDBPath(*dbPath)

	input := tools.ExportDatasetInput{
		DatasetID: *datasetID,
		Output:    *output,
		DryRun:    *dryRun,
		Force:     *force,
	}

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

	enc := json.NewEncoder(os.Stdout)
	enc.SetIndent("", "  ")
	if err := enc.Encode(outputResult); err != nil {
		fmt.Fprintf(os.Stderr, "Error encoding output: %v\n", err)
		os.Exit(1)
	}
}