package repository

import (
	dbgen "Yimaru-Backend/gen/db"
	"Yimaru-Backend/internal/domain"
	"Yimaru-Backend/internal/ports"
	"Yimaru-Backend/internal/services/authentication"
	"context"
	"database/sql"
	"errors"
	"time"

	"github.com/jackc/pgx/v5"
	"github.com/jackc/pgx/v5/pgtype"
)

func NewUserStore(s *Store) ports.UserStore { return s }

func (s *Store) GetUserDeviceTokens(ctx context.Context, userID int64) ([]string, error) {
	return s.queries.GetActiveDeviceTokens(ctx, userID)
}

func (s *Store) RegisterDevice(ctx context.Context, userID int64, deviceToken, platform string) error {
	_, err := s.queries.CreateDevice(ctx, dbgen.CreateDeviceParams{
		UserID:      userID,
		DeviceToken: deviceToken,
		Platform:    pgtype.Text{String: platform, Valid: platform != ""},
	})
	return err
}

func (s *Store) DeactivateDevice(ctx context.Context, userID int64, deviceToken string) error {
	return s.queries.DeactivateDeviceByToken(ctx, dbgen.DeactivateDeviceByTokenParams{
		UserID:      userID,
		DeviceToken: deviceToken,
	})
}

func (s *Store) DeactivateAllUserDevices(ctx context.Context, userID int64) error {
	return s.queries.DeactivateUserDevices(ctx, userID)
}

func (s *Store) LinkGoogleAccount(
	ctx context.Context,
	userID int64,
	googleID string,
) error {

	return s.queries.LinkGoogleAccount(ctx, dbgen.LinkGoogleAccountParams{
		ID:       userID,
		GoogleID: pgtype.Text{String: googleID, Valid: true},
	})
}

func (s *Store) CreateGoogleUser(
	ctx context.Context,
	gUser domain.GoogleUser,
) (domain.User, error) {

	res, err := s.queries.CreateGoogleUser(ctx, dbgen.CreateGoogleUserParams{
		FirstName:           pgtype.Text{String: gUser.GivenName, Valid: true},
		LastName:            pgtype.Text{String: gUser.FamilyName, Valid: true},
		Email:               pgtype.Text{String: gUser.Email, Valid: true},
		GoogleID:            pgtype.Text{String: gUser.ID, Valid: true},
		GoogleEmailVerified: pgtype.Bool{Bool: gUser.VerifiedEmail, Valid: true},
		Role:                string(domain.RoleStudent),
		Status:              string(domain.UserStatusActive),
		ProfilePictureUrl: pgtype.Text{
			String: gUser.Picture,
			Valid:  gUser.Picture != "",
		},
	})
	if err != nil {
		return domain.User{}, err
	}

	return mapDBUser(res, nil, nil), nil
}

func (s *Store) GetProfileCompletionStatus(ctx context.Context, userId int64) (ports.ProfileCompletionStatus, error) {
	result, err := s.queries.GetProfileCompletionStatus(ctx, userId)
	if err != nil {
		if errors.Is(err, sql.ErrNoRows) {
			return ports.ProfileCompletionStatus{}, authentication.ErrUserNotFound
		}
		return ports.ProfileCompletionStatus{}, err
	}
	return ports.ProfileCompletionStatus{
		IsCompleted: result.ProfileCompleted.Bool,
		Percentage:  int(result.ProfileCompletionPercentage),
	}, nil
}

func (s *Store) UpdateUserKnowledgeLevel(ctx context.Context, userID int64, knowledgeLevel string) error {
	return s.queries.UpdateUserKnowledgeLevel(ctx, dbgen.UpdateUserKnowledgeLevelParams{
		ID:             userID,
		KnowledgeLevel: pgtype.Text{String: knowledgeLevel, Valid: true},
	})
}

func (s *Store) IsUserPending(ctx context.Context, userID int64) (bool, error) {
	isPending, err := s.queries.IsUserPending(ctx, userID)
	if err != nil {
		if errors.Is(err, sql.ErrNoRows) {
			return false, authentication.ErrUserNotFound
		}
		return false, err
	}
	return isPending, nil
}

func (s *Store) IsUserNameUnique(ctx context.Context, userID int64) (bool, error) {
	isUnique, err := s.queries.IsUserNameUnique(ctx, userID)
	if err != nil {
		return false, err
	}
	return isUnique, nil
}

