package user

import (
	"context"

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

type AddAddressInput struct {
	Name      string
	Mobile    string
	Province  string
	City      string
	District  string
	Address   string
	IsDefault bool
}

func (s *service) AddAddress(ctx context.Context, userID int64, in AddAddressInput) (*model.UserAddresses, error) {
	addr := &model.UserAddresses{
		UserID:    userID,
		Name:      in.Name,
		Mobile:    in.Mobile,
		Province:  in.Province,
		City:      in.City,
		District:  in.District,
		Address:   in.Address,
		IsDefault: 0,
	}
	if in.IsDefault {
		addr.IsDefault = 1
	}
	tx := s.writeDB.Begin()
	if in.IsDefault {
		if _, err := tx.UserAddresses.WithContext(ctx).Where(tx.UserAddresses.UserID.Eq(userID)).UpdateSimple(tx.UserAddresses.IsDefault.Value(0)); err != nil {
			_ = tx.Rollback()
			return nil, err
		}
	}
	if err := tx.UserAddresses.WithContext(ctx).Omit(tx.UserAddresses.DefaultUserUnique).Create(addr); err != nil {
		_ = tx.Rollback()
		return nil, err
	}
	if err := tx.Commit(); err != nil {
		return nil, err
	}
	return addr, nil
}

func (s *service) ListAddresses(ctx context.Context, userID int64, page, pageSize int) (items []*model.UserAddresses, total int64, err error) {
	q := s.readDB.UserAddresses.WithContext(ctx).ReadDB().Where(s.readDB.UserAddresses.UserID.Eq(userID))
	total, err = q.Count()
	if err != nil {
		return nil, 0, err
	}
	if page <= 0 {
		page = 1
	}
	if pageSize <= 0 {
		pageSize = 20
	}
	if pageSize > 100 {
		pageSize = 100
	}
	items, err = q.Order(s.readDB.UserAddresses.IsDefault.Desc(), s.readDB.UserAddresses.ID.Desc()).Offset((page - 1) * pageSize).Limit(pageSize).Find()
	if err != nil {
		return nil, 0, err
	}
	return items, total, nil
}

func (s *service) SetDefaultAddress(ctx context.Context, userID int64, addressID int64) error {
	tx := s.writeDB.Begin()
	// 先将用户所有地址的 is_default 设为 0
	if _, err := tx.UserAddresses.WithContext(ctx).Where(tx.UserAddresses.UserID.Eq(userID)).UpdateSimple(tx.UserAddresses.IsDefault.Value(0)); err != nil {
		_ = tx.Rollback()
		return err
	}
	// 再将指定地址设为默认
	if _, err := tx.UserAddresses.WithContext(ctx).Where(tx.UserAddresses.UserID.Eq(userID), tx.UserAddresses.ID.Eq(addressID)).UpdateSimple(tx.UserAddresses.IsDefault.Value(1)); err != nil {
		_ = tx.Rollback()
		return err
	}
	return tx.Commit()
}

func (s *service) DeleteAddress(ctx context.Context, userID int64, addressID int64) error {
	_, err := s.writeDB.UserAddresses.WithContext(ctx).Where(s.writeDB.UserAddresses.UserID.Eq(userID), s.writeDB.UserAddresses.ID.Eq(addressID)).Delete(&model.UserAddresses{})
	return err
}

type UpdateAddressInput struct {
	Name      string
	Mobile    string
	Province  string
	City      string
	District  string
	Address   string
	IsDefault bool
}

func (s *service) UpdateAddress(ctx context.Context, userID int64, addressID int64, in UpdateAddressInput) error {
	tx := s.writeDB.Begin()
	if in.IsDefault {
		// 先将用户所有地址设为非默认
		if _, err := tx.UserAddresses.WithContext(ctx).Where(tx.UserAddresses.UserID.Eq(userID)).UpdateSimple(tx.UserAddresses.IsDefault.Value(0)); err != nil {
			_ = tx.Rollback()
			return err
		}
	}
	// 更新指定地址的信息
	isDefaultVal := int32(0)
	if in.IsDefault {
		isDefaultVal = 1
	}
	if _, err := tx.UserAddresses.WithContext(ctx).Where(tx.UserAddresses.UserID.Eq(userID), tx.UserAddresses.ID.Eq(addressID)).UpdateSimple(
		tx.UserAddresses.Name.Value(in.Name),
		tx.UserAddresses.Mobile.Value(in.Mobile),
		tx.UserAddresses.Province.Value(in.Province),
		tx.UserAddresses.City.Value(in.City),
		tx.UserAddresses.District.Value(in.District),
		tx.UserAddresses.Address.Value(in.Address),
		tx.UserAddresses.IsDefault.Value(isDefaultVal),
	); err != nil {
		_ = tx.Rollback()
		return err
	}
	return tx.Commit()
}
