package repositories

import (
	configs "astrology-api/configs"
	usermodel "astrology-api/models/usermodel"
	"strings"
)

func FindUserByMobile(mobile string) (*usermodel.User, error) {

	var user usermodel.User
	err := configs.DB.
		Where("contactNo = ?", mobile).
		First(&user).Error
	if err != nil {
		return nil, err
	}
	return &user, nil

}

func FindUserByEmail(email string) (*usermodel.User, error) {

	var user usermodel.User
	err := configs.DB.
		Where("email = ?", email).
		First(&user).Error
	if err != nil {
		return nil, err
	}
	return &user, nil
}

func CreateUser(user *usermodel.User) error {

	return configs.DB.Create(user).Error
}

func FindUserByID(id uint) (*usermodel.User, error) {

	var user usermodel.User

	err := configs.DB.
		Where("id = ?", id).
		First(&user).Error

	if err != nil {
		return nil, err
	}

	return &user, nil
}

func FindUserByToken(token string) (*usermodel.User, error) {

	var user usermodel.User

	err := configs.DB.
		Where("jwt_token = ?", token).
		First(&user).Error

	if err != nil {
		return nil, err
	}

	return &user, nil
}

func UpdateUser(user *usermodel.User) error {
	return configs.DB.Save(user).Error
}

func UpdateUserStatus(userID uint, isActive bool) error {

	var user usermodel.User

	err := configs.DB.
		Where("id = ?", userID).
		First(&user).Error

	if err != nil {
		return err
	}

	user.IsActive = isActive

	return configs.DB.Save(&user).Error
}

func DeleteUser(user *usermodel.User) error {

	user.IsDelete = true

	return configs.DB.Save(user).Error
}

func UpdateMobileVerified(userID uint) error {
	// The column is `mobile_verified`. This said `mobileVerified`, which is a
	// different identifier, not a case variation — MySQL answered every call
	// with "Unknown column 'mobileVerified' in 'field list'", so
	// /verify-mobile-otp failed after the OTP had already been accepted and
	// no account ever reached a mobile-verified state through this path.
	return configs.DB.
		Model(&usermodel.User{}).
		Where("id = ?", userID).
		Update("mobile_verified", true).Error
}

func UpdateEmailVerified(userID uint) error {
	return configs.DB.
		Model(&usermodel.User{}).
		Where("id = ?", userID).
		Update("email_verified", true).Error
}

func UpdateProfileImage(userID uint, imageURL string) error {

	return configs.DB.
		Model(&usermodel.User{}).
		Where("id = ?", userID).
		Update("profile", imageURL).Error
}

func RemoveProfileImage(userID uint) error {

	return configs.DB.
		Model(&usermodel.User{}).
		Where("id = ?", userID).
		Update("profile", "").Error
}

// SaveDeviceToken stores the handset's FCM registration token on the user row.
//
// The schema carries three columns for the same value — device_token,
// fcm_token and token — and only device_token was ever written, so the other
// two were empty on every row. Push notifications look the token up by
// device_token, but anything reading fcm_token (the obvious name, and what the
// PHP side reaches for) found nothing. All three are written together here so
// they cannot disagree.
//
// Called from every entry point where the app can hand over a token:
// register, mobile OTP verification, login OTP verification, social login and
// the dedicated refresh endpoint — FCM rotates tokens, so the refresh matters
// as much as the login.
//
// An empty token is ignored rather than written: an app that omits the field
// must not wipe a registration that is still live.
func SaveDeviceToken(userID uint, deviceToken string, deviceType string) error {

	if userID == 0 || strings.TrimSpace(deviceToken) == "" {
		return nil
	}

	deviceToken = strings.TrimSpace(deviceToken)

	updates := map[string]any{
		"device_token": deviceToken,
		"fcm_token":    deviceToken,
		"token":        deviceToken,
	}

	if value := strings.TrimSpace(deviceType); value != "" {
		updates["device_type"] = value
	}

	return configs.DB.
		Model(&usermodel.User{}).
		Where("id = ?", userID).
		Updates(updates).Error
}
