package com.jeesharp.business.modules.food.application;

import cn.hutool.core.util.StrUtil;
import com.jeesharp.business.modules.food.dto.FoodCompanyEmployeeSaveDTO;
import com.jeesharp.business.modules.food.dto.FoodCompanySaveDTO;
import com.jeesharp.business.modules.food.entity.FoodCompany;
import com.jeesharp.business.modules.food.entity.FoodCompanyEmployee;
import com.jeesharp.business.modules.food.service.FoodCompanyEmployeeService;
import com.jeesharp.business.modules.food.service.FoodCompanyService;
import com.jeesharp.business.modules.food.vo.FoodCompanyEmployeeListVO;
import com.jeesharp.business.modules.food.vo.FoodCompanyEmployeeQueryVO;
import com.jeesharp.business.modules.food.vo.FoodCompanyInfoVO;
import com.jeesharp.business.modules.food.vo.FoodCompanyListVO;
import com.jeesharp.business.modules.food.vo.FoodCompanyQueryVO;
import com.jeesharp.business.modules.food.vo.FoodCompanySearchVO;
import com.jeesharp.framework.exception.BizErrorException;
import com.jeesharp.framework.pojo.Page;
import com.jeesharp.framework.pojo.query.PageRespVO;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@AllArgsConstructor
@Transactional(readOnly = true)
public class FoodCompanyEmployeeApplicationService {

    private static final int STATUS_ENABLED = 1;
    private static final String SOURCE_ADMIN = "ADMIN";

    private final FoodCompanyService foodCompanyService;
    private final FoodCompanyEmployeeService foodCompanyEmployeeService;

    public PageRespVO<FoodCompanyListVO> findCompanyPage(Page<FoodCompany> page, FoodCompanyQueryVO query) {
        Page<FoodCompany> result = foodCompanyService.findPage(page, query);
        PageRespVO<FoodCompanyListVO> resp = new PageRespVO<>();
        resp.setTotal(result.getTotal());
        resp.setPages(result.getPages());
        resp.setPageNo(result.getPageNo());
        resp.setPageSize(result.getPageSize());
        resp.setRecords(result.getRecords().stream().map(this::toCompanyListVO).collect(Collectors.toList()));
        return resp;
    }

    public FoodCompanyInfoVO getCompany(String id) {
        return toCompanyInfoVO(foodCompanyService.get(id));
    }

    public List<FoodCompanySearchVO> searchCompanies(String keyword) {
        return foodCompanyService.searchEnabledCompanies(keyword, 50).stream().map(this::toCompanySearchVO).collect(Collectors.toList());
    }

    @Transactional(readOnly = false)
    public void saveCompany(FoodCompanySaveDTO dto) {
        FoodCompany entity = new FoodCompany();
        entity.setId(dto.getId());
        entity.setCompanyName(StrUtil.trim(dto.getCompanyName()));
        entity.setCompanyCode(StrUtil.trim(dto.getCompanyCode()));
        entity.setContactName(StrUtil.trim(dto.getContactName()));
        entity.setContactPhone(StrUtil.trim(dto.getContactPhone()));
        entity.setStatus(dto.getStatus() == null ? STATUS_ENABLED : dto.getStatus());
        if (StrUtil.isBlank(entity.getId())) {
            foodCompanyService.save(entity);
        } else {
            foodCompanyService.update(entity);
        }
    }

    @Transactional(readOnly = false)
    public void updateCompanyStatus(String id, Integer status) {
        FoodCompany company = foodCompanyService.get(id);
        if (company == null) {
            throw new BizErrorException("企业不存在");
        }
        company.setStatus(status == null ? STATUS_ENABLED : status);
        foodCompanyService.update(company);
    }

    @Transactional(readOnly = false)
    public void deleteCompany(String ids) {
        foodCompanyService.batchDelete(StrUtil.splitTrim(ids, ','));
    }

    public PageRespVO<FoodCompanyEmployeeListVO> findEmployeePage(Page<FoodCompanyEmployee> page, FoodCompanyEmployeeQueryVO query) {
        Page<FoodCompanyEmployee> result = foodCompanyEmployeeService.findPage(page, query);
        Map<String, FoodCompany> companyMap = result.getRecords().stream()
            .map(FoodCompanyEmployee::getCompanyId)
            .filter(StrUtil::isNotBlank)
            .distinct()
            .map(foodCompanyService::getById)
            .filter(Objects::nonNull)
            .collect(Collectors.toMap(FoodCompany::getId, Function.identity(), (a, b) -> a));
        PageRespVO<FoodCompanyEmployeeListVO> resp = new PageRespVO<>();
        resp.setTotal(result.getTotal());
        resp.setPages(result.getPages());
        resp.setPageNo(result.getPageNo());
        resp.setPageSize(result.getPageSize());
        resp.setRecords(result.getRecords().stream().map(e -> toEmployeeListVO(e, companyMap.get(e.getCompanyId()))).collect(Collectors.toList()));
        return resp;
    }

