package com.microservices.zone.common.controller;

import com.alibaba.fastjson2.JSONObject;
import com.microservices.common.core.web.controller.BaseController;
import com.microservices.common.core.web.domain.AjaxResult;
import com.microservices.common.core.web.domain.GenericsAjaxResult;
import com.microservices.common.core.web.page.GenericsTableDataInfo;
import com.microservices.common.log.annotation.Log;
import com.microservices.common.log.enums.BusinessType;
import com.microservices.common.security.annotation.RequiresPermissions;
import com.microservices.common.security.utils.SecurityUtils;
import com.microservices.zone.detail.domain.vo.ZoneFrontRoleVo;
import com.microservices.zone.detail.service.IZoneDetailService;
import com.microservices.zone.project.domain.vo.*;
import com.microservices.zone.project.service.IZoneProjectService;
import com.microservices.zone.project.service.IZoneProjectTypeService;
import com.microservices.zone.resource.domain.ZoneResource;
import com.microservices.zone.resource.domain.vo.*;
import com.microservices.zone.resource.service.IAiResourceParseService;
import com.microservices.zone.resource.service.IZoneResourceService;
import io.swagger.annotations.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

/**
 * @author otto
 */
@RestController
@RequestMapping("/zoneFront")
@Api(tags = "特色专区前台接口")
public class FrontController extends BaseController {

    @Autowired
    private IZoneResourceService zoneResourceService;

    @Autowired
    private IAiResourceParseService aiResourceParseService;

    @Autowired
    private IZoneProjectService zoneProjectService;

    @Autowired
    private IZoneDetailService zoneDetailService;

    /**
     * 查询我的资源列表
     */
    @RequiresPermissions("zone:front:resource:myList")
    @GetMapping("/myResourceList")
    @ApiOperation(value = "查询我的资源列表")
    public GenericsTableDataInfo<ZoneResourceDataVo> myResourceList(ZoneResourceSearchVo zoneResourceSearchVo) {
        ZoneResource zoneResourceSearch = zoneResourceSearchVo.toZoneResource();
        zoneResourceSearch.setCreateBy(SecurityUtils.getUsername());
        startPage();
        return zoneResourceService.selectMyZoneResourceList(zoneResourceSearch);
    }

    /**
     * 查询我的资源详情
     */
    @RequiresPermissions("zone:front:resource:query")
    @GetMapping("/myResource/{id}")
    @ApiOperation(value = "查询我的资源详情")
    public GenericsAjaxResult<ZoneResourceDataVo> myResource(@PathVariable("id") Long id) {
        return genericsSuccess(zoneResourceService.selectZoneResourceDataById(id));
    }

    /**
     * 新增资源
     */
    @RequiresPermissions("zone:front:resource:add")
    @Log(title = "专区前台资源操作", businessType = BusinessType.INSERT)
    @PostMapping("/addResource")
    @ApiOperation(value = "新增资源")
    public AjaxResult addResource(@RequestBody ZoneResourceInputVo zoneResourceInputVo) {
        return success(zoneResourceService.insertZoneResource(zoneResourceInputVo));
    }

    /**
     * 编辑资源
     */
    @RequiresPermissions("zone:front:resource:edit")
    @Log(title = "专区前台资源操作", businessType = BusinessType.UPDATE)
    @PutMapping("/editResource")
    @ApiOperation(value = "编辑资源")
    public AjaxResult editResource(@RequestBody ZoneResourceUpdateVo zoneResourceUpdateVo) {
        return success(zoneResourceService.updateZoneResource(zoneResourceUpdateVo));
    }

    /**
     * 删除资源
     */
    @RequiresPermissions("zone:front:resource:remove")
    @Log(title = "专区前台资源操作", businessType = BusinessType.DELETE)
    @DeleteMapping("/removeResource/{ids}")
    @ApiOperation(value = "删除资源")
    public AjaxResult removeResource(@PathVariable Long[] ids) {
        return toAjax(zoneResourceService.deleteMyZoneResourceByIds(ids));
    }


