package com.yunzhupaas.portal.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import com.yunzhupaas.base.ActionResult;
import com.yunzhupaas.base.controller.SuperController;
import com.yunzhupaas.base.entity.ModuleEntity;
import com.yunzhupaas.base.entity.PortalManageEntity;
import com.yunzhupaas.base.entity.SystemEntity;
import com.yunzhupaas.base.model.VisualFunctionModel;
import com.yunzhupaas.base.model.base.SystemListVO;
import com.yunzhupaas.base.model.base.SystemPageVO;
import com.yunzhupaas.base.model.module.ModuleNameVO;
import com.yunzhupaas.base.service.ModuleService;
import com.yunzhupaas.base.service.PortalManageService;
import com.yunzhupaas.base.service.SystemService;
import com.yunzhupaas.base.vo.DownloadVO;
import com.yunzhupaas.base.vo.ListVO;
import com.yunzhupaas.base.vo.PageListVO;
import com.yunzhupaas.base.vo.PaginationVO;
import com.yunzhupaas.config.ConfigValueUtil;
import com.yunzhupaas.constant.MsgCode;
import com.yunzhupaas.emnus.ExportModelTypeEnum;
import com.yunzhupaas.emnus.ModuleTypeEnum;
import com.yunzhupaas.portal.constant.PortalConst;
import com.yunzhupaas.portal.entity.PortalEntity;
import com.yunzhupaas.portal.model.*;
import com.yunzhupaas.portal.service.PortalDataService;
import com.yunzhupaas.portal.service.PortalService;
import com.yunzhupaas.util.*;
import com.yunzhupaas.util.treeutil.SumTree;
import com.yunzhupaas.util.treeutil.newtreeutil.TreeDotUtils;
import com.yunzhupaas.util.treeutil.newtreeutil.TreeDotUtils2;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import jakarta.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 可视化门户
 *
 * @author 云筑产品开发平台组
 * @version V3.1.0
 * @copyright 深圳市乐程软件有限公司（http://www.szlecheng.cn）
 * @date 2023/09/27
 */
@Slf4j
@RestController
@Tag(name = "可视化门户" , description = "Portal" )
@RequestMapping("/api/visualdev/Portal" )
public class PortalController extends SuperController<PortalService, PortalEntity> {

    
    @Autowired
    private PortalService portalService;
    @Autowired
    private FileExport fileExport;
    @Autowired
    private ConfigValueUtil configValueUtil;
    @Autowired
    private PortalDataService portalDataService;

    @Operation(summary = "门户列表" )
    @GetMapping
    @SaCheckPermission("onlineDev.visualPortal" )
    public ActionResult list(PortalPagination portalPagination) {
        List<VisualFunctionModel> modelAll = portalService.getModelList(portalPagination);
        PaginationVO paginationVO = JsonUtil.getJsonToBean(portalPagination, PaginationVO.class);
        return ActionResult.page(modelAll, paginationVO);
    }

    @Operation(summary = "门户树形列表" )
    @Parameters({
            @Parameter(name = "type" , description = "类型：0-门户设计,1-配置路径" ),
    })
    @GetMapping("/Selector" )
    public ActionResult<ListVO<PortalSelectVO>> listSelect(String platform,String type) {
        List<PortalSelectModel> modelList = new ArrayList<>();
        if(StringUtil.isNotEmpty(type)){
            modelList.addAll(portalService.getModList(new PortalViewPrimary(platform, null)));
        }else {
            modelList.addAll(portalService.getModSelectList());
        }
        List<SumTree<PortalSelectModel>> sumTrees = TreeDotUtils2.convertListToTreeDot(modelList);
        List<PortalSelectVO> jsonToList = JsonUtil.getJsonToList(sumTrees, PortalSelectVO.class);
        return ActionResult.success(new ListVO<>(jsonToList));
    }

