package org.dromara.system.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.annotation.SaMode;
import com.baomidou.lock.annotation.Lock4j;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.constant.TenantConstants;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.common.web.core.BaseController;
import org.dromara.system.domain.SysTenant;
import org.dromara.system.domain.bo.SysTenantBo;
import org.dromara.system.domain.bo.SysTenantExtendBo;
import org.dromara.system.domain.bo.SysTenantReviewBo;
import org.dromara.system.domain.dto.TenantDTO;
import org.dromara.system.service.ISysTenantService;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.List;

/**
 * 租户管理
 *
 * @author Michelle.Chung
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/tenant")
@ConditionalOnProperty(value = "tenant.enable", havingValue = "true")
public class SysTenantController extends BaseController {

    private final ISysTenantService tenantService;


    @Tag(name ="查询租户列表")
//    @SaCheckRole(value = {
//        TenantConstants.SUPER_ADMIN_ROLE_KEY,
//        TenantConstants.TENANT_ADMIN_ROLE_KEY
//    }, mode = SaMode.OR)
    @SaCheckPermission("system:tenant:list")
    @PostMapping("/list")
    public R<IPage<TenantDTO>> list(@RequestBody SysTenantExtendBo query, Page<SysTenant> page){
        return R.ok(tenantService.getlist(page,query));
    }


    /**
     * 导出租户列表
     */
//    @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<TenantDTO> list = tenantService.getAll(bo);
        ExcelUtil.exportExcel(list, "租户", TenantDTO.class, response);
    }


    /**
     * 获取租户详细信息
     *
     * @param id 主键
     */
    @Tag(name ="获取租户表详细信息")
//    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
    @SaCheckPermission("system:tenant:query")
    @GetMapping(value = "/{id}")
    public R<TenantDTO> getInfo(@PathVariable("id") Long id) {
        return R.ok(tenantService.getById(id));
    }



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

    /**
     * 修改租户
     */
//    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
    @SaCheckPermission("system:tenant:edit")
    @Log(title = "修改租户", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PostMapping("/update")
    public R<Void> edit(@Validated(EditGroup.class) @RequestBody SysTenantExtendBo 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));
    }


    /**
     * 提交签约
     */
    @SaCheckPermission("system:tenant:submitSign")
    @Log(title = "提交签约", businessType = BusinessType.UPDATE)
    @PostMapping("/submitSign/{tenantId}")
    public R<Void> submitSign(@PathVariable String tenantId) {
        tenantService.checkTenantAllowed(tenantId);
        return toAjax(tenantService.submitSign(tenantId));
    }

    /**
     * 审核提交的签约
     */
    @SaCheckPermission("system:tenant:reviewSubmitted")
    @Log(title = "审核提交的签约", businessType = BusinessType.UPDATE)
    @PostMapping("/reviewSubmitted")
    public R<Void> reviewSubmitted(@RequestBody SysTenantReviewBo bo) {
        tenantService.checkTenantAllowed(bo.getTenantId());
        tenantService.reviewSubmitted(bo);
        return R.ok("审核成功");
    }

    /**
     * 确认审核通过的签约
     */
    @SaCheckPermission("system:tenant:confirmedSign")
    @Log(title = "租户管理", businessType = BusinessType.UPDATE)
    @PostMapping("/confirmedSign/{tenantId}")
    public R<Void> confirmedSign(@PathVariable String tenantId) {
        tenantService.checkTenantAllowed(tenantId);
        tenantService.confirmedSign(tenantId);
        return R.ok("确认成功");
    }




    /**
     * 删除租户
     *
     * @param
     */
    @Tag(name = "删除租户表")
    @Log(title = "租户表", businessType = BusinessType.DELETE)
    @SaCheckRole(value = {TenantConstants.SUPER_ADMIN_ROLE_KEY, TenantConstants.TENANT_ADMIN_ROLE_KEY})
    @SaCheckPermission("system:tenant:remove")
    @DeleteMapping("/remove")
    public R batchRemove(@RequestParam("ids") String ids) {
        List<Long> idList = Arrays.stream(ids.split(","))
            .map(Long::parseLong)
            .toList();
        return toAjax(tenantService.batchRemoveByIds(idList));
    }



    /**
     * 动态切换租户
     *
     * @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, true);
        return R.ok();
    }

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


    /**
     * 同步租户套餐
     *
     * @param tenantId  租户id
     * @param packageId 套餐id
     */
//    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
    @SaCheckPermission("system:tenant:edit")
    @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)));
    }

    /**
     * 同步租户字典
     */
//    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
    @Log(title = "租户管理", businessType = BusinessType.INSERT)
    @GetMapping("/syncTenantDict")
    public R<Void> syncTenantDict() {
        if (!TenantHelper.isEnable()) {
            return R.fail("当前未开启租户模式");
        }
        tenantService.syncTenantDict();
        return R.ok("同步租户字典成功");
    }

}