    /**
     * 查询GitLink项目列表
     */
    @GetMapping("/zone/{zoneId}/myGitlinkProjectList")
    @ApiOperation("查询专区下我的GitLink项目列表")
    public GenericsTableDataInfo<JSONObject> selectMyGitlinkProjectListByZone(
            @ApiParam(name = "zoneId", value = "专区Id") @PathVariable Long zoneId
            , MyGitLinkProjectSearchVo myGitLinkProjectSearchVo) {
        return zoneProjectService.selectMyGitlinkProjectListByZone(zoneId, myGitLinkProjectSearchVo);
    }

    /**
     * 查询我的项目列表
     */
    @RequiresPermissions("zone:front:project:myList")
    @GetMapping("/myProjectList")
    @ApiOperation(value = "查询我的项目聚合列表")
    public GenericsTableDataInfo<ZoneProjectDataVo> myProjectList(ZoneProjectSearchVo zoneProjectSearchVo) {
        zoneProjectSearchVo.setCreateBy(SecurityUtils.getUsername());
        return zoneProjectService.selectMyZoneProjectList(zoneProjectSearchVo);
    }

    /**
     * 查询我的项目详情
     */
    @RequiresPermissions("zone:front:project:query")
    @GetMapping("/myProject/{id}")
    @ApiOperation(value = "查询我的项目聚合详情")
    public GenericsAjaxResult<ZoneProjectDataVo> myProject(@PathVariable("id") Long id) {
        return genericsSuccess(zoneProjectService.selectZoneProjectDataById(id));
    }

    /**
     * 新增项目
     */
    @RequiresPermissions("zone:front:project:add")
    @Log(title = "专区前台项目操作", businessType = BusinessType.INSERT)
    @PostMapping("/addProject")
    @ApiOperation(value = "新增项目聚合")
    public AjaxResult addProject(@RequestBody @Validated List<ZoneProjectInputVo> zoneProjectInputVoList) {
        return success(zoneProjectService.insertBatchZoneProject(zoneProjectInputVoList));
    }

    /**
     * 编辑项目
     */
    @RequiresPermissions("zone:front:project:edit")
    @Log(title = "专区前台项目操作", businessType = BusinessType.UPDATE)
    @PutMapping("/editProject/{projectId}")
    @ApiOperation(value = "编辑项目聚合")
    public AjaxResult editProject(@PathVariable("projectId") Long projectId, @RequestBody ZoneProjectFrontUpdateVo zoneProjectFrontUpdateVo) {
        return success(zoneProjectService.updateMyZoneProject(projectId, zoneProjectFrontUpdateVo.toZoneProjectUpdateVo()));
    }

    /**
     * 删除项目
     */
    @RequiresPermissions("zone:front:project:remove")
    @Log(title = "专区前台项目操作", businessType = BusinessType.DELETE)
    @DeleteMapping("/removeProject/{ids}")
    @ApiOperation(value = "删除项目聚合")
    public AjaxResult removeProject(@PathVariable Long[] ids) {
        return toAjax(zoneProjectService.deleteMyZoneProjectByIds(ids));
    }

    /**
     * 检查当前登录用户在当前专区下角色
     */
    @GetMapping("/{zoneId}/checkCurrentRole")
    @ApiOperation(value = "检查当前登录用户在当前专区下权限",
            notes = "1、当权限为Manager时，后台返回资源管理访问地址和资讯管理访问地址，前台可提供（资源管理/资讯管理）按钮跳转到对应的后台地址\n" +
                    "2、当权限为Member时，用户可在前台操作资源和资讯\n" +
                    "3、当权限为None时，不展示前台操作按钮\n" +
                    "4、检测到用户登录后才能调用该接口，否则不展示前台操作按钮")
    public GenericsAjaxResult<ZoneFrontRoleVo> checkCurrentRole(@PathVariable Long zoneId) {
        return genericsSuccess(zoneDetailService.checkCurrentRoleInZone(zoneId));
    }

