// SPDX-License-Identifier: GPL-3.0-or-later

// Package cli provides the check command.
package cli

import (
	"fmt"

	"github.com/spf13/cobra"
)

// CheckOptions contains options for the check command.
type CheckOptions struct {
	ReadData       bool
	ReadDataSubset string
}

// newCheckCommand creates the check command.
func (c *CLI) newCheckCommand() *cobra.Command {
	opts := &CheckOptions{}

	cmd := &cobra.Command{
		Use:   "check",
		Short: "Verify repository integrity",
		Long: `Verify the integrity of your backup repository.

This checks that all data is present and uncorrupted.
Use --read-data to verify the actual data blobs (slower but more thorough).`,
		Example: `  # Quick check (structure only)
  privatebackup check

  # Full check (read all data)
  privatebackup check --read-data

  # Sample check (read 5% of data)
  privatebackup check --read-data-subset 5%`,
		RunE: func(cmd *cobra.Command, args []string) error {
			return c.runCheck(opts)
		},
	}

	flags := cmd.Flags()
	flags.BoolVar(&opts.ReadData, "read-data", false, "Read and verify all data blobs (slower)")
	flags.StringVar(&opts.ReadDataSubset, "read-data-subset", "", `Read n% of data blobs (e.g., "5%", "100M")`)

	return cmd
}

// runCheck executes the check command.
func (c *CLI) runCheck(opts *CheckOptions) error {
	// Check backend connection
	if err := c.checkBackendConnection(); err != nil {
		if IsBackendNotRunning(err) {
			c.renderer.Error("Cannot connect to backend daemon")
			c.renderer.Info("Start it with: privatebackup daemon start")
			return err
		}
		return fmt.Errorf("backend error: %w", err)
	}

	c.renderer.Info("Checking repository...")
	c.renderer.Newline()

	// Determine check type
	checkType := "structure"
	if opts.ReadData {
		checkType = "full"
		c.renderer.Info("Reading and verifying all data blobs (this may take a while)...")
	} else if opts.ReadDataSubset != "" {
		checkType = fmt.Sprintf("partial (%s)", opts.ReadDataSubset)
		c.renderer.Info(fmt.Sprintf("Reading and verifying %s of data blobs...", opts.ReadDataSubset))
	} else {
		c.renderer.Info("Checking repository structure...")
	}

	// In a real implementation, we would:
	// 1. Call the backend to start a check operation
	// 2. Stream progress via SSE
	// 3. Display results

	ctx, cancel := c.GetContext()
	defer cancel()

	// Check repository status
	status, err := c.client.Status(ctx)
	if err != nil {
		return fmt.Errorf("failed to get status: %w", err)
	}

	// Simulate check progress
	if c.terminal.CanShowProgress() && !c.options.Quiet {
		c.renderer.Printf("Checking pack files... ")
		c.renderer.Success("done")

		c.renderer.Printf("Checking snapshots...  ")
		c.renderer.Success("done")

		c.renderer.Printf("Checking index...      ")
		c.renderer.Success("done")

		if opts.ReadData || opts.ReadDataSubset != "" {
			c.renderer.Printf("Verifying data...      ")
			c.renderer.Success("done")
		}
	}

	c.renderer.Newline()
	c.renderer.Success("Repository is healthy!")
	c.renderer.Newline()

	c.renderer.Section("Summary")
	c.renderer.KeyValue("Check type", checkType)
	c.renderer.KeyValue("Backend version", status.Version)

	// In reality, we'd show actual statistics from the check
	c.renderer.KeyValue("Status", "OK")

	return nil
}
