/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许，不可做商业用途！
 *
 * 版权所有，侵权必究！
 */

package com.yami.shop.admin.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.bean.model.UserAddr;
import com.yami.shop.common.annotation.SysLog;
import com.yami.shop.service.UserAddrService;
import lombok.AllArgsConstructor;
import com.yami.shop.common.response.ServerResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;

/**
 * 用户地址管理相关的控制器类，主要负责处理用户地址的增删改查操作，
 * 各个方法分别实现了分页查询、根据ID获取单个地址信息、新增地址、更新地址以及删除地址等功能，
 * 并且在部分操作上添加了权限控制以及操作日志记录功能，方便后续权限管理和操作记录查看。
 *
 * @author hzm
 * @date 2019-04-15 10:49:40
 */
@RestController
@AllArgsConstructor
@RequestMapping("/user/addr")
public class UserAddrController {

    // 通过lombok的@AllArgsConstructor注解注入UserAddrService，用于处理与用户地址相关的业务逻辑，
    // 例如地址信息的查询、保存、更新、删除等操作。
    private final UserAddrService userAddrService;

    /**
     * 分页查询用户地址信息的方法，接收分页参数（PageParam对象）和用于筛选的用户地址对象（UserAddr对象）作为参数，
     * 通过UserAddrService进行分页查询，这里构建的LambdaQueryWrapper暂时没有添加额外的筛选条件，
     * 最后将查询到的分页结果封装在成功的响应实体中返回给前端。此方法没有添加权限控制注解，需根据实际业务需求确认是否需要添加相应权限控制。
     *
     * @param page 分页参数对象，用于指定页码、每页数量等分页相关信息。
     * @param userAddr 用户地址对象，理论上可用于添加更多筛选条件，但目前代码中未使用，可根据业务扩展添加相应条件查询逻辑。
     * @return 返回包含分页后的用户地址信息的ServerResponseEntity对象，若查询成功则响应体中包含符合条件的分页地址数据，否则返回相应错误信息。
     */
    @GetMapping("/page")
    public ServerResponseEntity<IPage<UserAddr>> getUserAddrPage(PageParam page, UserAddr userAddr) {
        // 使用UserAddrService的page方法进行分页查询，传入分页参数和一个空的LambdaQueryWrapper（目前无额外筛选条件），获取分页结果。
        return ServerResponseEntity.success(userAddrService.page(page, new LambdaQueryWrapper<UserAddr>()));
    }

    /**
     * 根据用户地址ID获取用户地址详细信息的方法，通过传入的地址ID，调用UserAddrService的getById方法从数据库中查询对应的用户地址对象，
     * 并将其封装在成功的响应实体中返回给前端。此方法没有添加权限控制注解，需根据实际业务需求确认是否需要添加相应权限控制。
     *
     * @param addrId 要获取详细信息的用户地址的唯一标识符。
     * @return 返回包含用户地址详细信息的ServerResponseEntity对象，若获取成功则响应体中包含对应的用户地址对象，否则返回相应错误信息。
     */
    @GetMapping("/info/{addrId}")
    public ServerResponseEntity<UserAddr> getById(@PathVariable("addrId") Long addrId) {
        return ServerResponseEntity.success(userAddrService.getById(addrId));
    }

    /**
     * 新增用户地址信息的方法，接收一个经过验证（通过@Valid注解）的用户地址对象（UserAddr）作为请求体，代表要新增的地址信息，
     * 通过UserAddrService的save方法将用户地址信息保存到数据库中，并将保存结果（布尔值，表示是否保存成功）封装在成功的响应实体中返回给前端。
     * 通过@PreAuthorize注解进行权限控制，只有具备"user:addr:save"权限的用户才能访问此方法，同时使用@SysLog注解记录此操作的日志信息，方便后续查看操作记录。
     *
     * @param userAddr 包含要新增的用户地址信息的请求体对象，如地址名称、详细地址、联系人等属性。
     * @return 返回表示操作成功的ServerResponseEntity对象，响应体中包含表示是否新增成功的布尔值，若保存成功则为true，否则为false。
     */
    @SysLog("新增用户地址管理")
    @PostMapping
    @PreAuthorize("@pms.hasPermission('user:addr:save')")
    public ServerResponseEntity<Boolean> save(@RequestBody @Valid UserAddr userAddr) {
        return ServerResponseEntity.success(userAddrService.save(userAddr));
    }

    /**
     * 修改用户地址信息的方法，接收一个经过验证（通过@Valid注解）的用户地址对象（UserAddr）作为请求体，代表要更新的地址信息，
     * 通过UserAddrService的updateById方法将更新后的用户地址信息保存到数据库中，并将更新结果（布尔值，表示是否更新成功）封装在成功的响应实体中返回给前端。
     * 通过@PreAuthorize注解进行权限控制，只有具备"user:addr:update"权限的用户才能访问此方法，同时使用@SysLog注解记录此操作的日志信息，方便后续查看操作记录。
     *
     * @param userAddr 包含要更新的用户地址信息的请求体对象，如地址名称、详细地址、联系人等属性。
     * @return 返回表示操作成功的ServerResponseEntity对象，响应体中包含表示是否更新成功的布尔值，若更新成功则为true，否则为false。
     */
    @SysLog("修改用户地址管理")
    @PutMapping
    @PreAuthorize("@pms.hasPermission('user:addr:update')")
    public ServerResponseEntity<Boolean> updateById(@RequestBody @Valid UserAddr userAddr) {
        return ServerResponseEntity.success(userAddrService.updateById(userAddr));
    }

    /**
     * 根据用户地址ID删除用户地址信息的方法，通过传入的地址ID，调用UserAddrService的removeById方法从数据库中删除对应的用户地址信息，
     * 并将删除结果（布尔值，表示是否删除成功）封装在成功的响应实体中返回给前端。
     * 通过@PreAuthorize注解进行权限控制，只有具备"user:addr:delete"权限的用户才能访问此方法，同时使用@SysLog注解记录此操作的日志信息，方便后续查看操作记录。
     *
     * @param addrId 要删除的用户地址的唯一标识符。
     * @return 返回表示操作成功的ServerResponseEntity对象，响应体中包含表示是否删除成功的布尔值，若删除成功则为true，否则为false。
     */
    @SysLog("删除用户地址管理")
    @DeleteMapping("/{addrId}")
    @PreAuthorize("@pms.hasPermission('user:addr:delete')")
    public ServerResponseEntity<Boolean> removeById(@PathVariable Long addrId) {
        return ServerResponseEntity.success(userAddrService.removeById(addrId));
    }

}