package com.infoepoch.pms.dispatchassistant.controller.basic;

import com.infoepoch.pms.dispatchassistant.common.component.BaseController;
import com.infoepoch.pms.dispatchassistant.common.component.Result;
import com.infoepoch.pms.dispatchassistant.common.exception.NotLoginException;
import com.infoepoch.pms.dispatchassistant.domain.basic.organization.*;
import com.infoepoch.pms.dispatchassistant.domain.basic.user.User;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/organization")
public class OrganizationController extends BaseController {

    @Autowired
    private OrganizationService organizationService;
    @Autowired
    private IOrganizationRepository organizationRepository;

    @Autowired
    private Auth auth;

    /**
     * 获取分公司列表
     *
     * @return
     */
    @GetMapping("/branch-company-list")
    public Result branchCompanyList() {
        OrganizationCriteria criteria = new OrganizationCriteria();
        criteria.setLevel(2);
        List<Organization> organizationList = organizationRepository.selectByCriteria(criteria);
        return Result.successData(organizationList);
    }

    @GetMapping("/department-tree")
    public Result departmentTree() {
        List<Map<String, Object>> list = new ArrayList<>();
        for (Organization o : OrganizationRoot.getRootOrganizations()) {
            list.add(addChildrenOrganizationTwo(o));
        }
        return Result.successData(list);
    }

    @GetMapping("/current-department-tree")
    public Result currentDepartmentTree() {
        Map<String, Object> map = new HashMap<>();
        List<Map<String, Object>> list = new ArrayList<>();
        User user = auth.getUser();
        Organization organization = OrganizationRoot.getCompanyById(user.getOrganizationId());
        if (organization != null && OrganizationRoot.judgeBranchCompany(organization.getId())) {
            list.add(addChildrenOrganization(organization));
        } else {
            for (Organization o : OrganizationRoot.getRootOrganizations()) {
                list.add(addChildrenOrganization(o));
            }
            organization = null;
        }
        //当前登录用户的部门
        map.put("list", list);
        map.put("organization", organization);
        return Result.successData(map);
    }

    @GetMapping("/current-departmentOrg-tree")
    public Result currentDepartmentOrg() {
        return Result.successData(organizationService.getCurrentDepartmentOrg(auth.getUser().getOrganizationId()));
    }

    private Map<String, Object> addChildrenOrganization(Organization organization) {
        Map<String, Object> map = new HashMap<>();
        map.put("id", organization.getId());
        map.put("name", organization.getName());
        if (organization.hasChildren()) {
            map.put("nocheck", true);
            List<Map<String, Object>> l = new ArrayList<>();
            for (Organization o : organization.getChildren()) {
                l.add(addChildrenOrganization(o));
            }
            map.put("children", l);
        } else {
            map.put("nocheck", false);
        }
        return map;
    }

    private Map<String, Object> addChildrenOrganizationTwo(Organization organization) {
        Map<String, Object> map = new HashMap<>();
        map.put("id", organization.getId());
        map.put("name", organization.getName());
        if (organization.hasChildren()) {
            map.put("nocheck", false);
            List<Map<String, Object>> l = new ArrayList<>();
            for (Organization o : organization.getChildren()) {
                l.add(addChildrenOrganizationTwo(o));
            }
            map.put("children", l);
        } else {
            map.put("nocheck", false);
        }
        return map;
    }

    /**
     * 组织列表
     *
     * @param criteria
     * @return
     */
    @PostMapping("/list")
    public Result list(@RequestBody OrganizationCriteria criteria) throws NotLoginException {
        Map<String, Object> resultMap = new HashMap<>();
        User user = auth.getUserReq();
        if (OrganizationRoot.judgeBranchCompany(user.getOrganizationId())) {
            Organization department = OrganizationRoot.getCompanyById(user.getOrganizationId());
            List<String> branchOrgIdList = organizationService.getChildrenOrgIdList(department.getId());
            branchOrgIdList.add(department.getId());
            criteria.setOrgIdList(branchOrgIdList);
        }
        if (criteria.byPage()) {
            List<Organization> list = organizationRepository.selectByCriteriaPage(criteria, criteria.getPageIndex(), criteria.getPageSize());
            resultMap.put("list", list);
            resultMap.put("totalCount", organizationRepository.selectCountByCriteria(criteria));
        } else {
            resultMap.put("list", organizationRepository.selectByCriteria(criteria));
        }
        return Result.successData(resultMap);
    }

