package com.dsk.web.controller.system;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.annotation.SaMode;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.lock.annotation.Lock4j;
import com.dsk.common.annotation.Log;
import com.dsk.common.annotation.RepeatSubmit;
import com.dsk.common.constant.TenantConstants;
import com.dsk.common.core.controller.BaseController;
import com.dsk.common.core.domain.PageQuery;
import com.dsk.common.core.domain.R;
import com.dsk.common.core.page.TableDataInfo;
import com.dsk.common.core.validate.AddGroup;
import com.dsk.common.core.validate.EditGroup;
import com.dsk.common.enums.BusinessType;
import com.dsk.common.tenant.helper.TenantHelper;
import com.dsk.common.utils.StringUtils;
import com.dsk.system.domain.SysUser;
import com.dsk.system.domain.bo.SysTenantAdminBo;
import com.dsk.system.domain.bo.SysTenantBo;
import com.dsk.system.domain.vo.SysTenantVo;
import com.dsk.system.service.ISysTenantService;
import com.dsk.system.service.ISysUserService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Arrays;

/**
 * 租户管理
 *
 * @author sxk
 * @date 2023.08.22
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/tenant")
public class SysTenantController extends BaseController {
    private final ISysTenantService tenantService;
    private final ISysUserService userService;

    /**
     * 查询租户列表
     */
    @SaCheckRole(value = {TenantConstants.SUPER_ADMIN_ROLE_KEY, TenantConstants.DSK_TENANT_ADMIN_ROLE_KEY}, mode = SaMode.OR)
    @SaCheckPermission(value = "system:tenant:list", orRole = "accountAdmin")
    @GetMapping("/list")
    public TableDataInfo<SysTenantVo> list(SysTenantBo bo, PageQuery pageQuery) {
        return tenantService.queryPageList(bo, pageQuery);
    }

