package com.microservices.cms.doc.controller;

import com.alibaba.fastjson2.JSONObject;
import com.microservices.cms.doc.domain.*;
import com.microservices.cms.doc.service.ICmsDocService;
import com.microservices.common.core.domain.R;
import com.microservices.common.core.web.controller.BaseController;
import com.microservices.common.core.web.domain.AjaxResult;
import com.microservices.common.core.web.page.GenericsTableDataInfo;
import com.microservices.common.core.web.page.TableDataInfo;
import com.microservices.common.log.annotation.Log;
import com.microservices.common.log.enums.BusinessType;
import com.microservices.common.security.annotation.InnerAuth;
import com.microservices.common.security.annotation.RequiresPermissions;
import com.microservices.common.security.utils.SecurityUtils;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 文章信息Controller
 *
 * @author otto
 * @date 2023-03-28
 */
@Api(tags = "栏目及文章相关接口")
@RestController
@RequestMapping("/doc")
public class CmsDocController extends BaseController {
    @Autowired
    private ICmsDocService cmsDocService;

    /**
     * 查询栏目列表
     */
    @RequiresPermissions("cms:doc:dirList")
    @GetMapping("/zone/{zoneId}/dirList")
    @ApiOperation("查询栏目列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNum", value = "当前记录起始索引", paramType = "query", dataType = "Integer"),
            @ApiImplicitParam(name = "pageSize", value = "每页显示记录数", paramType = "query", dataType = "Integer"),
            @ApiImplicitParam(name = "orderByColumn", value = "排序列", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "isAsc", value = "排序的方向desc或者asc,默认asc", paramType = "query", dataType = "String")
    })
    public GenericsTableDataInfo<CmsDir> dirList(@ApiParam(name = "zoneId", value = "专区Id") @PathVariable("zoneId") Long zoneId) {
        Long deptId = cmsDocService.getDeptIdByZoneId(zoneId);
        List<CmsDir> list = cmsDocService.selectCmsDocDirList(deptId, false);
        return getAllGenericsDataTableToPage(list);
    }

    /**
     * 查询栏目下文章列表
     */
    @RequiresPermissions("cms:doc:list")
    @GetMapping("/dir/{dirId}/docList")
    @ApiOperation("查询栏目下文章列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNum", value = "当前记录起始索引", paramType = "query", dataType = "Integer"),
            @ApiImplicitParam(name = "pageSize", value = "每页显示记录数", paramType = "query", dataType = "Integer"),
            @ApiImplicitParam(name = "orderByColumn", value = "排序列", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "isAsc", value = "排序的方向desc或者asc,默认asc", paramType = "query", dataType = "String")
    })
    public GenericsTableDataInfo<CmsDocBaseDto> docList(
            @ApiParam(name = "dirId", value = "栏目Id") @PathVariable("dirId") Long dirId
            , CmsDocSearchVo cmsDocSearchVo) {
        cmsDocSearchVo.setIsOpen(false);
        List<CmsDocBaseDto> list = cmsDocService.selectCmsDocList(dirId, cmsDocSearchVo);

        list.forEach(x -> {
            String docDetailUrl = cmsDocService.getDocDetailUrl(x.getDeptId(), x.getId());
            x.setDocDetailUrl(docDetailUrl);

            Boolean editable = cmsDocService.isCmsDocEditable(x);
            x.setEditable(editable);

        });
        return getAllGenericsDataTableToPage(list);
    }

    /**
     * 获取专区下文章首页推荐数量
     */
    @RequiresPermissions("cms:doc:list")
    @GetMapping("/zone/{zoneId}/homepageCount")
    @ApiOperation("获取专区下文章首页推荐数量")
    public AjaxResult homepageCount(@ApiParam(name = "zoneId", value = "专区Id") @PathVariable Long zoneId
            , @ApiParam(name = "dirId", value = "栏目Id") Long dirId) {
        Long deptId = cmsDocService.getDeptIdByZoneId(zoneId);
        String dirName = null;
        if (dirId != null) {
            CmsDir cmsDir = cmsDocService.selectCmsDirById(dirId, true);
            dirName = cmsDir.getName();
        }
        return success(cmsDocService.selectHomepageCountByDeptIdAndDirName(deptId, dirName));
    }

    /**
     * 查询专区下所有文章列表
     */
    @RequiresPermissions("cms:doc:list")
    @GetMapping("/zone/{zoneId}/docList")
    @ApiOperation("查询专区下所有文章列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNum", value = "当前记录起始索引", paramType = "query", dataType = "Integer"),
            @ApiImplicitParam(name = "pageSize", value = "每页显示记录数", paramType = "query", dataType = "Integer"),
    })
    public TableDataInfo docListByZone(
            @ApiParam(name = "zoneId", value = "专区Id") @PathVariable("zoneId") Long zoneId
            , CmsDocSearchVo cmsDocSearchVo) {
        Long deptId = cmsDocService.getDeptIdByZoneId(zoneId);
        cmsDocSearchVo.setIsOpen(false);
        startPage();
        List<CmsDocAllDto> list = cmsDocService.selectCmsDocListByDept(deptId, cmsDocSearchVo);
        list.forEach(x -> {
            String docDetailUrl = cmsDocService.getDocDetailUrl(x.getDeptId(), x.getId());
            x.setDocDetailUrl(docDetailUrl);

            Boolean editable = cmsDocService.isCmsDocEditable(x);
            x.setEditable(editable);

        });
        int count = cmsDocService.selectCmsDocCountByDept(deptId, cmsDocSearchVo);
        return getDataTable(list, count);
    }

    /**
     * 查询专区下我的文章列表
     */
    @RequiresPermissions("cms:doc:myDocList")
    @GetMapping("/zone/{zoneId}/myDocList")
    @ApiOperation("查询专区下我的文章列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNum", value = "当前记录起始索引", paramType = "query", dataType = "Integer"),
            @ApiImplicitParam(name = "pageSize", value = "每页显示记录数", paramType = "query", dataType = "Integer"),
    })
    public TableDataInfo myDocListByZone(
            @ApiParam(name = "zoneId", value = "专区Id") @PathVariable("zoneId") Long zoneId
            , CmsDocSearchVo cmsDocSearchVo) {
        Long deptId = cmsDocService.getDeptIdByZoneId(zoneId);
        cmsDocSearchVo.setIsOpen(false);
        cmsDocSearchVo.setCreateBy(SecurityUtils.getUsername());
        startPage();
        List<CmsDocAllDto> list = cmsDocService.selectCmsDocListByDept(deptId, cmsDocSearchVo);
        list.forEach(x -> {
            String docDetailUrl = cmsDocService.getDocDetailUrl(x.getDeptId(), x.getId());
            x.setDocDetailUrl(docDetailUrl);
        });
        int count = cmsDocService.selectCmsDocCountByDept(deptId, cmsDocSearchVo);
        return getDataTable(list, count);
    }

    /**
     * 获取文章信息详细信息
     */
    @RequiresPermissions("cms:doc:query")
    @ApiOperation("获取文章详细信息")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@ApiParam(name = "id", value = "文章Id") @PathVariable("id") Long id) {
        return success(cmsDocService.selectCmsDocById(id, false, null));
    }

    /**
     * 新增文章信息
     */
    @RequiresPermissions("cms:doc:add")
    @Log(title = "文章信息", businessType = BusinessType.INSERT)
    @PostMapping("/dir/{dirId}")
    @ApiOperation("在栏目下创建文章")
    public AjaxResult addDocByDir(@ApiParam(name = "dirId", value = "栏目Id") @PathVariable("dirId") Long dirId,
                                  @ApiParam(name = "cmsDocDto", value = "文章实体对象") @RequestBody CmsDocInputDto cmsDocInputDto) {
        return success(cmsDocService.insertCmsDoc(dirId, cmsDocInputDto));
    }

    /**
     * 手动进行全量同步
     */
    @RequiresPermissions("cms:doc:syncAll")
    @Log(title = "手动进行全量同步", businessType = BusinessType.UPDATE)
    @PostMapping("/syncAll")
    @ApiOperation("手动进行全量同步")
    public AjaxResult syncAll() {
        cmsDocService.syncAll();
        return AjaxResult.success("同步消息发送成功");
    }

    /**
     * 新增文章栏目
     */
    @RequiresPermissions("cms:doc:addDir")
    @Log(title = "文章栏目信息", businessType = BusinessType.INSERT)
    @PostMapping("/zone/{zoneId}/dir")
    @ApiOperation("在专区项目中创建栏目")
    public AjaxResult addDir(@ApiParam(name = "zoneId", value = "专区Id") @PathVariable("zoneId") Long zoneId,
                             @ApiParam(name = "cmsDoc", value = "文章实体对象") @RequestBody CmsDir cmsDir) {
        Long deptId = cmsDocService.getDeptIdByZoneId(zoneId);
        return toAjax(cmsDocService.insertCmsDocDir(deptId, cmsDir));
    }

    /**
     * 删除文章
     */
    @RequiresPermissions("cms:doc:remove")
    @Log(title = "文章信息", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    @ApiOperation("删除文章/栏目")
    public AjaxResult remove(@ApiParam(name = "ids", value = "文章/栏目Ids") @PathVariable Long[] ids) {
        return toAjax(cmsDocService.deleteCmsDocByIds(ids));
    }

    /**
     * 修改文章信息
     */
    @RequiresPermissions("cms:doc:edit")
    @Log(title = "文章信息", businessType = BusinessType.UPDATE)
    @PutMapping("/{id}")
    @ApiOperation("更新文章")
    public AjaxResult edit(@ApiParam(name = "id", value = "文章Id") @PathVariable Long id,
                           @ApiParam(name = "cmsDoc", value = "文章实体对象") @RequestBody CmsDocDto cmsDocDto) {
        return toAjax(cmsDocService.updateCmsDoc(id, cmsDocDto));
    }

    /**
     * 修改栏目信息
     */
    @RequiresPermissions("cms:dir:edit")
    @Log(title = "栏目信息", businessType = BusinessType.UPDATE)
    @PutMapping("/cmsDir/{id}")
    @ApiOperation("更新栏目")
    public AjaxResult editCmsDIr(@ApiParam(name = "id", value = "栏目Id") @PathVariable Long id,
                                 @ApiParam(name = "cmsDirUpdateVo", value = "栏目更新对象") @RequestBody CmsDirUpdateVo cmsDirUpdateVo) {
        cmsDocService.updateCmsDir(id, cmsDirUpdateVo);
        return success("异步更新栏目信息");
    }

    /**
     * 审核文章信息
     */
    @RequiresPermissions("cms:doc:audit")
    @Log(title = "文章信息", businessType = BusinessType.UPDATE)
    @PutMapping("/{id}/audit")
    @ApiOperation("审核文章")
    public AjaxResult audit(@ApiParam(name = "id", value = "文章Id") @PathVariable Long id,
                           @ApiParam(name = "cmsDocAuditVo", value = "文章审核对象") @RequestBody CmsDocAuditVo cmsDocAuditVo) {
        return toAjax(cmsDocService.auditCmsDoc(id, cmsDocAuditVo));
    }

    /**
     * 设置是否首页展示
     */
    @RequiresPermissions("cms:doc:edit")
    @Log(title = "文章信息", businessType = BusinessType.UPDATE)
    @PutMapping("/{id}/homepage")
    @ApiOperation("设置是否首页展示")
    public AjaxResult updateCmsDocHomePageShow(@ApiParam(name = "id", value = "文章Id") @PathVariable Long id) {
        return toAjax(cmsDocService.updateCmsDocHomePageShow(id));
    }


    /**
     * 内部接口，通过组织Id获取专区下文章数量
     */
    @InnerAuth
    @GetMapping("/getCmsCountByDeptId/{deptId}")
    @ApiOperation(value = "通过组织Id获取专区下文章数量", hidden = true)
    public R<Long> getCmsCountByDeptId(@PathVariable(value = "deptId") Long deptId) {
        Long cmsSize = cmsDocService.getCmsCountByDeptId(deptId);
        return R.ok(cmsSize);
    }

    /**
     * 内部接口，通过组织Id获取专区下待审核文章数量
     */
    @InnerAuth
    @GetMapping("/getNotAuditCmsCountByDeptId/{deptId}")
    @ApiOperation(value = "通过组织Id获取专区下待审核文章数量", hidden = true)
    public R<Long> getNotAuditCmsCountByDeptId(@PathVariable(value = "deptId") Long deptId) {
        Long cmsSize = cmsDocService.getNotAuditCmsCountByDeptId(deptId);
        return R.ok(cmsSize);
    }

    /**
     * 内部接口，初始化栏目
     */
    @PostMapping("/initCmsDir/{zoneId}")
    @Log(title = "初始化栏目", businessType = BusinessType.INSERT)
    @ApiOperation(value = "初始化栏目", hidden = true)
    public R<CmsDir> initCmsDir(@PathVariable(value = "zoneId") Long zoneId
            , @RequestBody CmsDir cmsDirInput) {
        Long deptId = cmsDocService.getDeptIdByZoneId(zoneId);
        CmsDir cmsDir = cmsDocService.initCmsDir(deptId, cmsDirInput);
        return R.ok(cmsDir);
    }

    /**
     * 内部接口，初始化新闻
     */
    @InnerAuth
    @PostMapping("/initCmsDoc/{dirId}")
    @Log(title = "初始化新闻", businessType = BusinessType.INSERT)
    @ApiOperation(value = "初始化新闻", hidden = true)
    public R<Boolean> initCmsDoc(@PathVariable(value = "dirId") Long dirId
            , @RequestBody CmsDocInputDto cmsDocInputDto) {
        return R.ok(cmsDocService.initCmsDoc(dirId, cmsDocInputDto));
    }

    @InnerAuth
    @GetMapping("/getJSONObject/{cmsDocId}")
    R<JSONObject> selectCmsDocJSONObjectById(@PathVariable(value = "cmsDocId") Long cmsDocId) {
        CmsDoc cmsDoc = cmsDocService.selectBaseCmsDocById(cmsDocId);
        JSONObject cmsDocJSONObject = JSONObject.from(cmsDoc);
        String docDetailUrl = cmsDocService.getDocDetailUrl(cmsDoc.getDeptId(), cmsDoc.getId());
        cmsDocJSONObject.put("docDetailUrl", docDetailUrl);
        return R.ok(cmsDocJSONObject);
    }

    /**
     * 通过组织Id获取专区下文章阅读数量
     *
     * @param deptId 组织id
     * @return 结果
     */
    @GetMapping("/getCmsDocVisitsByDeptId/{deptId}")
    public R<Long> getCmsDocVisitsByDeptId(@PathVariable(value = "deptId") Long deptId) {
        return R.ok(cmsDocService.getCmsDocVisitsByDeptId(deptId));
    }
}
