package identity

import (
	"database/sql/driver"
	"encoding/json"
	"fmt"
	"strconv"
	"strings"
)

type SettingValue []byte

func (v *SettingValue) Scan(value any) error {
	if value == nil {
		*v = nil
		return nil
	}
	switch raw := value.(type) {
	case []byte:
		*v = append((*v)[0:0], raw...)
	case string:
		*v = append((*v)[0:0], raw...)
	default:
		return fmt.Errorf("unsupported setting value type %T", value)
	}
	return nil
}

func (v SettingValue) Value() (driver.Value, error) {
	if len(v) == 0 {
		return nil, nil
	}
	return string(v), nil
}

func (v SettingValue) Bool(defaultValue bool) bool {
	if len(v) == 0 {
		return defaultValue
	}
	var decoded any
	if err := json.Unmarshal(v, &decoded); err == nil {
		switch value := decoded.(type) {
		case bool:
			return value
		case string:
			return truthyString(value, defaultValue)
		case float64:
			return value != 0
		case nil:
			return defaultValue
		}
	}
	return truthyString(string(v), defaultValue)
}

func truthyString(value string, defaultValue bool) bool {
	normalized := strings.TrimSpace(strings.ToLower(value))
	if parsed, err := strconv.ParseBool(normalized); err == nil {
		return parsed
	}
	switch normalized {
	case "", "1", "yes", "on", "enabled":
		return true
	case "0", "no", "off", "disabled":
		return false
	default:
		return defaultValue
	}
}
