package com.ssm.manage.service.impl;

import com.ssm.core.service.impl.BaseServiceImpl;
import com.ssm.core.utils.RedisLock;
import com.ssm.manage.dao.SsmHairCallNumDao;
import com.ssm.manage.entity.BaseStore;
import com.ssm.manage.entity.SmsException;
import com.ssm.manage.extendEntity.CallEntity;
import com.ssm.manage.extendEntity.HairCallEntity;
import com.ssm.manage.response.ResponseCode;
import com.ssm.manage.service.SsmBaseStoreService;
import com.ssm.manage.service.SsmHairCallNumService;
import com.ssm.util.RedisClient;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class SsmHairCallNumServiceImpl extends BaseServiceImpl<HairCallEntity> implements SsmHairCallNumService {
    @Autowired
    private RedisClient<HairCallEntity> redisClient;

    @Autowired
    private RedisClient<String> stringRedisClient;

    @Autowired
    private SsmBaseStoreService ssmBaseStoreService;

    @Autowired
    private SsmHairCallNumDao dao;

    @Override
    public SsmHairCallNumDao getDao() {
        return dao;
    }

    private static String key = "hairCallNum";

    @Override
    public List<HairCallEntity> selectList(HairCallEntity hairCallEntity) {
        BaseStore store = ssmBaseStoreService.selectByPrimaryKey(hairCallEntity.getStoreId());
        String key = getKey(store.getStoreNum());
        List<HairCallEntity> list = new ArrayList<>();
        if (redisClient.hasKey(key)){
            list = redisClient.lRange(key,Long.parseLong("0"),Long.parseLong("-1"));
        }
        Map<Integer, List<HairCallEntity>> map = list.stream().collect(Collectors.groupingBy(HairCallEntity::getState));
        List<HairCallEntity> list1 = new ArrayList<>();
        //获取已叫号列表
        if (hairCallEntity.getState() == 1) {
            list1 = map.get(1);
        }else if (hairCallEntity.getState() == 0){
            //获取未叫号列表
            list1 = map.get(0);
        }else {
            //获取过号列表
            list1 = map.get(2);
        }
        return list1;
    }

    @Override
    public Integer selectNum(HairCallEntity hairCallEntity) {
        BaseStore store = ssmBaseStoreService.selectByPrimaryKey(hairCallEntity.getStoreId());
        String key = getKey(store.getStoreNum());
        List<HairCallEntity> list = new ArrayList<>();
        if (redisClient.hasKey(key)){
            list = redisClient.lRange(key,Long.parseLong("0"),Long.parseLong("-1"));
        }
        Map<Integer, List<HairCallEntity>> map = list.stream().collect(Collectors.groupingBy(HairCallEntity::getState));
        List<HairCallEntity> calledList = new ArrayList<>();
        //获取当前叫号
        if (hairCallEntity.getType() == 1) {
            calledList = map.get(1);
        }else {
            //获取当前取到多少号
            calledList = map.get(0);
        }
        Integer num = 0;
        if (null != calledList && !calledList.isEmpty()) {
            //获取最后一个已叫号的号码
            num = calledList.get(calledList.size()-1).getNum();
        }
        return num;
    }

    @Override
    public HairCallEntity addNum(HairCallEntity hairCallEntity) throws SmsException {
        BaseStore store = ssmBaseStoreService.selectByPrimaryKey(hairCallEntity.getStoreId());
        String key = getKey(store.getStoreNum());
        int i = 0;
        int num = 0;
        List<HairCallEntity> list = new ArrayList<>();
        if (redisClient.hasKey(key)){
            list = redisClient.lRange(key,Long.parseLong("0"),Long.parseLong("-1"));
            //列表最后一个号码 + 1
            num = list.get(list.size()-1).getNum() + 1;
        }else {
            num = num + 1;
        }

        hairCallEntity.setNum(num);

        //默认未叫号状态
        hairCallEntity.setState(0);
        i = redisClient.rightPush(key,hairCallEntity).intValue();
        if (i > 0){
            return hairCallEntity;
        }else {
            throw new SmsException(ResponseCode.UNKNOWN_SYSTEM_EXCEPTION);
        }

    }

    @Override
    public HairCallEntity callNum(HairCallEntity hairCallEntity) throws SmsException, InterruptedException {
        HairCallEntity entity = new HairCallEntity();
        BaseStore store = ssmBaseStoreService.selectByPrimaryKey(hairCallEntity.getStoreId());
        String key = getKey(store.getStoreNum());
        List<HairCallEntity> list = new ArrayList<>();
        String path = "";
        if (redisClient.hasKey(key)) {
            list = redisClient.lRange(key, Long.parseLong("0"), Long.parseLong("-1"));
            RedisLock lock = new RedisLock(stringRedisClient, key);
            //遍历获取第一个状态为未叫号的号码 修改状态为叫号
            if (lock.lock()) {
                for (int i = 0; i < list.size(); i++) {
                    entity = list.get(i);

                    try {

                        //状态为未叫号 并且支付完成关联的有单据号的号码
                        if (entity.getState() == 0 && null != entity.getDocId()) {
                            entity.setState(1);
                            //设置文件读取路径   1-001.mp3
                            String num = "";
                            if (entity.getNum() < 10) {
                                num = "00" + entity.getNum();
                            } else if (entity.getNum() < 100) {
                                num = "0" + entity.getNum();
                            } else {
                                num = "" + entity.getNum();
                            }
                            //设置文件读取路径 1-001.mp3
                            path = "demay/voice/" + hairCallEntity.getStaffNum() + "-" + num + ".mp3";
                            entity.setPath(path);
                            redisClient.lSet(key, Long.parseLong(String.valueOf(i)), entity);
                            break;
                        }

                    } catch (Exception e) {
                        log.error("SsmHairCallNumServiceImpl.callNum:", e);
                        throw new SmsException(ResponseCode.UNKNOWN_SYSTEM_EXCEPTION);
                    } finally {
                        lock.unlock();
                    }
                }
            }
        }
        return entity;
    }

    @Override
    public void passNum(HairCallEntity hairCallEntity) {
        BaseStore store = ssmBaseStoreService.selectByPrimaryKey(hairCallEntity.getStoreId());
        String key = getKey(store.getStoreNum());
        List<HairCallEntity> list = new ArrayList<>();
        if (redisClient.hasKey(key)){
            list = redisClient.lRange(key,Long.parseLong("0"),Long.parseLong("-1"));
            for (int i = 0; i < list.size(); i++) {
                HairCallEntity callEntity = list.get(i);
                if (callEntity.getNum() == hairCallEntity.getNum()) {
                    //设置为过号状态
                    callEntity.setState(2);
                    redisClient.lSet(key, Long.parseLong(String.valueOf(i)), callEntity);
                }
            }
        }
    }

    @Override
    public void deleteCallNum(HairCallEntity hairCallEntity) {
        BaseStore store = ssmBaseStoreService.selectByPrimaryKey(hairCallEntity.getStoreId());
        String key = getKey(store.getStoreNum());
        List<HairCallEntity> list = new ArrayList<>();
        if (redisClient.hasKey(key)){
            list = redisClient.lRange(key,Long.parseLong("0"),Long.parseLong("-1"));
            for (int i = 0; i < list.size(); i++) {
                HairCallEntity callEntity = list.get(i);
                if (null != hairCallEntity.getNum()) {
                    if (callEntity.getNum() == hairCallEntity.getNum()) {
                        //删除当前号码
                        redisClient.lRem(key, Long.parseLong(String.valueOf(i)), callEntity);
                    }
                }else {
                    //兼容定时任务删除
                    redisClient.lRem(key,Long.parseLong(String.valueOf(i)),callEntity);
                }
            }
        }
    }

    @Override
    public void connectNum(HairCallEntity hairCallEntity) {
        BaseStore store = ssmBaseStoreService.selectByPrimaryKey(hairCallEntity.getStoreId());
        String key = getKey(store.getStoreNum());
        List<HairCallEntity> list = new ArrayList<>();
        if (redisClient.hasKey(key)){
            list = redisClient.lRange(key,Long.parseLong("0"),Long.parseLong("-1"));
            for (int i = 0; i < list.size(); i++) {
                HairCallEntity callEntity = list.get(i);
                if (callEntity.getNum() == hairCallEntity.getNum()) {
                    //关联单据号和消费者openid
                    callEntity.setDocId(hairCallEntity.getDocId());
                    callEntity.setOpenid(hairCallEntity.getOpenid());
                    redisClient.lSet(key, Long.parseLong(String.valueOf(i)), callEntity);
                }
            }
        }
    }

    @Override
    public void passCallNum(HairCallEntity hairCallEntity) {
        //过号的号码重新叫号
        BaseStore store = ssmBaseStoreService.selectByPrimaryKey(hairCallEntity.getStoreId());
        String key = getKey(store.getStoreNum());
        List<HairCallEntity> list = new ArrayList<>();
        if (redisClient.hasKey(key)){
            list = redisClient.lRange(key,Long.parseLong("0"),Long.parseLong("-1"));
            for (int i = 0; i < list.size(); i++) {
                HairCallEntity callEntity = list.get(i);
                if (callEntity.getNum() == hairCallEntity.getNum()) {
                    //设置为叫号状态
                    callEntity.setState(1);
                    redisClient.lSet(key, Long.parseLong(String.valueOf(i)), callEntity);
                }
            }
        }
    }

    @Override
    public HairCallEntity nextWaitNum(HairCallEntity hairCallEntity) {
        HairCallEntity entity = new HairCallEntity();
        BaseStore store = ssmBaseStoreService.selectByPrimaryKey(hairCallEntity.getStoreId());
        String key = getKey(store.getStoreNum());
        List<HairCallEntity> list = new ArrayList<>();
        //前台传递的当前叫号的下一个号码
        int num = hairCallEntity.getNum() + 1;
        if (redisClient.hasKey(key)) {
            list = redisClient.lRange(key, Long.parseLong("0"), Long.parseLong("-1"));
            if (num > list.size()){
                return entity;
            }
            for (int i = num-1; i <= list.size(); i++) {
                entity = list.get(i);
                if (entity.getNum() == num && entity.getState() == 0 && null != entity.getDocId()) {
                    break;
                }
                num += 1;
            }
        }
        return entity;
    }

    public String getKey(String storeNum){
        return key + "-" + storeNum;
    }
}
