package com.eitc.patient.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.eitc.common.annotation.Log;
import com.eitc.common.core.controller.BaseController;
import com.eitc.common.core.domain.AjaxResult;
import com.eitc.common.enums.BusinessType;
import com.eitc.common.utils.bean.BeanUtils;
import com.eitc.patient.domain.AppointmentProject;
import com.eitc.patient.enums.AppointmentProjectTypeEnum;
import com.eitc.patient.service.IAppointmentProjectService;
import com.eitc.patient.tree.AppointmentProjectTree;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * DiagnosisTypeController
 *
 * @author mtx
 * @date: 2024/05/17 15:51
 */
@Api(tags = "预约项目")
@RestController
@RequestMapping("/project/appointment-project")
public class AppointmentProjectController extends BaseController {

    @Resource
    private IAppointmentProjectService appointmentProjectService;

    /**
     * 查询预约项目
     */
    @GetMapping("/list")
    @ApiOperation("查询所有预约项目")
    public AjaxResult list(AppointmentProject appointmentProject) {
        // 查询所有预约项目
        appointmentProject.setType(AppointmentProjectTypeEnum.PROJECT.getCode());
        return success(getAppointmentProjects(appointmentProject));
    }

    @GetMapping("/tree")
    @ApiOperation("查询层级预约项目")
    public AjaxResult tree(AppointmentProject appointmentProject) {
        // 查询预约项目
        List<AppointmentProject> list = getAppointmentProjects(appointmentProject);
        // 封装树形结构
        List<AppointmentProjectTree> treeBeans = list.stream().map(item -> {
            AppointmentProjectTree entry = new AppointmentProjectTree();
            BeanUtils.copyProperties(item, entry);
            return entry;
        }).collect(Collectors.toList());
        //获取父节点
        List<AppointmentProjectTree> collect = getChildren("0", treeBeans);

        return success(collect);
    }

    /**
     * 根据搜索条件查询所有的预约项目
     *
     * @param appointmentProject 搜索条件
     * @return 列表
     */
    private List<AppointmentProject> getAppointmentProjects(AppointmentProject appointmentProject) {
        LambdaQueryWrapper<AppointmentProject> eq = Wrappers.<AppointmentProject>lambdaQuery()
                .eq(Objects.nonNull(appointmentProject.getType()), AppointmentProject::getType, appointmentProject.getType())
                .eq(StringUtils.isNotBlank(appointmentProject.getParentId()), AppointmentProject::getParentId, appointmentProject.getParentId())
                .eq(StringUtils.isNotBlank(appointmentProject.getAppointmentName()), AppointmentProject::getAppointmentName, appointmentProject.getAppointmentName())
                .orderByDesc(AppointmentProject::getUpdateDate);

        return appointmentProjectService.list(eq);
    }

    /**
     * 封装属性结构
     *
     * @param parentId 父级id
     * @param list     数据
     * @return 封装好的数据
     */
    public static List<AppointmentProjectTree> getChildren(String parentId, List<AppointmentProjectTree> list) {
        return list.stream().filter(t -> Objects.equals(t.getParentId(), parentId)).peek(
                m -> m.setChildrenList(getChildren(m.getId(), list))
        ).collect(Collectors.toList());
    }

    /**
     * 获取预约项目详细信息
     */
    @GetMapping(value = "/detail")
    @ApiOperation("获取预约项目详细信息")
    public AjaxResult detail(String id) {
        return success(appointmentProjectService.getById(id));
    }

    /**
     * 新增预约项目
     */
    @Log(title = "新增预约项目", businessType = BusinessType.INSERT)
    @PostMapping
    @ApiOperation("新增预约项目")
    public AjaxResult add(@ApiParam(name = "appointmentProject") @Valid @RequestBody AppointmentProject appointmentProject) {
        long count = appointmentProjectService.count(Wrappers.<AppointmentProject>lambdaQuery()
                .eq(AppointmentProject::getType, AppointmentProjectTypeEnum.CATALOGUE.getCode())
                .eq(AppointmentProject::getParentId, appointmentProject.getParentId()));
        if (AppointmentProjectTypeEnum.PROJECT.getCode().equals(appointmentProject.getType()) && count > 0) {
            return error("不允许添加项目");
        }
        long count2 = appointmentProjectService.count(Wrappers.<AppointmentProject>lambdaQuery()
                .eq(AppointmentProject::getType, AppointmentProjectTypeEnum.PROJECT.getCode())
                .eq(AppointmentProject::getParentId, appointmentProject.getParentId()));
        if (AppointmentProjectTypeEnum.CATALOGUE.getCode().equals(appointmentProject.getType()) && count2 > 0) {
            return error("不允许添加子集");
        }
        return toAjax(appointmentProjectService.save(appointmentProject));
    }

    /**
     * 修改预约项目
     */
    @Log(title = "修改预约项目", businessType = BusinessType.UPDATE)
    @PutMapping
    @ApiOperation("修改预约项目")
    public AjaxResult edit(@ApiParam(name = "appointmentProject") @RequestBody AppointmentProject appointmentProject) {
        return toAjax(appointmentProjectService.updateById(appointmentProject));
    }

    /**
     * 删除预约项目
     */
    @Log(title = "删除预约项目", businessType = BusinessType.DELETE)
    @DeleteMapping("/remove")
    @ApiOperation("删除预约项目")
    public AjaxResult remove(String ids) {
        List<String> idList = Arrays.asList(ids.split(","));
        for (String id : idList) {
            // 判断是否有子集
            long count = appointmentProjectService.count(Wrappers.<AppointmentProject>lambdaQuery()
                    .eq(AppointmentProject::getType, AppointmentProjectTypeEnum.CATALOGUE.getCode())
                    .eq(AppointmentProject::getParentId, id));
            if (count > 0) {
                throw new IllegalArgumentException("请删除子集");
            }
            // 判断是否有模板
            long templateCount = appointmentProjectService.count(Wrappers.<AppointmentProject>lambdaQuery()
                    .eq(AppointmentProject::getType, AppointmentProjectTypeEnum.PROJECT.getCode())
                    .eq(AppointmentProject::getParentId, id));
            if (templateCount > 0) {
                throw new IllegalArgumentException("请删除项目");
            }
        }
        return toAjax(appointmentProjectService.removeBatchByIds(idList));
    }

    @GetMapping("/crumb")
    @ApiOperation("查询面包屑")
    public AjaxResult crumb(@RequestParam("id") String id) {
        AppointmentProject service = appointmentProjectService.getById(id);
        String appointmentName = service.getAppointmentName();
        String parentId = service.getParentId();
        String crumbStr = findCrumb(parentId);
        Object str;
        if (StringUtils.isNotBlank(crumbStr)) {
            str = crumbStr + " > " + appointmentName;
        } else {
            str = appointmentName;
        }
        return success(str);
    }

    /**
     * 获取面包屑
     *
     * @param parentId id
     * @return 字符串
     * @author mtx
     * @date: 2024/5/31 10:12
     */
    private String findCrumb(String parentId) {
        if (!"0".equals(parentId)) {
            AppointmentProject service = appointmentProjectService.getById(parentId);
            String appointmentName = service.getAppointmentName();
            // 循环添加子集面包屑
            String s = findCrumb(service.getParentId());
            if (StringUtils.isNotBlank(s)) {
                return s + " > " + appointmentName;
            } else {
                return appointmentName;
            }
        }
        return "";
    }

}