func (s *Store) UpdateUserStatus(ctx context.Context, req domain.UpdateUserStatusReq) error {
	return s.queries.UpdateUserStatus(ctx, dbgen.UpdateUserStatusParams{
		Status: req.Status,
		ID:     req.UserID,
	})
}

func (s *Store) CreateUserWithoutOtp(
	ctx context.Context,
	user domain.User,
) (domain.User, error) {

	userRes, err := s.queries.CreateUser(ctx, dbgen.CreateUserParams{
		FirstName: pgtype.Text{String: user.FirstName},
		LastName:  pgtype.Text{String: user.LastName},
		Gender: pgtype.Text{
			String: user.Gender,
			Valid:  user.Gender != "",
		},
		BirthDay: pgtype.Date{
			Time:  user.BirthDay,
			Valid: true,
		},
		// UserName:  user.UserName,

		Email:       pgtype.Text{String: user.Email, Valid: user.Email != ""},
		PhoneNumber: pgtype.Text{String: user.PhoneNumber, Valid: user.PhoneNumber != ""},

		Role:     string(user.Role),
		Password: user.Password,

		AgeGroup:       pgtype.Text{String: user.AgeGroup, Valid: user.AgeGroup != ""},
		EducationLevel: pgtype.Text{String: user.EducationLevel, Valid: user.EducationLevel != ""},
		Country:        pgtype.Text{String: user.Country, Valid: user.Country != ""},
		Region:         pgtype.Text{String: user.Region, Valid: user.Region != ""},

		NickName: pgtype.Text{
			String: user.NickName,
			Valid:  user.NickName != "",
		},
		Occupation: pgtype.Text{
			String: user.Occupation,
			Valid:  user.Occupation != "",
		},
		LearningGoal: pgtype.Text{
			String: user.LearningGoal,
			Valid:  user.LearningGoal != "",
		},
		LanguageGoal: pgtype.Text{
			String: user.LanguageGoal,
			Valid:  user.LanguageGoal != "",
		},
		LanguageChallange: pgtype.Text{
			String: user.LanguageChallange,
			Valid:  user.LanguageChallange != "",
		},
		FavouriteTopic: pgtype.Text{
			String: user.FavouriteTopic,
			Valid:  user.FavouriteTopic != "",
		},

		EmailVerified: user.EmailVerified,
		PhoneVerified: user.PhoneVerified,

		ProfilePictureUrl: pgtype.Text{
			String: user.ProfilePictureURL,
			Valid:  user.ProfilePictureURL != "",
		},
		Status: string(user.Status),
		ProfileCompleted: pgtype.Bool{
			Bool:  user.ProfileCompleted,
			Valid: true,
		},
		PreferredLanguage: pgtype.Text{
			String: user.PreferredLanguage,
			Valid:  user.PreferredLanguage != "",
		},
	})
	if err != nil {
		return domain.User{}, err
	}

	var updatedAt *time.Time
	if userRes.UpdatedAt.Valid {
		updatedAt = &userRes.UpdatedAt.Time
	}

	return mapCreateUserResult(userRes, user.Password, updatedAt), nil
}