//    /**
//     * 导出租户列表
//     */
//    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
//    @SaCheckPermission("system:tenant:export")
//    @Log(title = "租户", businessType = BusinessType.EXPORT)
//    @PostMapping("/export")
//    public void export(SysTenantBo bo, HttpServletResponse response) {
//        List<SysTenantVo> list = tenantService.queryList(bo);
//        ExcelUtil.exportExcel(list, "租户", SysTenantVo.class, response);
//    }

    /**
     * 获取租户详细信息
     *
     * @param id 主键
     */
    @SaCheckRole(value = {TenantConstants.SUPER_ADMIN_ROLE_KEY, TenantConstants.DSK_TENANT_ADMIN_ROLE_KEY}, mode = SaMode.OR)
    @SaCheckPermission(value = "system:tenant:query", orRole = "accountAdmin")
    @GetMapping("/{id}")
    public R<SysTenantVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) {
        return R.ok(tenantService.queryById(id));
    }

    /**
     * 新增租户
     */
    @SaCheckRole(value = {TenantConstants.SUPER_ADMIN_ROLE_KEY, TenantConstants.DSK_TENANT_ADMIN_ROLE_KEY}, mode = SaMode.OR)
    @SaCheckPermission(value = "system:tenant:add", orRole = "accountAdmin")
    @Log(title = "租户", businessType = BusinessType.INSERT)
    @Lock4j
    @RepeatSubmit()
    @PostMapping()
    public R<Void> add(@Validated(AddGroup.class) @RequestBody SysTenantBo bo) {
        if (!tenantService.checkCompanyNameUnique(bo)) {
            return R.fail("新增企业'" + bo.getCompanyName() + "'失败，企业名称已存在");
        }
        return toAjax(TenantHelper.ignore(() -> tenantService.insertByBo(bo)));
    }

    /**
     * 新增企业普通管理员账号
     */
    @SaCheckRole(value = {TenantConstants.SUPER_ADMIN_ROLE_KEY, TenantConstants.DSK_TENANT_ADMIN_ROLE_KEY}, mode = SaMode.OR)
    @SaCheckPermission(value = "system:user:add")
    @Log(title = "用户管理", businessType = BusinessType.INSERT)
    @PostMapping("/addTenantAdmin")
    public R<Void> addTenantAdmin(@Validated @RequestBody SysTenantAdminBo tenantAdminBo) {
        //校验手机号是否已存在
        if (TenantHelper.ignore(()->userService.checkTenantAdminPhoneUnique(tenantAdminBo))) {
            return R.fail("新增用户'" + tenantAdminBo.getPhonenumber() + "'失败，手机号码已存在");
        }
        return toAjax(TenantHelper.ignore(() -> tenantService.addTenantAdmin(tenantAdminBo)));
        //return R.ok("手机号验证成功");
    }

    /**
     * 修改租户
     */
    @SaCheckRole(value = {TenantConstants.SUPER_ADMIN_ROLE_KEY, TenantConstants.DSK_TENANT_ADMIN_ROLE_KEY}, mode = SaMode.OR)
    @SaCheckPermission(value = "system:tenant:edit", orRole = "accountAdmin")
    @Log(title = "租户", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping()
    public R<Void> edit(@Validated(EditGroup.class) @RequestBody SysTenantBo bo) {
        tenantService.checkTenantAllowed(bo.getTenantId());
        if (!tenantService.checkCompanyNameUnique(bo)) {
            return R.fail("修改企业'" + bo.getCompanyName() + "'失败，公司名称已存在");
        }
        return toAjax(tenantService.updateByBo(bo));
    }

//    /**
//     * 状态修改
//     */
//    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
//    @SaCheckPermission("system:tenant:edit")
//    @Log(title = "租户", businessType = BusinessType.UPDATE)
//    @PutMapping("/changeStatus")
//    public R<Void> changeStatus(@RequestBody SysTenantBo bo) {
//        tenantService.checkTenantAllowed(bo.getTenantId());
//        return toAjax(tenantService.updateTenantStatus(bo));
//    }

    /**
     * 删除租户
     *
     * @param ids 主键串
     */
    @SaCheckRole(value = {TenantConstants.SUPER_ADMIN_ROLE_KEY, TenantConstants.DSK_TENANT_ADMIN_ROLE_KEY}, mode = SaMode.OR)
    @SaCheckPermission(value = "system:tenant:remove", orRole = "accountAdmin")
    @Log(title = "租户", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public R<Void> remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] ids) {
        return toAjax(tenantService.deleteWithValidByIds(Arrays.asList(ids), Boolean.TRUE));
    }

//    /**
//     * 动态切换租户
//     *
//     * @param tenantId 租户ID
//     */
//    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
//    @GetMapping("/dynamic/{tenantId}")
//    public R<Void> dynamicTenant(@NotBlank(message = "租户ID不能为空") @PathVariable String tenantId) {
//        TenantHelper.setDynamic(tenantId);
//        return R.ok();
//    }

    /**
     * 清除动态租户
     */
    @SaCheckRole(value = {TenantConstants.SUPER_ADMIN_ROLE_KEY, TenantConstants.DSK_TENANT_ADMIN_ROLE_KEY}, mode = SaMode.OR)
    @GetMapping("/dynamic/clear")
    public R<Void> dynamicClear() {
        TenantHelper.clearDynamic();
        return R.ok();
    }

    /**
     * 同步租户套餐
     *
     * @param tenantId  租户id
     * @param packageId 套餐id
     */
    @SaCheckRole(value = {TenantConstants.SUPER_ADMIN_ROLE_KEY, TenantConstants.DSK_TENANT_ADMIN_ROLE_KEY}, mode = SaMode.OR)
    @SaCheckPermission(value = "system:tenant:edit", orRole = "accountAdmin")
    @Log(title = "租户", businessType = BusinessType.UPDATE)
    @GetMapping("/syncTenantPackage")
    public R<Void> syncTenantPackage(@NotBlank(message = "企业ID不能为空") String tenantId,
                                     @NotNull(message = "企业方案ID不能为空") Long packageId) {
        return toAjax(TenantHelper.ignore(() -> tenantService.syncTenantPackage(tenantId, packageId)));
    }

}