    @Operation(summary = "门户详情" )
    @Parameters({
            @Parameter(name = "id" , description = "主键" ),
    })
    @GetMapping("/{id}" )
    public ActionResult<PortalInfoVO> info(@PathVariable("id" ) String id, String platform) throws Exception {
        StpUtil.checkPermissionOr("onlineDev.visualPortal" , id);
        PortalEntity entity = portalService.getInfo(id);
        if (entity == null) {
            return ActionResult.fail(MsgCode.FA001.get());
        }
        PortalInfoVO vo = JsonUtil.getJsonToBean(JsonUtilEx.getObjectToStringDateFormat(entity, "yyyy-MM-dd HH:mm:ss" ), PortalInfoVO.class);
        vo.setFormData(portalDataService.getModelDataForm(new PortalModPrimary(id)));
        //获取发布信息
        VisualFunctionModel releaseInfo = portalService.getReleaseInfo(entity.getId());
        vo.setPcPortalIsRelease(releaseInfo.getPcPortalIsRelease());
        vo.setPcPortalReleaseName(releaseInfo.getPcPortalReleaseName());
        vo.setAppPortalIsRelease(releaseInfo.getAppPortalIsRelease());
        vo.setAppPortalReleaseName(releaseInfo.getAppPortalReleaseName());
        vo.setPcIsRelease(releaseInfo.getPcIsRelease());
        vo.setPcReleaseName(releaseInfo.getPcReleaseName());
        vo.setAppIsRelease(releaseInfo.getAppIsRelease());
        vo.setAppReleaseName(releaseInfo.getAppReleaseName());
        return ActionResult.success(vo);
    }

    @Operation(summary = "删除门户" )
    @Parameters({
            @Parameter(name = "id" , description = "主键" ),
    })
    @DeleteMapping("/{id}" )
    @SaCheckPermission("onlineDev.visualPortal" )
    @DSTransactional
    public ActionResult<String> delete(@PathVariable("id" ) String id) {
        PortalEntity entity = portalService.getInfo(id);
        if (entity != null) {
            try {
                portalService.delete(entity);
            } catch (Exception e) {
                return ActionResult.fail(e.getMessage());
            }
        }
        return ActionResult.success(MsgCode.SU003.get());
    }

    @Operation(summary = "创建门户" )
    @PostMapping()
    @SaCheckPermission("onlineDev.visualPortal" )
    @DSTransactional
    public ActionResult<String> create(@RequestBody @Valid PortalCrForm portalCrForm) throws Exception {
        PortalEntity entity = JsonUtil.getJsonToBean(portalCrForm, PortalEntity.class);
        entity.setId(RandomUtil.uuId());
        //判断名称是否重复
        if (portalService.isExistByFullName(entity.getFullName(), entity.getId())) {
            return ActionResult.fail(MsgCode.EXIST001.get());
        }
        //判断编码是否重复
        if (portalService.isExistByEnCode(entity.getEnCode(), entity.getId())) {
            return ActionResult.fail(MsgCode.EXIST002.get());
        }
        // 修改模板排版数据
        if(Objects.equals(entity.getType(),1)){
            entity.setEnabledLock(null);
        }
        // 修改模板排版数据
        portalService.create(entity);
        portalDataService.createOrUpdate(new PortalModPrimary(entity.getId()), portalCrForm.getFormData());
        return ActionResult.success(MsgCode.SU001.get(), entity.getId());
    }