// CreateUser inserts a new user into the database
func (s *Store) CreateUser(
	ctx context.Context,
	user domain.User,
	usedOtpId int64,
) (domain.User, error) {

	if usedOtpId > 0 {
		if err := s.queries.MarkOtpAsUsed(ctx, dbgen.MarkOtpAsUsedParams{
			ID:     usedOtpId,
			UsedAt: pgtype.Timestamptz{Time: time.Now(), Valid: true},
		}); err != nil {
			return domain.User{}, err
		}
	}

	userRes, err := s.queries.CreateUser(ctx, dbgen.CreateUserParams{
		FirstName: pgtype.Text{String: user.FirstName},
		LastName:  pgtype.Text{String: user.LastName},
		Gender: pgtype.Text{
			String: user.Gender,
			Valid:  user.Gender != "",
		},
		BirthDay: pgtype.Date{
			Time:  user.BirthDay,
			Valid: true,
		},
		// UserName:  user.UserName,

		Email:       pgtype.Text{String: user.Email, Valid: user.Email != ""},
		PhoneNumber: pgtype.Text{String: user.PhoneNumber, Valid: user.PhoneNumber != ""},

		Role:     string(user.Role),
		Password: user.Password,

		AgeGroup:       pgtype.Text{String: user.AgeGroup, Valid: user.AgeGroup != ""},
		EducationLevel: pgtype.Text{String: user.EducationLevel, Valid: user.EducationLevel != ""},
		Country:        pgtype.Text{String: user.Country, Valid: user.Country != ""},
		Region:         pgtype.Text{String: user.Region, Valid: user.Region != ""},

		NickName:          pgtype.Text{String: user.NickName, Valid: user.NickName != ""},
		Occupation:        pgtype.Text{String: user.Occupation, Valid: user.Occupation != ""},
		LearningGoal:      pgtype.Text{String: user.LearningGoal, Valid: user.LearningGoal != ""},
		LanguageGoal:      pgtype.Text{String: user.LanguageGoal, Valid: user.LanguageGoal != ""},
		LanguageChallange: pgtype.Text{String: user.LanguageChallange, Valid: user.LanguageChallange != ""},
		FavouriteTopic:    pgtype.Text{String: user.FavouriteTopic, Valid: user.FavouriteTopic != ""},

		EmailVerified: user.EmailVerified,
		PhoneVerified: user.PhoneVerified,

		ProfilePictureUrl: pgtype.Text{
			String: user.ProfilePictureURL,
			Valid:  user.ProfilePictureURL != "",
		},
		Status: string(user.Status),
		ProfileCompleted: pgtype.Bool{
			Bool:  user.ProfileCompleted,
			Valid: true,
		},
		PreferredLanguage: pgtype.Text{
			String: user.PreferredLanguage,
			Valid:  user.PreferredLanguage != "",
		},
	})
	if err != nil {
		return domain.User{}, err
	}

	var updatedAt *time.Time
	if userRes.UpdatedAt.Valid {
		updatedAt = &userRes.UpdatedAt.Time
	}

	return mapCreateUserResult(userRes, user.Password, updatedAt), nil
}

// GetUserByID retrieves a user by ID
func (s *Store) GetUserByID(
	ctx context.Context,
	id int64,
) (domain.User, error) {

	u, err := s.queries.GetUserByID(ctx, id)
	if err != nil {
		if errors.Is(err, pgx.ErrNoRows) {
			return domain.User{}, domain.ErrUserNotFound
		}
		return domain.User{}, err
	}

	var lastLogin *time.Time
	if u.LastLogin.Valid {
		lastLogin = &u.LastLogin.Time
	}

	var updatedAt *time.Time
	if u.UpdatedAt.Valid {
		updatedAt = &u.UpdatedAt.Time
	}

	return domain.User{
		ID:        u.ID,
		FirstName: u.FirstName.String,
		LastName:  u.LastName.String,
		Gender:    u.Gender.String,
		BirthDay:  u.BirthDay.Time,
		// UserName:    u.UserName,
		Email:       u.Email.String,
		PhoneNumber: u.PhoneNumber.String,
		Role:        domain.Role(u.Role),

		AgeGroup:       u.AgeGroup.String,
		EducationLevel: u.EducationLevel.String,
		Country:        u.Country.String,
		Region:         u.Region.String,

		NickName:          u.NickName.String,
		Occupation:        u.Occupation.String,
		LearningGoal:      u.LearningGoal.String,
		LanguageGoal:      u.LanguageGoal.String,
		LanguageChallange: u.LanguageChallange.String,
		FavouriteTopic:    u.FavouriteTopic.String,

		EmailVerified: u.EmailVerified,
		PhoneVerified: u.PhoneVerified,
		Status:        domain.UserStatus(u.Status),

		LastLogin:                   lastLogin,
		ProfileCompleted:            u.ProfileCompleted.Bool,
		ProfileCompletionPercentage: int(u.ProfileCompletionPercentage),
		ProfilePictureURL:           u.ProfilePictureUrl.String,
		PreferredLanguage:           u.PreferredLanguage.String,

		CreatedAt: u.CreatedAt.Time,
		UpdatedAt: updatedAt,
	}, nil
}

