package title

import (
    "context"
    "time"

    "bindbox-game/internal/repository/mysql/model"
    "fmt"
)

func (s *service) AssignUserTitle(ctx context.Context, userID int64, titleID int64, expiresAt *time.Time, remark string) error {
    t, err := s.readDB.SystemTitles.WithContext(ctx).
        Where(s.readDB.SystemTitles.ID.Eq(titleID)).First()
    if err != nil || t == nil || t.Status != 1 {
        return err
    }
    ut, err := s.readDB.UserTitles.WithContext(ctx).
        Where(s.readDB.UserTitles.UserID.Eq(userID)).
        Where(s.readDB.UserTitles.TitleID.Eq(titleID)).First()
    if err == nil && ut != nil {
        now := time.Now()
        if ut.Active == 1 && (ut.ExpiresAt.IsZero() || ut.ExpiresAt.After(now)) {
            return fmt.Errorf("already_owned")
        }
        ut.Active = 1
        ut.Remark = remark
        if expiresAt != nil && !expiresAt.IsZero() { ut.ExpiresAt = *expiresAt }
        if err := s.writeDB.UserTitles.WithContext(ctx).Save(ut); err != nil { return err }
    } else {
        now := time.Now()
        row := &model.UserTitles{
            UserID:     userID,
            TitleID:    titleID,
            Active:     1,
            ObtainedAt: now,
            Source:     "admin_assign",
            Remark:     remark,
        }
        if expiresAt != nil && !expiresAt.IsZero() { row.ExpiresAt = *expiresAt }
        if err := s.writeDB.UserTitles.WithContext(ctx).Create(row); err != nil { return err }
    }
    others, _ := s.readDB.UserTitles.WithContext(ctx).
        Where(s.readDB.UserTitles.UserID.Eq(userID)).
        Where(s.readDB.UserTitles.TitleID.Neq(titleID)).
        Where(s.readDB.UserTitles.Active.Eq(1)).Find()
    for _, o := range others {
        o.Active = 0
        _ = s.writeDB.UserTitles.WithContext(ctx).Save(o)
    }
    return nil
}