package bootstrap

import (
	"context"
	"database/sql"

	"github.com/nexuscrm/shared/pkg/constants"
	"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 SharingModel for folder-related objects.
// Objects with a non-default SharingModel in defaultSharingModel() need their
// DB values updated — the bootstrap table creation uses the old default, and
// SF-imported objects retain their original SharingModel.
func EnsureFolderSharingModels(ctx context.Context, db *sql.DB) error {
	// Map of apiName → required SharingModel (from defaultSharingModel logic)
	overrides := map[string]string{
		"ReportFolder":          string(constants.SharingModelFolderSharing),
		"Report":                string(constants.SharingModelFolderContentSharing),
		"Dashboard":             string(constants.SharingModelFolderContentSharing),
		"_System_EmailTemplate": string(constants.SharingModelFolderContentSharing),
		"DashboardComponent":    string(constants.SharingModelControlledByParent),
	}
	updated := 0
	for apiName, model := range overrides {
		result, err := db.ExecContext(ctx,
			"UPDATE `_System_Object` SET `SharingModel` = ? WHERE `APIName` = ? AND `SharingModel` != ?",
			model, apiName, model,
		)
		if err != nil {
			log.Warn().Err(err).Str("object", apiName).Msg("Failed to update SharingModel")
			continue
		}
		if n, _ := result.RowsAffected(); n > 0 {
			updated++
			log.Info().Str("object", apiName).Str("model", model).Msg("✅ Updated SharingModel")
		}
	}

	return nil
}