func (s *Store) GetUserByGoogleID(
	ctx context.Context,
	googleId string,
) (domain.User, error) {

	u, err := s.queries.GetUserByGoogleID(ctx, pgtype.Text{String: googleId, Valid: googleId != ""})
	if err != nil {
		if errors.Is(err, pgx.ErrNoRows) {
			return domain.User{}, domain.ErrUserNotFound
		}
		return domain.User{}, err
	}

	var lastLogin *time.Time
	if u.LastLogin.Valid {
		lastLogin = &u.LastLogin.Time
	}

	var updatedAt *time.Time
	if u.UpdatedAt.Valid {
		updatedAt = &u.UpdatedAt.Time
	}

	return domain.User{
		ID:        u.ID,
		FirstName: u.FirstName.String,
		LastName:  u.LastName.String,
		Gender:    u.Gender.String,
		BirthDay:  u.BirthDay.Time,
		// UserName:    u.UserName,
		Email:       u.Email.String,
		PhoneNumber: u.PhoneNumber.String,
		Role:        domain.Role(u.Role),

		AgeGroup:       u.AgeGroup.String,
		EducationLevel: u.EducationLevel.String,
		Country:        u.Country.String,
		Region:         u.Region.String,

		NickName:          u.NickName.String,
		Occupation:        u.Occupation.String,
		LearningGoal:      u.LearningGoal.String,
		LanguageGoal:      u.LanguageGoal.String,
		LanguageChallange: u.LanguageChallange.String,
		FavouriteTopic:    u.FavouriteTopic.String,

		EmailVerified: u.EmailVerified,
		PhoneVerified: u.PhoneVerified,
		Status:        domain.UserStatus(u.Status),

		LastLogin:         lastLogin,
		ProfileCompleted:  u.ProfileCompleted.Bool,
		ProfilePictureURL: u.ProfilePictureUrl.String,
		PreferredLanguage: u.PreferredLanguage.String,

		CreatedAt: u.CreatedAt.Time,
		UpdatedAt: updatedAt,
	}, nil
}

// GetAllUsers retrieves users with optional filters
func (s *Store) GetAllUsers(
	ctx context.Context,
	role *string,
	query *string,
	createdBefore, createdAfter *time.Time,
	limit, offset int32,
) ([]domain.User, int64, error) {

	// var roleParam sql.NullString
	// if role != nil && *role != "" {
	// 	roleParam = sql.NullString{String: *role, Valid: true}
	// } else {
	// 	roleParam = sql.NullString{Valid: false} // This will make $1 IS NULL work
	// }

	// var queryParam sql.NullString
	// if query != nil && *query != "" {
	// 	queryParam = sql.NullString{String: *query, Valid: true}
	// } else {
	// 	queryParam = sql.NullString{Valid: false}
	// }

	// var createdAfterParam sql.NullTime
	// if createdAfter != nil {
	// 	createdAfterParam = sql.NullTime{Time: *createdAfter, Valid: true}
	// } else {
	// 	createdAfterParam = sql.NullTime{Valid: false}
	// }

	// var createdBeforeParam sql.NullTime
	// if createdBefore != nil {
	// 	createdBeforeParam = sql.NullTime{Time: *createdBefore, Valid: true}
	// } else {
	// 	createdBeforeParam = sql.NullTime{Valid: false}
	// }

	params := dbgen.GetAllUsersParams{
		// Role: pgtype.Text{
		// 	String: roleParam.String,
		// 	Valid:  roleParam.String != "",
		// },
		// Query: queryParam.String,
		// CreatedAfter: pgtype.Timestamptz{
		// 	Time:  createdAfterParam.Time,
		// 	Valid: createdAfterParam.Valid,
		// },
		// CreatedBefore: pgtype.Timestamptz{
		// 	Time:  createdBeforeParam.Time,
		// 	Valid: createdBeforeParam.Valid,
		// },
		Limit: pgtype.Int4{
			Int32: limit,
			Valid: true,
		},
		Offset: pgtype.Int4{
			Int32: offset,
			Valid: true,
		},
	}

	rows, err := s.queries.GetAllUsers(ctx, params)
	if err != nil {
		return nil, 0, err
	}

	if len(rows) == 0 {
		return []domain.User{}, 0, nil
	}

	totalCount := rows[0].TotalCount
	users := make([]domain.User, 0, len(rows))

	for _, u := range rows {

		var updatedAt *time.Time
		if u.UpdatedAt.Valid {
			updatedAt = &u.UpdatedAt.Time
		}

		users = append(users, domain.User{
			ID:        u.ID,
			FirstName: u.FirstName.String,
			LastName:  u.LastName.String,
			Gender:    u.Gender.String,
			BirthDay:  u.BirthDay.Time,
			// UserName:    u.UserName,
			Email:       u.Email.String,
			PhoneNumber: u.PhoneNumber.String,
			Role:        domain.Role(u.Role),

			AgeGroup:       u.AgeGroup.String,
			EducationLevel: u.EducationLevel.String,
			Country:        u.Country.String,
			Region:         u.Region.String,

			NickName:          u.NickName.String,
			Occupation:        u.Occupation.String,
			LearningGoal:      u.LearningGoal.String,
			LanguageGoal:      u.LanguageGoal.String,
			LanguageChallange: u.LanguageChallange.String,
			FavouriteTopic:    u.FavouriteTopic.String,

			EmailVerified: u.EmailVerified,
			PhoneVerified: u.PhoneVerified,
			Status:        domain.UserStatus(u.Status),

			ProfilePictureURL: u.ProfilePictureUrl.String,
			ProfileCompleted:  u.ProfileCompleted.Bool,
			PreferredLanguage: u.PreferredLanguage.String,

			CreatedAt: u.CreatedAt.Time,
			UpdatedAt: updatedAt,
		})
	}

	return users, totalCount, nil
}

