package bootstrapimpl

import (
	"context"
	"fmt"
	"strings"

	"github.com/nexuscrm/kernel/pkg/schema"
)

type managedPhysicalTableCreator interface {
	CreatePhysicalTable(context.Context, schema.TableDefinition) error
}

// reconcileConnectorV2IngressReceiptAuthorityTables is the resume-safe
// lifecycle owner for the three mandatory V2 ingress receipt authority tables.
// Bootstrap invokes it outside resume-skippable phases: a failure after phase
// 1 must not strand a database whose later resume skips batch table creation.
//
// CreatePhysicalTable is deliberately called unconditionally. Its catalog-
// derived CREATE TABLE IF NOT EXISTS path is the one physical existence owner,
// so this reconciliation neither adds a check-then-create race nor adopts an
// alternative schema declaration. Exact readiness remains responsible for
// rejecting an already-present table whose physical shape has drifted.
func reconcileConnectorV2IngressReceiptAuthorityTables(
	ctx context.Context,
	creator managedPhysicalTableCreator,
	tableDefs []schema.TableDefinition,
) error {
	definitions, err := connectorV2IngressReceiptAuthorityDefinitionsFrom(tableDefs)
	if err != nil {
		return err
	}
	for _, definition := range definitions {
		if err := creator.CreatePhysicalTable(ctx, definition); err != nil {
			return fmt.Errorf("reconcile mandatory table %s: %w", definition.TableName, err)
		}
	}
	return nil
}

func connectorV2IngressReceiptAuthorityDefinitionsFrom(
	tableDefs []schema.TableDefinition,
) ([]schema.TableDefinition, error) {
	definitions := make([]schema.TableDefinition, 0, len(connectorV2IngressReceiptAuthorityTableNames))
	for _, requiredName := range connectorV2IngressReceiptAuthorityTableNames {
		matches := 0
		var found schema.TableDefinition
		for _, definition := range tableDefs {
			if !strings.EqualFold(definition.TableName, requiredName) {
				continue
			}
			matches++
			found = definition
		}
		if matches != 1 {
			return nil, fmt.Errorf(
				"managed catalog must declare exactly one mandatory table %s, found %d",
				requiredName,
				matches,
			)
		}
		definitions = append(definitions, found)
	}
	return definitions, nil
}
