package com.cf.imes.module.system.controller.admin.organ;

import cn.hutool.core.collection.CollectionUtil;
import com.cf.imes.framework.common.enums.CommonStatusEnum;
import com.cf.imes.framework.common.pojo.CommonResult;
import com.cf.imes.framework.common.pojo.PageParam;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.common.util.object.BeanUtils;
import com.cf.imes.framework.excel.core.util.ExcelUtils;
import com.cf.imes.framework.operatelog.core.annotations.OperateLog;
import com.cf.imes.framework.security.core.util.SecurityFrameworkUtils;
import com.cf.imes.module.system.api.user.dto.OrganAdminUserRespDTO;
import com.cf.imes.module.system.controller.admin.organ.vo.organ.*;
import com.cf.imes.module.system.dal.dataobject.organ.OrganizationDO;
import com.cf.imes.module.system.dal.dataobject.organ.TenantPackageDO;
import com.cf.imes.module.system.dal.mysql.organ.TenantPackageMapper;
import com.cf.imes.module.system.service.organ.OrganService;
import com.cf.imes.module.system.service.user.AdminUserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

import static com.cf.imes.framework.common.pojo.CommonResult.success;
import static com.cf.imes.framework.common.util.collection.CollectionUtils.convertList;
import static com.cf.imes.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;

@Tag(name = "管理后台 - 组织")
@RestController
@RequestMapping("/system/organ")
public class OrganController {

    @Resource
    private OrganService organService;

    @Resource
    private TenantPackageMapper tenantPackageMapper;

    @Resource
    private AdminUserService adminUserService;

    @GetMapping("/get-id-by-name")
    @PermitAll
    @Operation(summary = "使用组织名，获得组织编号", description = "登录界面，根据用户的组织名，获得组织编号")
    @Parameter(name = "name", description = "组织名", required = true, example = "1024")
    public CommonResult<Long> getOrganIdByName(@RequestParam("name") String name) {
        OrganizationDO organizationDO = organService.getOrganByName(name);
        return success(organizationDO != null ? organizationDO.getId() : null);
    }

    @GetMapping("/get-by-website")
    @PermitAll
    @Operation(summary = "使用域名，获得组织信息", description = "登录界面，根据用户的域名，获得组织信息")
    @Parameter(name = "website", description = "域名", required = true, example = "www.cf.com")
    public CommonResult<OrganSimpleRespVO> getOrganByWebsite(@RequestParam("website") String website) {
        OrganizationDO organizationDO = organService.getOrganByWebsite(website);
        return success(BeanUtils.toBean(organizationDO, OrganSimpleRespVO.class));
    }

    @PostMapping("/create")
    @Operation(summary = "创建组织")
    @PreAuthorize("@ss.hasPermission('system:organ:create')")
    public CommonResult<Long> createOrgan(@Valid @RequestBody OrganSaveReqVO createReqVO) {
        return success(organService.createOrgan(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新组织")
    @PreAuthorize("@ss.hasPermission('system:organ:update')")
    public CommonResult<Boolean> updateOrgan(@Valid @RequestBody OrganSaveReqVO updateReqVO) {
        organService.updateOrgan(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除组织")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('system:organ:delete')")
    public CommonResult<Boolean> deleteOrgan(@RequestParam("id") Long id) {
        organService.deleteOrgan(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得组织")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('system:organ:query')")
    public CommonResult<OrganRespVO> getOrgan(@RequestParam("id") Long id) {
        OrganizationDO organ = organService.getOrgan(id);
        TenantPackageDO tenantPackageDO = tenantPackageMapper.selectById(organ.getPackageId());
        OrganRespVO bean = BeanUtils.toBean(organ, OrganRespVO.class);
        bean.setPackageName(Objects.isNull(tenantPackageDO)? "": tenantPackageDO.getName());
        return success(bean);
    }

    @GetMapping("/page")
    @Operation(summary = "获得组织分页")
    @PreAuthorize("@ss.hasPermission('system:organ:query')")
    public CommonResult<PageResult<OrganRespVO>> getOrganPage(@Valid OrganPageReqVO pageVO) {
        PageResult<OrganizationDO> pageResult = organService.getOrganPage(pageVO);
        if(CollectionUtil.isEmpty(pageResult.getList())) {
            return success(new PageResult<>());
        }
        PageResult<OrganRespVO> bean = BeanUtils.toBean(pageResult, OrganRespVO.class);
        Set<Long> packageIds = bean.getList().stream().map(OrganRespVO::getPackageId).collect(Collectors.toSet());
        List<TenantPackageDO> tenantPackageDOS = tenantPackageMapper.selectBatchIds(packageIds);
        bean.getList().forEach(e->{
            e.setPackageName(tenantPackageDOS.stream()
                    .filter(f->Objects.equals(f.getId(), e.getPackageId()))
                    .map(TenantPackageDO::getName)
                    .findAny()
                    .orElse("")
            );
        });
        return success(bean);
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出组织 Excel")
    @PreAuthorize("@ss.hasPermission('system:organ:export')")
    @OperateLog(type = EXPORT)
    public void exportOrganExcel(@Valid OrganPageReqVO exportReqVO,
                                  HttpServletResponse response) throws IOException {
        exportReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<OrganizationDO> list = organService.getOrganPage(exportReqVO).getList();
        if(CollectionUtil.isEmpty(list)) {
            ExcelUtils.write(response, "组织.xls", "数据", OrganExportRespVO.class, new ArrayList<>());
            return;
        }
        Set<Long> organIds = list.stream().map(OrganizationDO::getId).collect(Collectors.toSet());
        Set<Long> packageIds = list.stream().map(OrganizationDO::getPackageId).collect(Collectors.toSet());
        List<TenantPackageDO> tenantPackageDOS = tenantPackageMapper.selectBatchIds(packageIds);
        List<OrganExportRespVO> organExportRespVOS = BeanUtils.toBean(list, OrganExportRespVO.class);
        List<OrganAdminUserRespDTO> organAdminUserRespDTOS = adminUserService.getOrganAdminByOrganIds(organIds);

        organExportRespVOS.forEach(e->{
            e.setPackageName(tenantPackageDOS.stream()
                    .filter(f-> Objects.equals(e.getPackageId(),f.getId()))
                    .map(TenantPackageDO::getName)
                    .findAny()
                    .orElse(null));
            e.setLargeStr(e.getLarge()? "是":"否");
            e.setUsernames(organAdminUserRespDTOS.stream()
                    .filter(f->Objects.equals(e.getId(), f.getOrganId()))
                    .map(OrganAdminUserRespDTO::getUsername)
                    .reduce("", (a,b)-> a + " " + b)
            );
        });

        // 导出 Excel
        ExcelUtils.write(response, "组织.xls", "数据", OrganExportRespVO.class, organExportRespVOS);
    }


    @GetMapping({"/list-all-simple", "/simple-list"})
    @Operation(summary = "获取组织精简信息列表", description = "主要用于前端的下拉选项")
    @Parameter(name = "name", description = "组织名称", required = false, example = "xxx")
    public CommonResult<List<OrganSimpleRespVO>> getSimpleOrganList(@RequestParam(required = false, value = "name") String name) {
        return success(organService.getSimpleOrganList(name));
    }

}
