package com.zioinfo.mes.uiws.system.service;

import com.zioinfo.mes.uiws.common.UiwsApiException;
import com.zioinfo.mes.uiws.common.UiwsErrorCode;
import com.zioinfo.mes.uiws.system.dto.PageResponse;
import com.zioinfo.mes.uiws.system.dto.RoleDto;
import com.zioinfo.mes.uiws.system.dto.RoleSaveDto;
import com.zioinfo.mes.uiws.system.mapper.DeptRoleMapper;
import com.zioinfo.mes.uiws.system.mapper.RoleMapper;
import com.zioinfo.mes.uiws.system.mapper.RoleMenuMapper;
import com.zioinfo.mes.uiws.system.model.SysRole;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/** 2.1 권한(roles) CRUD. */
@Service
@RequiredArgsConstructor
public class RoleService {

    private final RoleMapper roleMapper;
    private final RoleMenuMapper roleMenuMapper;
    private final DeptRoleMapper deptRoleMapper;

    @Transactional(readOnly = true)
    public PageResponse<RoleDto> list(String keyword, int page, int size) {
        List<RoleDto> content = roleMapper.search(keyword, page * size, size).stream().map(this::toDto).toList();
        return PageResponse.of(content, roleMapper.countSearch(keyword), page, size);
    }

    @Transactional(readOnly = true)
    public RoleDto get(String roleId) {
        return toDto(find(roleId));
    }

    @Transactional
    public RoleDto create(RoleSaveDto dto) {
        if (dto.roleId() == null || dto.roleId().isBlank()) {
            throw new UiwsApiException(UiwsErrorCode.INVALID_REQUEST, "roleId는 등록 시 필수입니다.");
        }
        if (roleMapper.existsById(dto.roleId())) {
            throw new UiwsApiException(UiwsErrorCode.DUPLICATE_KEY, "이미 존재하는 권한 ID입니다.");
        }
        SysRole role = new SysRole();
        role.setRoleId(dto.roleId());
        role.setRoleNm(dto.roleNm());
        role.setRoleDesc(dto.roleDesc());
        role.setUseYn(dto.useYn());
        role.setCreatedBy(SysActor.id());
        roleMapper.insert(role);
        return toDto(find(dto.roleId()));
    }

    @Transactional
    public RoleDto update(String roleId, RoleSaveDto dto) {
        SysRole role = find(roleId);
        role.setRoleNm(dto.roleNm());
        role.setRoleDesc(dto.roleDesc());
        role.setUseYn(dto.useYn());
        role.setUpdatedBy(SysActor.id());
        roleMapper.update(role);
        return toDto(find(roleId));
    }

    @Transactional
    public void delete(List<String> ids) {
        for (String id : ids) {
            if (deptRoleMapper.existsByRoleId(id)) {
                throw new UiwsApiException(UiwsErrorCode.RESOURCE_IN_USE, "부서에 부여된 권한은 삭제할 수 없습니다: " + id);
            }
            roleMenuMapper.deleteByRoleId(id);
            roleMapper.deleteById(id);
        }
    }

    private RoleDto toDto(SysRole r) {
        return new RoleDto(r.getRoleId(), r.getRoleNm(), r.getRoleDesc(), r.getUseYn());
    }

    private SysRole find(String roleId) {
        SysRole r = roleMapper.findById(roleId);
        if (r == null) {
            throw new UiwsApiException(UiwsErrorCode.ROLE_NOT_FOUND);
        }
        return r;
    }
}
