package models

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

// ============================================================
// 🔹 NullUUID — MSSQL UNIQUEIDENTIFIER için nullable tip
// ============================================================
type NullUUID struct {
	UUID  string `json:"UUID"`
	Valid bool   `json:"Valid"`
}

// ------------------------------------------------------------
//
//	SQL Valuer (INSERT/UPDATE parametresi)
//
// ------------------------------------------------------------
func (n NullUUID) Value() (driver.Value, error) {
	if !n.Valid || strings.TrimSpace(n.UUID) == "" {
		return nil, nil
	}
	return n.UUID, nil
}

// ------------------------------------------------------------
//
//	SQL Scanner (SELECT sonucu)
//
// ------------------------------------------------------------
func (n *NullUUID) Scan(value interface{}) error {
	if value == nil {
		n.UUID = ""
		n.Valid = false
		return nil
	}

	switch v := value.(type) {
	case string:
		n.UUID = v
		n.Valid = true
	case []byte:
		n.UUID = string(v)
		n.Valid = true
	default:
		n.UUID = ""
		n.Valid = false
	}
	return nil
}

// ------------------------------------------------------------
//
//	JSON Marshal — Go → JSON
//	 Null ise: null
//	 Değer varsa: "guid-string"
//
// ------------------------------------------------------------
func (n NullUUID) MarshalJSON() ([]byte, error) {
	if !n.Valid || strings.TrimSpace(n.UUID) == "" {
		return []byte("null"), nil
	}
	return json.Marshal(n.UUID)
}

// ------------------------------------------------------------
//
//	JSON Unmarshal — JSON → Go
//	 Kabul ettiği formatlar:
//	  • null
//	  • "guid-string"
//	  • {"UUID":"...","Valid":true} (ileride istersen)
//
// ------------------------------------------------------------
func (n *NullUUID) UnmarshalJSON(data []byte) error {
	s := strings.TrimSpace(string(data))

	// null veya boş
	if s == "null" || s == "" {
		n.UUID = ""
		n.Valid = false
		return nil
	}

	// Önce string gibi dene: "guid"
	var str string
	if err := json.Unmarshal(data, &str); err == nil {
		str = strings.TrimSpace(str)
		if str == "" {
			n.UUID = ""
			n.Valid = false
		} else {
			n.UUID = str
			n.Valid = true
		}
		return nil
	}

	// Objeyse: { "UUID":"...", "Valid":true }
	var aux struct {
		UUID  string `json:"UUID"`
		Valid bool   `json:"Valid"`
	}
	if err := json.Unmarshal(data, &aux); err != nil {
		return err
	}

	aux.UUID = strings.TrimSpace(aux.UUID)
	if aux.UUID == "" || !aux.Valid {
		n.UUID = ""
		n.Valid = false
	} else {
		n.UUID = aux.UUID
		n.Valid = true
	}
	return nil
}