    @Operation(summary = "复制功能" )
    @Parameters({
            @Parameter(name = "id" , description = "主键" ),
    })
    @PostMapping("/{id}/Actions/Copy" )
    @SaCheckPermission("onlineDev.visualPortal" )
    public ActionResult copyInfo(@PathVariable("id" ) String id) throws Exception {
        PortalEntity entity = portalService.getInfo(id);
        entity.setEnabledMark(0);
        String copyNum = UUID.randomUUID().toString().substring(0, 5);
        entity.setFullName(entity.getFullName() + ".副本" + copyNum);
        entity.setLastModifyTime(null);
        entity.setLastModifyUserId(null);
        entity.setId(RandomUtil.uuId());
        entity.setEnCode(entity.getEnCode() + copyNum);
        entity.setCreatorTime(new Date());
        entity.setCreatorUserId(UserProvider.getUser().getUserId());
        PortalEntity entity1 = JsonUtil.getJsonToBean(entity, PortalEntity.class);
        if (entity1.getEnCode().length() > 50 || entity1.getFullName().length() > 50) {
            return ActionResult.fail(MsgCode.PRI006.get());
        }
        portalService.create(entity1);
        portalDataService.createOrUpdate(new PortalModPrimary(entity1.getId()),
                portalDataService.getModelDataForm(new PortalModPrimary(id)));
        return ActionResult.success(MsgCode.SU007.get());
    }

    @Operation(summary = "修改门户" )
    @Parameters({
            @Parameter(name = "id" , description = "主键" ),
    })
    @PutMapping("/{id}" )
    @SaCheckPermission("onlineDev.visualPortal" )
    @DSTransactional
    public ActionResult<String> update(@PathVariable("id" ) String id, @RequestBody @Valid PortalUpForm portalUpForm) throws Exception {
        PortalEntity originEntity = portalService.getInfo(portalUpForm.getId());
        if(originEntity == null){
            ActionResult.fail(MsgCode.FA002.get());
        }
        //判断名称是否重复
        if (!originEntity.getFullName().equals(portalUpForm.getFullName()) && StringUtil.isNotEmpty(portalUpForm.getFullName())) {
            if (portalService.isExistByFullName(portalUpForm.getFullName(), portalUpForm.getId())) {
                return ActionResult.fail(MsgCode.EXIST001.get());
            }
        }
        //判断编码是否重复
        if (!originEntity.getEnCode().equals(portalUpForm.getEnCode()) && StringUtil.isNotEmpty(portalUpForm.getEnCode())) {
            if (portalService.isExistByEnCode(portalUpForm.getEnCode(), portalUpForm.getId())) {
                return ActionResult.fail(MsgCode.EXIST002.get());
            }
        }
        // 修改排版数据
        if(Objects.equals(portalUpForm.getType(),1)){
            portalUpForm.setEnabledLock(null);
        }
        //修改状态
        if(Objects.equals(originEntity.getState(),1)){
            originEntity.setState(2);
            portalUpForm.setState(2);
        }
        // 修改排版数据
        portalDataService.createOrUpdate(new PortalModPrimary(portalUpForm.getId()), portalUpForm.getFormData());
        if (StringUtil.isNotEmpty(portalUpForm.getFullName()) && StringUtil.isNotEmpty(portalUpForm.getEnCode())) {
            portalService.update(id, JsonUtil.getJsonToBean(portalUpForm, PortalEntity.class));
        }else {
            portalService.update(id, originEntity);
        }
        return ActionResult.success(MsgCode.SU004.get());
    }

    @Operation(summary = "门户导出" )
    @Parameters({
            @Parameter(name = "modelId" , description = "模板id" ),
    })
    @PostMapping("/{modelId}/Actions/Export" )
    @SaCheckPermission("onlineDev.visualPortal" )
    public ActionResult exportFunction(@PathVariable("modelId" ) String modelId) throws Exception {
        PortalEntity entity = portalService.getInfo(modelId);
        if (entity != null) {
            PortalExportDataVo vo = new PortalExportDataVo();
            BeanUtils.copyProperties(entity, vo);
            vo.setId(entity.getId());
            vo.setModelType(ExportModelTypeEnum.Portal.getMessage());
            vo.setFormData(portalDataService.getModelDataForm(new PortalModPrimary(entity.getId())));
            DownloadVO downloadVO = fileExport.exportFile(vo, configValueUtil.getTemporaryFilePath(), entity.getFullName(), ModuleTypeEnum.VISUAL_PORTAL.getTableName());
            return ActionResult.success(downloadVO);
        } else {
            return ActionResult.success(MsgCode.FA001.get());
        }
    }

