package shop

import (
	"context"

	"github.com/break/junhong_cmp_fiber/internal/model"
	"github.com/break/junhong_cmp_fiber/internal/model/dto"
	"github.com/break/junhong_cmp_fiber/pkg/constants"
	"github.com/break/junhong_cmp_fiber/pkg/errors"
	"github.com/break/junhong_cmp_fiber/pkg/middleware"
)

func (s *Service) AssignRolesToShop(ctx context.Context, shopID uint, roleIDs []uint) ([]*model.ShopRole, error) {
	if err := middleware.CanManageShop(ctx, shopID); err != nil {
		return nil, err
	}

	shop, err := s.shopStore.GetByID(ctx, shopID)
	if err != nil {
		return nil, errors.New(errors.CodeNotFound, "店铺不存在")
	}

	currentUserID := middleware.GetUserIDFromContext(ctx)

	if len(roleIDs) == 0 {
		if err := s.shopRoleStore.DeleteByShopID(ctx, shopID); err != nil {
			return nil, errors.Wrap(errors.CodeInternalError, err, "清空店铺角色失败")
		}
		return []*model.ShopRole{}, nil
	}

	roles, err := s.roleStore.GetByIDs(ctx, roleIDs)
	if err != nil {
		return nil, errors.Wrap(errors.CodeInternalError, err, "查询角色失败")
	}
	if len(roles) != len(roleIDs) {
		return nil, errors.New(errors.CodeNotFound, "部分角色不存在")
	}

	for _, role := range roles {
		if role.RoleType != constants.RoleTypeCustomer {
			return nil, errors.New(errors.CodeInvalidParam, "店铺只能分配客户角色")
		}
		if role.Status != constants.StatusEnabled {
			return nil, errors.New(errors.CodeInvalidParam, "角色已禁用")
		}
	}

	if err := s.shopRoleStore.DeleteByShopID(ctx, shopID); err != nil {
		return nil, errors.Wrap(errors.CodeInternalError, err, "删除现有店铺角色失败")
	}

	shopRoles := make([]*model.ShopRole, 0, len(roleIDs))
	for _, roleID := range roleIDs {
		shopRole := &model.ShopRole{
			ShopID:  shop.ID,
			RoleID:  roleID,
			Status:  constants.StatusEnabled,
			Creator: currentUserID,
			Updater: currentUserID,
		}
		shopRoles = append(shopRoles, shopRole)
	}

	if err := s.shopRoleStore.BatchCreate(ctx, shopRoles); err != nil {
		return nil, errors.Wrap(errors.CodeInternalError, err, "批量创建店铺角色失败")
	}

	return shopRoles, nil
}

func (s *Service) GetShopRoles(ctx context.Context, shopID uint) (*dto.ShopRolesResponse, error) {
	if err := middleware.CanManageShop(ctx, shopID); err != nil {
		return nil, err
	}

	_, err := s.shopStore.GetByID(ctx, shopID)
	if err != nil {
		return nil, errors.New(errors.CodeNotFound, "店铺不存在")
	}

	shopRoles, err := s.shopRoleStore.GetByShopID(ctx, shopID)
	if err != nil {
		return nil, errors.Wrap(errors.CodeInternalError, err, "查询店铺角色失败")
	}

	if len(shopRoles) == 0 {
		return &dto.ShopRolesResponse{
			ShopID: shopID,
			Roles:  []*dto.ShopRoleResponse{},
		}, nil
	}

	roleIDs := make([]uint, 0, len(shopRoles))
	for _, sr := range shopRoles {
		roleIDs = append(roleIDs, sr.RoleID)
	}

	roles, err := s.roleStore.GetByIDs(ctx, roleIDs)
	if err != nil {
		return nil, errors.Wrap(errors.CodeInternalError, err, "查询角色详情失败")
	}

	roleMap := make(map[uint]*model.Role)
	for _, role := range roles {
		roleMap[role.ID] = role
	}

	responses := make([]*dto.ShopRoleResponse, 0, len(shopRoles))
	for _, sr := range shopRoles {
		role, exists := roleMap[sr.RoleID]
		if !exists {
			continue
		}
		responses = append(responses, &dto.ShopRoleResponse{
			ShopID:   sr.ShopID,
			RoleID:   sr.RoleID,
			RoleName: role.RoleName,
			RoleDesc: role.RoleDesc,
			Status:   sr.Status,
		})
	}

	return &dto.ShopRolesResponse{
		ShopID: shopID,
		Roles:  responses,
	}, nil
}

func (s *Service) DeleteShopRole(ctx context.Context, shopID, roleID uint) error {
	if err := middleware.CanManageShop(ctx, shopID); err != nil {
		return err
	}

	_, err := s.shopStore.GetByID(ctx, shopID)
	if err != nil {
		return errors.New(errors.CodeNotFound, "店铺不存在")
	}

	if err := s.shopRoleStore.Delete(ctx, shopID, roleID); err != nil {
		return errors.Wrap(errors.CodeInternalError, err, "删除店铺角色失败")
	}

	return nil
}
