package com.taais.system.controller.system;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaCheckRole;
import com.baomidou.lock.annotation.Lock4j;
import com.taais.common.core.constant.TenantConstants;
import com.taais.common.core.core.domain.CommonResult;
import com.taais.common.core.core.page.PageResult;
import com.taais.common.encrypt.annotation.ApiEncrypt;
import com.taais.common.excel.utils.ExcelUtil;
import com.taais.common.log.annotation.Log;
import com.taais.common.log.enums.BusinessType;
import com.taais.common.tenant.helper.TenantHelper;
import com.taais.common.web.annotation.RepeatSubmit;
import com.taais.common.web.core.BaseController;
import com.taais.system.domain.bo.SysTenantBo;
import com.taais.system.domain.vo.SysTenantVo;
import com.taais.system.service.ISysTenantService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * 租户管理
 *
 * @author wgk
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/tenant")
public class SysTenantController extends BaseController {

    @Resource
    private ISysTenantService tenantService;

    /**
     * 分页查询租户列表
     */
    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
    @SaCheckPermission("system:tenant:list")
    @GetMapping("/list")
    public CommonResult<PageResult<SysTenantVo>> list(SysTenantBo sysTenantBo) {
        return CommonResult.success(tenantService.selectPage(sysTenantBo));
    }

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

    /**
     * 获取租户详细信息
     *
     * @param tenantId 主键
     */
    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
    @SaCheckPermission("system:tenant:query")
    @GetMapping("/{tenantId}")
    public CommonResult<SysTenantVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long tenantId) {
        return CommonResult.success(tenantService.selectById(tenantId));
    }

    /**
     * 新增租户
     */
    @ApiEncrypt
    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
    @SaCheckPermission("system:tenant:add")
    @Log(title = "租户", businessType = BusinessType.INSERT)
    @Lock4j
    @RepeatSubmit()
    @PostMapping()
    public CommonResult<Void> add(@Validated @RequestBody SysTenantBo sysTenantBo) {
        if (!tenantService.checkCompanyNameUnique(sysTenantBo)) {
            return CommonResult.fail("新增租户'" + sysTenantBo.getCompanyName() + "'失败，企业名称已存在");
        }
        boolean inserted = tenantService.insert(sysTenantBo);
        if (!inserted) {
            return CommonResult.fail("新增租户记录失败！");
        }
        return CommonResult.success();
    }

    /**
     * 修改租户
     */
    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
    @SaCheckPermission("system:tenant:edit")
    @Log(title = "租户", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping()
    public CommonResult<Void> edit(@Validated @RequestBody SysTenantBo sysTenantBo) {
        tenantService.checkTenantAllowed(sysTenantBo.getTenantId());
        boolean updated = tenantService.update(sysTenantBo);
        if (!updated) {
            return CommonResult.fail("修改租户记录失败!");
        }
        return CommonResult.success();
    }

    /**
     * 状态修改
     */
    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
    @SaCheckPermission("system:tenant:edit")
    @Log(title = "租户", businessType = BusinessType.UPDATE)
    @PutMapping("/changeStatus")
    public CommonResult<Void> changeStatus(@RequestBody SysTenantBo sysTenantBo) {
        tenantService.checkTenantAllowed(sysTenantBo.getTenantId());
        boolean updated = tenantService.updateTenantStatus(sysTenantBo);
        if (!updated) {
            return CommonResult.fail("修改租户状态失败!");
        }
        return CommonResult.success();
    }

    /**
     * 删除租户
     *
     * @param tenantIds 主键串
     */
    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
    @SaCheckPermission("system:tenant:remove")
    @Log(title = "租户", businessType = BusinessType.DELETE)
    @DeleteMapping("/{tenantIds}")
    public CommonResult<Void> remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] tenantIds) {
        boolean deleted = tenantService.deleteByIds(List.of(tenantIds), true);
        if (!deleted) {
            return CommonResult.fail("删除租户记录失败!");
        }
        return CommonResult.success();
    }

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

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


    /**
     * 同步租户套餐
     *
     * @param tenantId  租户id
     * @param packageId 套餐id
     */
    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
    @SaCheckPermission("system:tenant:edit")
    @Log(title = "租户", businessType = BusinessType.UPDATE)
    @GetMapping("/syncTenantPackage")
    public CommonResult<Void> syncTenantPackage(@NotNull(message = "租户ID不能为空") Long tenantId,
                                                @NotNull(message = "套餐ID不能为空") Long packageId) {
        boolean synced = tenantService.syncTenantPackage(tenantId, packageId);
        if (!synced) {
            return CommonResult.fail("同步租户套餐失败!");
        }
        return CommonResult.success();
    }

}