    // ==================== Skill资源广场 - 我的资源管理 ====================

    /**
     * 上传ZIP并解析
     */
    @RequiresPermissions("zone:front:skill:add")
    @PostMapping("/skill/parse")
    @ApiOperation("上传ZIP并解析Skill包")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "file", value = "文件实体", paramType = "form", dataType = "_file"),
    })
    public GenericsAjaxResult<AiSkillParseResultVo> parseSkillZip(@RequestPart("file") MultipartFile file) {
        return genericsSuccess(aiResourceParseService.parseSkillZip(file));
    }

    /**
     * 创建Skill资源
     */
    @RequiresPermissions("zone:front:skill:add")
    @Log(title = "创建Skill资源", businessType = BusinessType.INSERT)
    @PostMapping("/skill")
    @ApiOperation("创建Skill资源")
    public AjaxResult addSkill(@RequestBody @Validated AiSkillInputVo inputVo) {
        return success(zoneResourceService.insertAiSkillResource(inputVo));
    }

    @RequiresPermissions("zone:front:resource:add")
    @Log(title = "重新提交被驳回的资源", businessType = BusinessType.UPDATE)
    @PutMapping("/resource/{id}/resubmit")
    @ApiOperation(value = "重新提交被驳回的资源")
    public AjaxResult resubmitAiResource(
            @ApiParam(value = "资源ID", required = true) @PathVariable("id") Long id) {
        return toAjax(zoneResourceService.resubmitAiResource(id));
    }

    @RequiresPermissions("zone:front:resource:edit")
    @Log(title = "撤回审核中的资源", businessType = BusinessType.UPDATE)
    @PutMapping("/resource/{id}/withdraw")
    @ApiOperation(value = "撤回审核中的资源")
    public AjaxResult withdrawAiResource(
            @ApiParam(value = "资源ID", required = true) @PathVariable("id") Long id) {
        return toAjax(zoneResourceService.withdrawAiResource(id));
    }

    /**
     * 下架资源
     */
    @RequiresPermissions("zone:front:resource:edit")
    @Log(title = "下架资源", businessType = BusinessType.UPDATE)
    @PutMapping("/{id}/takeDown")
    @ApiOperation("下架资源")
    public AjaxResult takeDownResource(
            @ApiParam(value = "资源ID", required = true) @PathVariable("id") Long id,
            @RequestParam(value = "reason", required = false) String reason) {
        return toAjax(zoneResourceService.takeDownAiResource(id, reason));
    }

    /**
     * 上架资源
     */
    @RequiresPermissions("zone:front:resource:edit")
    @Log(title = "上架资源", businessType = BusinessType.UPDATE)
    @PutMapping("/{id}/takeUp")
    @ApiOperation("上架资源")
    public AjaxResult takeUpResource(
            @ApiParam(value = "资源ID", required = true) @PathVariable("id") Long id,
            @RequestParam(value = "reason", required = false) String reason) {
        return toAjax(zoneResourceService.takeUpAiResource(id, reason));
    }

    /**
     * 获取资源统计
     */
    @RequiresPermissions("zone:front:resource:query")
    @GetMapping("/resourceStatistics")
    @ApiOperation("获取资源统计")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "isMine", value = "是否查询我的资源(true-我的资源,false-专区资源)", paramType = "query", dataType = "boolean"),
            @ApiImplicitParam(name = "zoneId", value = "专区ID", paramType = "query", dataType = "Long", required = true),
            @ApiImplicitParam(name = "resourceCategory", value = "资源分类(SKILL/MODEL/DATASET)，为空则查询所有", paramType = "query", dataType = "String")
    })
    public GenericsAjaxResult<UserResourceStatisticsVo> resourceStatistics(
            @ApiParam(name = "isMine", value = "是否查询我的资源") @RequestParam(value = "isMine", required = false) Boolean isMine,
            @ApiParam(name = "zoneId") @RequestParam(value = "zoneId") Long zoneId,
            @ApiParam(name = "resourceCategory") @RequestParam(value = "resourceCategory", required = false) String resourceCategory) {
        return genericsSuccess(zoneResourceService.getResourceStatistics(zoneId, isMine, resourceCategory));
    }

    /**
     * 获取我的项目聚合统计
     */
    @RequiresPermissions("zone:front:project:query")
    @GetMapping("/myProjectStatistics")
    @ApiOperation("获取我的项目聚合统计")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "zoneId", value = "专区ID", paramType = "query", dataType = "Long", required = true)
    })
    public GenericsAjaxResult<UserProjectStatisticsVo> myProjectStatistics(@ApiParam(name = "zoneId") @RequestParam(value = "zoneId") Long zoneId) {
        return genericsSuccess(zoneProjectService.getUserProjectStatistics(zoneId,SecurityUtils.getUsername()));
    }

    /**
     * 点赞/取消点赞
     */
    @RequiresPermissions("zone:front:resource:query")
    @PostMapping("/{id}/like")
    @ApiOperation("点赞/取消点赞资源")
    public AjaxResult toggleLike(
            @ApiParam(value = "资源ID", required = true) @PathVariable("id") Long id) {
        boolean liked = zoneResourceService.toggleZoneResourcesLike(id);
        return success(liked ? "已点赞" : "已取消点赞");
    }

    /**
     * 修改Skill资源
     */
    @RequiresPermissions("zone:front:skill:edit")
    @Log(title = "修改Skill资源", businessType = BusinessType.UPDATE)
    @PutMapping("/skill")
    @ApiOperation("修改Skill资源")
    public AjaxResult editSkill(@RequestBody @Validated AiSkillUpdateVo updateVo) {
        return success(zoneResourceService.updateAiSkillResource(updateVo));
    }

    // ==================== 模型资源 ====================

    /**
     * 创建Model资源
     */
    @RequiresPermissions("zone:front:model:add")
    @Log(title = "创建Model资源", businessType = BusinessType.INSERT)
    @PostMapping("/resource/model")
    @ApiOperation("创建Model资源")
    public AjaxResult addModel(@RequestBody @Validated AiModelInputVo inputVo) {
        return success(zoneResourceService.insertAiModelResource(inputVo));
    }

    /**
     * 修改Model资源
     */
    @RequiresPermissions("zone:front:model:edit")
    @Log(title = "修改Model资源", businessType = BusinessType.UPDATE)
    @PutMapping("/resource/model")
    @ApiOperation("修改Model资源")
    public AjaxResult editModel(@RequestBody @Validated AiModelUpdateVo updateVo) {
        return success(zoneResourceService.updateAiModelResource(updateVo));
    }

    // ==================== 数据集资源 ====================

    /**
     * 创建Dataset资源
     */
    @RequiresPermissions("zone:front:dataset:add")
    @Log(title = "创建Dataset资源", businessType = BusinessType.INSERT)
    @PostMapping("/resource/dataset")
    @ApiOperation("创建Dataset资源")
    public AjaxResult addDataset(@RequestBody @Validated AiDatasetInputVo inputVo) {
        return success(zoneResourceService.insertAiDatasetResource(inputVo));
    }

    /**
     * 修改Dataset资源
     */
    @RequiresPermissions("zone:front:dataset:edit")
    @Log(title = "修改Dataset资源", businessType = BusinessType.UPDATE)
    @PutMapping("/resource/dataset")
    @ApiOperation("修改Dataset资源")
    public AjaxResult editDataset(@RequestBody @Validated AiDatasetUpdateVo updateVo) {
        return success(zoneResourceService.updateAiDatasetResource(updateVo));
    }


    /**
     * 查询资源是否点赞
     */
    @RequiresPermissions("zone:front:resource:query")
    @GetMapping("/{ids}/like")
    @ApiOperation(value = "查询资源是否点赞")
    public GenericsTableDataInfo<JSONObject> myResource(@PathVariable("ids") String ids) {
        return new GenericsTableDataInfo<>(zoneResourceService.selectZoneResourcesIsLike(ids));
    }
}
