package com.jeesharp.business.modules.food.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jeesharp.business.modules.food.entity.FoodCompanyEmployee;
import com.jeesharp.business.modules.food.mapper.FoodCompanyEmployeeMapper;
import com.jeesharp.business.modules.food.service.FoodCompanyEmployeeService;
import com.jeesharp.framework.mybatis.core.service.CrudService;
import com.jeesharp.framework.pojo.query.PaginationVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

@Service
@Transactional(readOnly = true)
public class FoodCompanyEmployeeServiceImpl extends CrudService<FoodCompanyEmployeeMapper, FoodCompanyEmployee, PaginationVO> implements FoodCompanyEmployeeService {

    private static final String DEL_NORMAL = "0";
    private static final int STATUS_DISABLED = 0;
    private static final int STATUS_ENABLED = 1;
    private static final int BIND_STATUS_BOUND = 1;
    private static final int BIND_STATUS_UNBOUND = 2;

    @Override
    public List<FoodCompanyEmployee> listBoundByMemberId(String memberId) {
        return getBaseMapper().selectList(new LambdaQueryWrapper<FoodCompanyEmployee>()
            .eq(FoodCompanyEmployee::getMemberId, memberId)
            .eq(FoodCompanyEmployee::getStatus, STATUS_ENABLED)
            .eq(FoodCompanyEmployee::getBindStatus, BIND_STATUS_BOUND)
            .eq(FoodCompanyEmployee::getDelFlag, DEL_NORMAL)
            .orderByDesc(FoodCompanyEmployee::getBindTime)
            .orderByDesc(FoodCompanyEmployee::getCreateDate));
    }

    @Override
    public FoodCompanyEmployee getBoundEmployee(String companyId, String memberId) {
        return getBaseMapper().selectOne(new LambdaQueryWrapper<FoodCompanyEmployee>()
            .eq(FoodCompanyEmployee::getCompanyId, companyId)
            .eq(FoodCompanyEmployee::getMemberId, memberId)
            .eq(FoodCompanyEmployee::getStatus, STATUS_ENABLED)
            .eq(FoodCompanyEmployee::getBindStatus, BIND_STATUS_BOUND)
            .eq(FoodCompanyEmployee::getDelFlag, DEL_NORMAL)
            .last("limit 1"));
    }

    @Override
    public FoodCompanyEmployee getAnyByCompanyAndMember(String companyId, String memberId) {
        if (StrUtil.isBlank(companyId) || StrUtil.isBlank(memberId)) {
            return null;
        }
        return getBaseMapper().selectOne(new LambdaQueryWrapper<FoodCompanyEmployee>()
            .eq(FoodCompanyEmployee::getCompanyId, companyId)
            .eq(FoodCompanyEmployee::getMemberId, memberId)
            .eq(FoodCompanyEmployee::getDelFlag, DEL_NORMAL)
            .last("limit 1"));
    }

    @Override
    public List<FoodCompanyEmployee> listByCompanyId(String companyId) {
        return getBaseMapper().selectList(new LambdaQueryWrapper<FoodCompanyEmployee>()
            .eq(FoodCompanyEmployee::getCompanyId, companyId)
            .eq(FoodCompanyEmployee::getDelFlag, DEL_NORMAL)
            .orderByDesc(FoodCompanyEmployee::getBindTime)
            .orderByDesc(FoodCompanyEmployee::getCreateDate));
    }

    @Override
    @Transactional(readOnly = false)
    public FoodCompanyEmployee saveOrBindEmployee(FoodCompanyEmployee employee) {
        if (StrUtil.isNotBlank(employee.getCompanyId()) && StrUtil.isNotBlank(employee.getMemberId())) {
            FoodCompanyEmployee existing = getAnyByCompanyAndMember(employee.getCompanyId(), employee.getMemberId());
            if (existing != null && !StrUtil.equals(existing.getId(), employee.getId())) {
                existing.setMemberNo(StrUtil.blankToDefault(employee.getMemberNo(), existing.getMemberNo()));
                existing.setEmployeeNo(StrUtil.blankToDefault(employee.getEmployeeNo(), existing.getEmployeeNo()));
                existing.setEmployeeName(StrUtil.blankToDefault(employee.getEmployeeName(), existing.getEmployeeName()));
                existing.setMobile(StrUtil.blankToDefault(employee.getMobile(), existing.getMobile()));
                existing.setStatus(employee.getStatus() == null ? STATUS_ENABLED : employee.getStatus());
                existing.setBindStatus(employee.getBindStatus() == null ? BIND_STATUS_BOUND : employee.getBindStatus());
                if (existing.getBindTime() == null && Integer.valueOf(BIND_STATUS_BOUND).equals(existing.getBindStatus())) {
                    existing.setBindTime(LocalDateTime.now());
                }
                existing.setUnbindTime(null);
                existing.setSource(StrUtil.blankToDefault(employee.getSource(), existing.getSource()));
                update(existing);
                return existing;
            }
        }
        if (employee.getStatus() == null) {
            employee.setStatus(STATUS_ENABLED);
        }
        if (employee.getBindStatus() == null) {
            employee.setBindStatus(StrUtil.isBlank(employee.getMemberId()) ? 0 : BIND_STATUS_BOUND);
        }
        if (employee.getBindTime() == null && Integer.valueOf(BIND_STATUS_BOUND).equals(employee.getBindStatus())) {
            employee.setBindTime(LocalDateTime.now());
        }
        if (StrUtil.isBlank(employee.getId())) {
            getBaseMapper().insert(employee);
        } else {
            update(employee);
        }
        return employee;
    }

    @Override
    @Transactional(readOnly = false)
    public void freezeEmployee(String employeeId) {
        FoodCompanyEmployee employee = get(employeeId);
        if (employee == null) {
            return;
        }
        employee.setStatus(STATUS_DISABLED);
        update(employee);
    }

    @Override
    @Transactional(readOnly = false)
    public void restoreEmployee(String employeeId) {
        FoodCompanyEmployee employee = get(employeeId);
        if (employee == null) {
            return;
        }
        employee.setStatus(STATUS_ENABLED);
        update(employee);
    }

    @Override
    @Transactional(readOnly = false)
    public void unbindEmployee(String employeeId) {
        FoodCompanyEmployee employee = get(employeeId);
        if (employee == null) {
            return;
        }
        employee.setBindStatus(BIND_STATUS_UNBOUND);
        employee.setUnbindTime(LocalDateTime.now());
        update(employee);
    }
}
