package bootstrapimpl

import (
	"context"
	"database/sql"
	"strings"

	"github.com/rs/zerolog/log"
)

// ReconcileSystemObjectTableTypes updates _System_Object.TableType to match the
// authoritative definitions in system_tables.json. SF-imported or legacy entries may
// have incorrect TableType values (e.g., "standard_object" for system_metadata tables).
// This is the generic fix — no per-table bootstrap functions needed.
func ReconcileSystemObjectTableTypes(ctx context.Context, db *sql.DB) error {
	defs := GetManagedTableDefinitions()
	updated := 0
	for _, def := range defs {
		if def.TableType == "" {
			continue
		}
		result, err := db.ExecContext(ctx,
			"UPDATE `_System_Object` SET `TableType` = ? WHERE `APIName` = ? AND (`TableType` != ? OR `TableType` IS NULL)",
			string(def.TableType), def.TableName, string(def.TableType),
		)
		if err != nil {
			continue
		}
		if n, _ := result.RowsAffected(); n > 0 {
			updated++
		}

		// Also reconcile RequiredReadPermission from system_tables.json
		if def.RequiredReadPermission != "" {
			if _, rrpErr := db.ExecContext(ctx,
				"UPDATE `_System_Object` SET `RequiredReadPermission` = ? WHERE `APIName` = ? AND (`RequiredReadPermission` != ? OR `RequiredReadPermission` IS NULL)",
				def.RequiredReadPermission, def.TableName, def.RequiredReadPermission,
			); rrpErr != nil {
				log.Warn().Err(rrpErr).Str("table", def.TableName).Msg("Failed to reconcile RequiredReadPermission")
			}
		}
	}
	if updated > 0 {
		log.Info().Int("updated", updated).Msg("✅ Reconciled TableType values from system_tables.json")
	}
	return nil
}

// EnsureFolderSharingModels reconciles declared SharingModel values from
// managed metadata. Non-default folder sharing semantics are authored on the
// table definition; bootstrap must not infer them from object names.
func EnsureFolderSharingModels(ctx context.Context, db *sql.DB) error {
	updated := 0
	for _, def := range GetManagedTableDefinitions() {
		model := strings.TrimSpace(def.SharingModel)
		if model == "" {
			continue
		}
		result, err := db.ExecContext(ctx,
			"UPDATE `_System_Object` SET `SharingModel` = ? WHERE `APIName` = ? AND (`SharingModel` != ? OR `SharingModel` IS NULL)",
			model, def.TableName, model,
		)
		if err != nil {
			log.Warn().Err(err).Str("object", def.TableName).Msg("Failed to update SharingModel")
			continue
		}
		if n, _ := result.RowsAffected(); n > 0 {
			updated++
			log.Info().Str("object", def.TableName).Str("model", model).Msg("✅ Updated SharingModel")
		}
	}

	return nil
}