    public FoodCompanyEmployeeListVO getEmployee(String id) {
        FoodCompanyEmployee employee = foodCompanyEmployeeService.get(id);
        FoodCompany company = employee == null ? null : foodCompanyService.getById(employee.getCompanyId());
        return toEmployeeListVO(employee, company);
    }

    @Transactional(readOnly = false)
    public void saveEmployee(FoodCompanyEmployeeSaveDTO dto) {
        FoodCompany company = foodCompanyService.getById(dto.getCompanyId());
        if (company == null) {
            throw new BizErrorException("企业不存在");
        }
        FoodCompanyEmployee employee = new FoodCompanyEmployee();
        employee.setId(dto.getId());
        employee.setCompanyId(dto.getCompanyId());
        employee.setMemberId(StrUtil.trim(dto.getMemberId()));
        employee.setMemberNo(StrUtil.trim(dto.getMemberNo()));
        employee.setEmployeeNo(StrUtil.trim(dto.getEmployeeNo()));
        employee.setEmployeeName(StrUtil.trim(dto.getEmployeeName()));
        employee.setMobile(StrUtil.trim(dto.getMobile()));
        employee.setStatus(dto.getStatus());
        employee.setBindStatus(dto.getBindStatus());
        employee.setSource(SOURCE_ADMIN);
        foodCompanyEmployeeService.saveOrBindEmployee(employee);
    }

    @Transactional(readOnly = false)
    public void freezeEmployee(String id) {
        foodCompanyEmployeeService.freezeEmployee(id);
    }

    @Transactional(readOnly = false)
    public void restoreEmployee(String id) {
        foodCompanyEmployeeService.restoreEmployee(id);
    }

    @Transactional(readOnly = false)
    public void unbindEmployee(String id) {
        foodCompanyEmployeeService.unbindEmployee(id);
    }

    @Transactional(readOnly = false)
    public void deleteEmployee(String ids) {
        foodCompanyEmployeeService.batchDelete(StrUtil.splitTrim(ids, ','));
    }

    private FoodCompanyListVO toCompanyListVO(FoodCompany company) {
        FoodCompanyListVO vo = new FoodCompanyListVO();
        vo.setId(company.getId());
        vo.setCreateDate(company.getCreateDate());
        vo.setCompanyCode(company.getCompanyCode());
        vo.setCompanyName(company.getCompanyName());
        vo.setContactName(company.getContactName());
        vo.setContactPhone(company.getContactPhone());
        vo.setStatus(company.getStatus());
        return vo;
    }

    private FoodCompanyInfoVO toCompanyInfoVO(FoodCompany company) {
        if (company == null) {
            return null;
        }
        FoodCompanyInfoVO vo = new FoodCompanyInfoVO();
        vo.setId(company.getId());
        vo.setCompanyCode(company.getCompanyCode());
        vo.setCompanyName(company.getCompanyName());
        vo.setContactName(company.getContactName());
        vo.setContactPhone(company.getContactPhone());
        vo.setStatus(company.getStatus());
        return vo;
    }

    private FoodCompanySearchVO toCompanySearchVO(FoodCompany company) {
        FoodCompanySearchVO vo = new FoodCompanySearchVO();
        vo.setId(company.getId());
        vo.setCompanyId(company.getId());
        vo.setCompanyCode(company.getCompanyCode());
        vo.setCompanyName(company.getCompanyName());
        vo.setContactName(company.getContactName());
        vo.setContactPhone(company.getContactPhone());
        vo.setStatus(company.getStatus());
        return vo;
    }

    private FoodCompanyEmployeeListVO toEmployeeListVO(FoodCompanyEmployee employee, FoodCompany company) {
        if (employee == null) {
            return null;
        }
        FoodCompanyEmployeeListVO vo = new FoodCompanyEmployeeListVO();
        vo.setId(employee.getId());
        vo.setCreateDate(employee.getCreateDate());
        vo.setCompanyId(employee.getCompanyId());
        if (company != null) {
            vo.setCompanyCode(company.getCompanyCode());
            vo.setCompanyName(company.getCompanyName());
        }
        vo.setMemberId(employee.getMemberId());
        vo.setMemberNo(employee.getMemberNo());
        vo.setEmployeeNo(employee.getEmployeeNo());
        vo.setEmployeeName(employee.getEmployeeName());
        vo.setMobile(employee.getMobile());
        vo.setStatus(employee.getStatus());
        vo.setBindStatus(employee.getBindStatus());
        vo.setBindTime(employee.getBindTime());
        vo.setUnbindTime(employee.getUnbindTime());
        vo.setSource(employee.getSource());
        return vo;
    }
}
