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) error {
	if len(args) < 1 {
		printExportUsage()
		return fmt.Errorf("export subcommand required")
	}

	switch args[0] {
	case "dataset":
		return runExportDataset(args[1:])
	default:
		printExportUsage()
		return fmt.Errorf("unknown export subcommand: %s", args[0])
	}
}

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) error {
	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 {
		return fmt.Errorf("parsing flags: %w", err)
	}

	if err := checkFlags(fs, "--db", *dbPath, "--id", *datasetID, "--output", *output); err != nil {
		return err
	}

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

	outputResult, err := tools.ExportDataset(context.Background(), input)
	if err != nil {
		return fmt.Errorf("exporting dataset: %w", err)
	}

	enc := json.NewEncoder(os.Stdout)
	enc.SetIndent("", "  ")
	if err := enc.Encode(outputResult); err != nil {
		return fmt.Errorf("encoding output: %w", err)
	}
	return nil
}