// GetTotalUsers counts users with optional filters
func (s *Store) GetTotalUsers(ctx context.Context, role *string) (int64, error) {
	count, err := s.queries.GetTotalUsers(ctx, *role)
	if err != nil {
		return 0, err
	}
	return count, nil
}

// SearchUserByNameOrPhone searches users by name or phone
func (s *Store) SearchUserByNameOrPhone(
	ctx context.Context,
	search string,
	role *string,
) ([]domain.User, error) {

	params := dbgen.SearchUserByNameOrPhoneParams{
		Column1: pgtype.Text{
			String: search,
			Valid:  search != "",
		},
	}

	if role != nil {
		params.Role = pgtype.Text{
			String: *role,
			Valid:  true,
		}
	}

	rows, err := s.queries.SearchUserByNameOrPhone(ctx, params)
	if err != nil {
		return nil, err
	}

	if len(rows) == 0 {
		return []domain.User{}, nil
	}

	users := make([]domain.User, 0, len(rows))

	for _, u := range rows {

		var updatedAt *time.Time
		if u.UpdatedAt.Valid {
			updatedAt = &u.UpdatedAt.Time
		}

		users = append(users, domain.User{
			ID:        u.ID,
			FirstName: u.FirstName.String,
			LastName:  u.LastName.String,
			Gender:    u.Gender.String,
			BirthDay:  u.BirthDay.Time,
			// UserName:    u.UserName,
			Email:       u.Email.String,
			PhoneNumber: u.PhoneNumber.String,
			Role:        domain.Role(u.Role),

			AgeGroup:       u.AgeGroup.String,
			EducationLevel: u.EducationLevel.String,
			Country:        u.Country.String,
			Region:         u.Region.String,

			NickName:          u.NickName.String,
			Occupation:        u.Occupation.String,
			LearningGoal:      u.LearningGoal.String,
			LanguageGoal:      u.LanguageGoal.String,
			LanguageChallange: u.LanguageChallange.String,
			FavouriteTopic:    u.FavouriteTopic.String,

			EmailVerified: u.EmailVerified,
			PhoneVerified: u.PhoneVerified,
			Status:        domain.UserStatus(u.Status),

			ProfileCompleted:  u.ProfileCompleted.Bool,
			ProfilePictureURL: u.ProfilePictureUrl.String,
			PreferredLanguage: u.PreferredLanguage.String,

			CreatedAt: u.CreatedAt.Time,
			UpdatedAt: updatedAt,
		})
	}

	return users, nil
}

