package common

import (
	"fmt"

	retry "github.com/avast/retry-go/v4"
	"github.com/go-openapi/swag"
	"github.com/tidbcloud/dataflow-service-e2e/internal/log"
	. "github.com/tidbcloud/dataflow-service-e2e/internal/model"
	"github.com/tidbcloud/dataflow-service-e2e/internal/tidbcloud/dedicated/consoleapi"
	import_model "github.com/tidbcloud/dataflow-service-e2e/internal/tidbcloud/dedicated/consoleapi/import/model"
)

// ImportValidator provides validation helper methods for Import E2E tests.
type ImportValidator struct {
	lgr     log.SimpleLogger
	importW *consoleapi.ImportClientWrapper
}

// NewImportValidator creates a new ImportValidator instance.
func NewImportValidator(lgr log.SimpleLogger) *ImportValidator {
	return &ImportValidator{
		lgr:     lgr,
		importW: consoleapi.NewImportClientWrapper(lgr),
	}
}

// Client returns the underlying ImportClientWrapper for direct API access.
func (v *ImportValidator) Client() *consoleapi.ImportClientWrapper {
	return v.importW
}

// IsImportCompleted checks if the import task has reached COMPLETED status.
// Returns nil if completed, error otherwise (for use with Expect).
func (v *ImportValidator) IsImportCompleted(tidbCluster *TiDBDedicatedEntity, importID string) error {
	task, err := v.importW.GetImport(tidbCluster, importID)
	if err != nil {
		return err
	}
	if task.Status == nil {
		return fmt.Errorf("import %s has nil status", importID)
	}
	status := *task.Status
	switch status {
	case import_model.DataflowImportGetRespStatusCOMPLETED:
		v.lgr.Info("import %s completed, totalSize: %s", importID, swag.StringValue(task.TotalSize))
		return nil
	case import_model.DataflowImportGetRespStatusFAILED:
		return retry.Unrecoverable(fmt.Errorf("import %s failed: %s", importID, swag.StringValue(task.Message)))
	case import_model.DataflowImportGetRespStatusCANCELED:
		return retry.Unrecoverable(fmt.Errorf("import %s was canceled", importID))
	default:
		return fmt.Errorf("import %s status: %s, completedPercent: %d, waiting for COMPLETED",
			importID, status, swag.Int64Value(task.CompletedPercent))
	}
}

// IsImportInList checks if the import task appears in the import list.
// Returns nil if found, error otherwise (for use with Expect).
func (v *ImportValidator) IsImportInList(tidbCluster *TiDBDedicatedEntity, importID string) error {
	resp, err := v.importW.ListImports(tidbCluster, 100)
	if err != nil {
		return err
	}
	for _, imp := range resp.Imports {
		if imp.ID == importID {
			var statusStr string
			if imp.Status != nil {
				statusStr = string(*imp.Status)
			}
			v.lgr.Info("import %s found in list, status: %s", importID, statusStr)
			return nil
		}
	}
	return fmt.Errorf("import %s not found in list (total: %s)", importID, swag.StringValue(resp.Total))
}