    /**
     * 组织弹窗
     *
     * @param criteria
     * @return
     * @throws NotLoginException
     */
    @PostMapping("/popup-list")
    public Result poppuList(@RequestBody OrganizationCriteria criteria) throws NotLoginException {
        Map<String, Object> resultMap = new HashMap<>();
        criteria.setDisabledFlag(false);
        if (criteria.byPage()) {
            List<Organization> list = organizationRepository.selectByCriteriaPage(criteria, criteria.getPageIndex(), criteria.getPageSize());
            resultMap.put("list", list);
            resultMap.put("totalCount", organizationRepository.selectCountByCriteria(criteria));
        } else {
            resultMap.put("list", organizationRepository.selectByCriteria(criteria));
        }
        return Result.successData(resultMap);
    }

    @GetMapping("/detail/{id}")
    public Result detail(@PathVariable("id") String id) {
        return Result.successData(organizationService.detail(id));
    }

    /**
     * 新增组织
     *
     * @param organization
     * @return
     */
    @PostMapping("/create")
    public Result create(@RequestBody Organization organization) {
        organizationService.create(organization);
        return Result.success();
    }

    /**
     * 修改组织信息
     *
     * @param organization
     * @return
     */
    @PostMapping("/modify")
    public Result modify(@RequestBody Organization organization) {
        organizationService.modify(organization);
        return Result.success();
    }

    /**
     * 删除组织
     *
     * @param id
     * @return
     */
    @GetMapping("/remove/{id}")
    public Result remove(@PathVariable("id") String id) {
        organizationService.remove(id);
        return Result.success();
    }

    /**
     * 刷新组织
     *
     * @return
     */
    @GetMapping("/refresh")
    public Result refresh() {
        organizationService.updateProvinceOrganizationName();
        organizationService.freshOrganization();
        return Result.success();
    }

    /**
     * @param name
     * @return
     */
    @GetMapping("/get-by-name/{name}")
    public Result getByName(@PathVariable("name") String name) {
        return Result.successData(organizationService.getByShortName(name));
    }

    /**
     * 根据组织id获取公司组织
     * @return
     */
    @GetMapping("/getCompany-by-id/{id}")
    public Result getCompanyByOrgId(@PathVariable String id){
        if (com.infoepoch.pms.dispatchassistant.common.utils.StringUtils.isNotEmpty(id)){
            Organization company = OrganizationRoot.getCompanyById(id);
            return Result.successData(company);
        }
        return Result.success();
    }

    /**
     * 根据组织id获取部门组织
     * @return
     */
    @GetMapping("/getDepartmentName-by-id/{id}")
    public Result getDepartmentByOrgId(@PathVariable String id){
        if (com.infoepoch.pms.dispatchassistant.common.utils.StringUtils.isNotEmpty(id)){
            Organization company = OrganizationRoot.getDepartmentById(id);
            return Result.successData(company);
        }
        return Result.success();
    }

    /**
     * 室弹窗查询
     *
     * @param pageIndex        分页index
     * @param pageSize         分页大小
     * @param shortNameContain 室名称模糊查询
     */
    @PostMapping("/room-popup-list")
    public Map<String, Object> queryPopupList(@RequestParam(value = "pageIndex", defaultValue = "1") Integer pageIndex,
                                              @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
                                              @RequestParam(value = "shortNameContain", defaultValue = "") String shortNameContain) {
        // 查询条件
        final Predicate<Organization> criteria = organization -> {
            if (StringUtils.isNotBlank(shortNameContain) && !organization.getName().contains(shortNameContain)) {
                return false;
            }
            return true;
        };

        Map<String, Object> retMap = Result.success().toMap();

        retMap.put("totalCount", OrganizationRoot.getRootOrganizations()
                .stream().map(list -> list.getChildren().stream().filter(criteria).count()).reduce(Long::sum));
        retMap.put("list",
                OrganizationRoot.getRootOrganizations()
                        .stream().flatMap(item -> item.getChildren().stream())
                        // 根据查询条件过滤
                        .filter(criteria)
                        // 根据排序字段排序
                        .sorted(Comparator.comparingInt(Organization::getDisplayOrderValue))
                        // 分页
                        .skip((long) (pageIndex - 1) * pageSize)
                        .limit(pageSize)
                        .collect(Collectors.toList()));

        return retMap;
    }

    /**
     * 刷新组织名称
     *
     * @return
     */
    @GetMapping("/refresh-org-name")
    public Result refreshOrgName() {
        organizationService.updateProvinceOrganizationName();
        return Result.success();
    }

}