// UpdateUser updates basic user info
func (s *Store) UpdateUser(
	ctx context.Context,
	req domain.UpdateUserReq,
) error {

	var birthDate pgtype.Date
	if req.BirthDay != nil && *req.BirthDay != "" {
		t, err := time.Parse("2006-01-02", *req.BirthDay)
		if err != nil {
			return err
		}
		birthDate = pgtype.Date{Time: t, Valid: true}
	}

	var ageGroup pgtype.Text
	if req.AgeGroup != nil {
		ageGroup = pgtype.Text{String: string(*req.AgeGroup), Valid: true}
	}

	return s.queries.UpdateUser(ctx, dbgen.UpdateUserParams{
		FirstName: pgtype.Text{String: req.FirstName, Valid: req.FirstName != ""},
		LastName:  pgtype.Text{String: req.LastName, Valid: req.LastName != ""},

		KnowledgeLevel: pgtype.Text{String: req.KnowledgeLevel, Valid: req.KnowledgeLevel != ""},
		AgeGroup:       ageGroup,

		EducationLevel: pgtype.Text{String: req.EducationLevel, Valid: req.EducationLevel != ""},
		Country:        pgtype.Text{String: req.Country, Valid: req.Country != ""},
		Region:         pgtype.Text{String: req.Region, Valid: req.Region != ""},

		NickName:          pgtype.Text{String: req.NickName, Valid: req.NickName != ""},
		Occupation:        pgtype.Text{String: req.Occupation, Valid: req.Occupation != ""},
		LearningGoal:      pgtype.Text{String: req.LearningGoal, Valid: req.LearningGoal != ""},
		LanguageGoal:      pgtype.Text{String: req.LanguageGoal, Valid: req.LanguageGoal != ""},
		LanguageChallange: pgtype.Text{String: req.LanguageChallange, Valid: req.LanguageChallange != ""},
		FavouriteTopic:    pgtype.Text{String: req.FavouriteTopic, Valid: req.FavouriteTopic != ""},

		InitialAssessmentCompleted: req.InitialAssessmentCompleted,

		ProfilePictureUrl: pgtype.Text{String: req.ProfilePictureURL, Valid: req.ProfilePictureURL != ""},
		PreferredLanguage: pgtype.Text{String: req.PreferredLanguage, Valid: req.PreferredLanguage != ""},

		Gender:   pgtype.Text{String: req.Gender, Valid: req.Gender != ""},
		BirthDay: birthDate,

		ID: req.UserID,
	})
}

// DeleteUser removes a user
func (s *Store) DeleteUser(ctx context.Context, userID int64) error {
	return s.queries.DeleteUser(ctx, userID)
}

// CheckPhoneEmailExist checks if phone or email exists in an organization
func (s *Store) CheckPhoneEmailExist(ctx context.Context, phone, email string) (phoneExists, emailExists bool, err error) {
	res, err := s.queries.CheckPhoneEmailExist(ctx, dbgen.CheckPhoneEmailExistParams{
		PhoneNumber: pgtype.Text{String: phone},
		Email:       pgtype.Text{String: email},
	})
	if err != nil {
		return false, false, err
	}

	return res.PhoneExists, res.EmailExists, nil
}

// GetUserByEmail retrieves a user by email and organization
func (s *Store) GetUserByEmailPhone(
	ctx context.Context,
	email string,
	phone string,
) (domain.User, error) {

	u, err := s.queries.GetUserByEmailPhone(ctx, dbgen.GetUserByEmailPhoneParams{
		Email: pgtype.Text{
			String: email,
			Valid:  email != "",
		},
		PhoneNumber: pgtype.Text{
			String: phone,
			Valid:  phone != "",
		},
	})
	if err != nil {
		if errors.Is(err, sql.ErrNoRows) || errors.Is(err, pgx.ErrNoRows) {
			return domain.User{}, domain.ErrUserNotFound
		}
		return domain.User{}, err
	}

	var lastLogin *time.Time
	if u.LastLogin.Valid {
		lastLogin = &u.LastLogin.Time
	}

	var updatedAt *time.Time
	if u.UpdatedAt.Valid {
		updatedAt = &u.UpdatedAt.Time
	}

	return domain.User{
		ID:        u.ID,
		FirstName: u.FirstName.String,
		LastName:  u.LastName.String,
		Gender:    u.Gender.String,
		BirthDay:  u.BirthDay.Time,
		// UserName:    u.UserName,
		Email:       u.Email.String,
		PhoneNumber: u.PhoneNumber.String,
		Password:    u.Password,
		Role:        domain.Role(u.Role),

		AgeGroup:       u.AgeGroup.String,
		EducationLevel: u.EducationLevel.String,
		Country:        u.Country.String,
		Region:         u.Region.String,

		NickName:          u.NickName.String,
		Occupation:        u.Occupation.String,
		LearningGoal:      u.LearningGoal.String,
		LanguageGoal:      u.LanguageGoal.String,
		LanguageChallange: u.LanguageChallange.String,
		FavouriteTopic:    u.FavouriteTopic.String,

		EmailVerified: u.EmailVerified,
		PhoneVerified: u.PhoneVerified,
		Status:        domain.UserStatus(u.Status),

		ProfilePictureURL: u.ProfilePictureUrl.String,
		LastLogin:         lastLogin,
		ProfileCompleted:  u.ProfileCompleted.Bool,
		PreferredLanguage: u.PreferredLanguage.String,

		CreatedAt: u.CreatedAt.Time,
		UpdatedAt: updatedAt,
	}, nil
}