    @SneakyThrows
    @Operation(summary = "门户导入" )
    @Parameters({
            @Parameter(name = "file" , description = "导入文件" ),
    })
    @PostMapping(value = "/Actions/Import" , consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    @SaCheckPermission("onlineDev.visualPortal" )
    public ActionResult importFunction(@RequestPart("file" ) MultipartFile multipartFile,@RequestParam("type") Integer type) throws Exception {
        //判断是否为.json结尾
        if (FileUtil.existsSuffix(multipartFile, ModuleTypeEnum.VISUAL_PORTAL.getTableName())) {
            return ActionResult.fail(MsgCode.IMP002.get());
        }
        //获取文件内容
        String fileContent = FileUtil.getFileContent(multipartFile);
        PortalExportDataVo vo = JsonUtil.getJsonToBean(fileContent, PortalExportDataVo.class);
        if (vo.getModelType() == null || !vo.getModelType().equals(ExportModelTypeEnum.Portal.getMessage())) {
            return ActionResult.fail(MsgCode.VS410.get());
        }

        PortalEntity entity = JsonUtil.getJsonToBean(fileContent, PortalEntity.class);
        StringJoiner errList = new StringJoiner("、");
        String copyNum = UUID.randomUUID().toString().substring(0, 5);
        if (portalService.getInfo(entity.getId()) != null) {
            if (Objects.equals(type, 0)) {
                errList.add("ID");
            }else{
                entity.setId(null);
            }
        }
        //判断编码是否重复
        if (portalService.isExistByEnCode(entity.getEnCode(), null)) {
            if (Objects.equals(type, 0)) {
                errList.add(MsgCode.IMP009.get());
            } else {
                entity.setEnCode(entity.getEnCode() + copyNum);
            }
        }
        //判断名称是否重复
        if (portalService.isExistByFullName(entity.getFullName(), null)) {
            if (Objects.equals(type, 0)) {
                errList.add(MsgCode.IMP008.get());
            } else {
                entity.setFullName(entity.getFullName() + ".副本" + copyNum);
            }
        }

        if (Objects.equals(type, 0) && errList.length() > 0) {
            return ActionResult.fail(errList + MsgCode.IMP007.get());
        }

        portalService.setIgnoreLogicDelete().removeById(entity.getId());
        portalService.clearIgnoreLogicDelete();
        entity.setEnabledMark(0);
        entity.setSortCode(0l);
        entity.setCreatorTime(new Date());
        entity.setCreatorUserId(UserProvider.getUser().getUserId());
        entity.setLastModifyTime(null);
        entity.setLastModifyUserId(null);
        portalService.create(entity);
        portalDataService.createOrUpdate(new PortalModPrimary(entity.getId()), vo.getFormData());
        return ActionResult.success(MsgCode.IMP001.get());
    }

    @Operation(summary = "门户管理下拉列表" )
    @GetMapping("/manage/Selector/{systemId}" )
    public ActionResult<PageListVO<PortalSelectVO>> getManageSelectorList(@PathVariable String systemId, PortalPagination portalPagination) {
        portalPagination.setType(null); // 门户设计、配置路径。全选
        List<PortalSelectVO> voList = portalService.getManageSelectorPage(portalPagination, systemId);
        PaginationVO paginationVO = JsonUtil.getJsonToBean(portalPagination, PaginationVO.class);
        return ActionResult.page(voList, paginationVO);
    }

    @Operation(summary = "门户获取系统下拉" )
    @GetMapping("/systemFilter/{id}" )
    public ActionResult<ListVO<SystemListVO>> systemFilterList(@PathVariable("id") String id,String category) {
        List<SystemListVO> systemListVOS = portalService.systemFilterList(id, category);
        return ActionResult.success(new ListVO<>(systemListVOS));
    }
}

