package postgres

import (
	"context"
	"database/sql"

	"chat-switchboard/models"
)

type PolicyStore struct{}

func NewPolicyStore() *PolicyStore { return &PolicyStore{} }

// Get returns a policy value by key. Falls back to PolicyDefaults if not in DB.
func (s *PolicyStore) Get(ctx context.Context, key string) (string, error) {
	var value string
	err := DB.QueryRowContext(ctx,
		"SELECT value FROM platform_policies WHERE key = $1", key).Scan(&value)
	if err == sql.ErrNoRows {
		if def, ok := models.PolicyDefaults[key]; ok {
			return def, nil
		}
		return "", nil
	}
	return value, err
}

// GetBool returns a policy value as a boolean.
func (s *PolicyStore) GetBool(ctx context.Context, key string) (bool, error) {
	val, err := s.Get(ctx, key)
	if err != nil {
		return false, err
	}
	return val == "true", nil
}

// Set upserts a policy value.
func (s *PolicyStore) Set(ctx context.Context, key, value, updatedBy string) error {
	_, err := DB.ExecContext(ctx, `
		INSERT INTO platform_policies (key, value, updated_by, updated_at)
		VALUES ($1, $2, $3, NOW())
		ON CONFLICT (key) DO UPDATE SET value = $2, updated_by = $3, updated_at = NOW()`,
		key, value, updatedBy)
	return err
}

// GetAll returns all platform policies, merged with defaults.
func (s *PolicyStore) GetAll(ctx context.Context) (map[string]string, error) {
	result := make(map[string]string)
	// Start with defaults
	for k, v := range models.PolicyDefaults {
		result[k] = v
	}
	// Override with DB values
	rows, err := DB.QueryContext(ctx, "SELECT key, value FROM platform_policies")
	if err != nil {
		return result, err // return defaults on error
	}
	defer rows.Close()
	for rows.Next() {
		var k, v string
		if err := rows.Scan(&k, &v); err != nil {
			continue
		}
		result[k] = v
	}
	return result, rows.Err()
}