// UpdatePassword updates a user's password (deprecated - use UpdatePasswordHash)
func (s *Store) UpdatePassword(ctx context.Context, password string, userID int64) error {
	return s.queries.UpdatePassword(ctx, dbgen.UpdatePasswordParams{
		Password: []byte(password),
		ID:       userID,
	})
}

// UpdatePasswordHash updates a user's password with a pre-hashed value
func (s *Store) UpdatePasswordHash(ctx context.Context, hashedPassword []byte, userID int64) error {
	return s.queries.UpdatePassword(ctx, dbgen.UpdatePasswordParams{
		Password: hashedPassword,
		ID:       userID,
	})
}

// mapUser converts dbgen.User to domain.User
func mapCreateUserResult(
	userRes dbgen.CreateUserRow,
	password []byte,
	updatedAt *time.Time,
) domain.User {

	return domain.User{
		ID:        userRes.ID,
		FirstName: userRes.FirstName.String,
		LastName:  userRes.LastName.String,
		Gender:    userRes.Gender.String,
		BirthDay:  userRes.BirthDay.Time,
		// UserName:    userRes.UserName,
		Email:       userRes.Email.String,
		PhoneNumber: userRes.PhoneNumber.String,
		Role:        domain.Role(userRes.Role),
		Password:    password,

		AgeGroup:       userRes.AgeGroup.String,
		EducationLevel: userRes.EducationLevel.String,
		Country:        userRes.Country.String,
		Region:         userRes.Region.String,

		NickName:          userRes.NickName.String,
		Occupation:        userRes.Occupation.String,
		LearningGoal:      userRes.LearningGoal.String,
		LanguageGoal:      userRes.LanguageGoal.String,
		LanguageChallange: userRes.LanguageChallange.String,
		FavouriteTopic:    userRes.FavouriteTopic.String,

		EmailVerified: userRes.EmailVerified,
		PhoneVerified: userRes.PhoneVerified,
		Status:        domain.UserStatus(userRes.Status),

		ProfileCompleted:  userRes.ProfileCompleted.Bool,
		PreferredLanguage: userRes.PreferredLanguage.String,

		CreatedAt: userRes.CreatedAt.Time,
		UpdatedAt: updatedAt,
	}
}

// mapDBUser converts dbgen.User to domain.User (used by CreateGoogleUser)
func mapDBUser(
	userRes dbgen.User,
	password []byte,
	updatedAt *time.Time,
) domain.User {

	return domain.User{
		ID:        userRes.ID,
		FirstName: userRes.FirstName.String,
		LastName:  userRes.LastName.String,
		Gender:    userRes.Gender.String,
		BirthDay:  userRes.BirthDay.Time,
		// UserName:    userRes.UserName,
		Email:       userRes.Email.String,
		PhoneNumber: userRes.PhoneNumber.String,
		Role:        domain.Role(userRes.Role),
		Password:    password,

		AgeGroup:       userRes.AgeGroup.String,
		EducationLevel: userRes.EducationLevel.String,
		Country:        userRes.Country.String,
		Region:         userRes.Region.String,

		NickName:          userRes.NickName.String,
		Occupation:        userRes.Occupation.String,
		LearningGoal:      userRes.LearningGoal.String,
		LanguageGoal:      userRes.LanguageGoal.String,
		LanguageChallange: userRes.LanguageChallange.String,
		FavouriteTopic:    userRes.FavouriteTopic.String,

		EmailVerified: userRes.EmailVerified,
		PhoneVerified: userRes.PhoneVerified,
		Status:        domain.UserStatus(userRes.Status),

		ProfilePictureURL: userRes.ProfilePictureUrl.String,
		ProfileCompleted:  userRes.ProfileCompleted.Bool,
		PreferredLanguage: userRes.PreferredLanguage.String,

		CreatedAt: userRes.CreatedAt.Time,
		UpdatedAt: updatedAt,
	}
}
