package com.sqx.modules.shop.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.ClientException;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.qcloudsms.SmsSingleSender;
import com.github.qcloudsms.SmsSingleSenderResult;
import com.github.qcloudsms.httpclient.HTTPException;
import com.sqx.common.utils.PageUtils;
import com.sqx.common.utils.Result;
import com.sqx.modules.app.dao.*;
import com.sqx.modules.app.entity.Msg;
import com.sqx.modules.app.entity.UserBrowse;
import com.sqx.modules.app.entity.UserEntity;
import com.sqx.modules.app.entity.UserMoneyDetails;
import com.sqx.modules.app.service.UserMoneyDetailsService;
import com.sqx.modules.app.service.UserService;
import com.sqx.modules.common.entity.CommonInfo;
import com.sqx.modules.common.service.CommonInfoService;
import com.sqx.modules.datacentre.dao.ShopAdminDao;
import com.sqx.modules.datacentre.entity.SysUserShop;
import com.sqx.modules.errand.dao.ErrandComplaintDao;
import com.sqx.modules.errand.dao.ErrandEvaluateDao;
import com.sqx.modules.errand.entity.ErrandComplaint;
import com.sqx.modules.errand.entity.Feedback;
import com.sqx.modules.file.utils.Md5Utils;
import com.sqx.modules.goods.dao.GoodsShopDao;
import com.sqx.modules.goods.entity.GoodsShop;
import com.sqx.modules.order.dao.AppOrderDao;
import com.sqx.modules.order.entity.TbOrder;
import com.sqx.modules.pay.service.CashOutService;
import com.sqx.modules.shop.dao.ShopMessageDao;
import com.sqx.modules.shop.service.ShopMessageService;
import com.sqx.modules.sys.dao.SysUserDao;
import com.sqx.modules.sys.entity.SysUserEntity;
import com.sqx.modules.sys.service.SysUserRoleService;
import com.sqx.modules.utils.fieYun.FeiYunUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.locks.ReentrantReadWriteLock;

@Slf4j
@Service
public class ShopMessageServiceImpl extends ServiceImpl<ShopMessageDao, GoodsShop> implements ShopMessageService {

    @Autowired
    private ShopMessageDao shopMessageDao;
    @Autowired
    private GoodsShopDao goodsShopDao;
    @Autowired
    private SysUserDao sysUserDao;
    @Autowired
    private ShopAdminDao shopAdminDao;
    @Autowired
    private SysUserRoleService sysUserRoleService;
    @Autowired
    private CommonInfoService commonInfoService;
    @Autowired
    private UserDao userDao;
    @Autowired
    private UserMoneyDao userMoneyDao;
    @Autowired
    private UserMoneyDetailsDao userMoneyDetailsDao;
    @Autowired
    private MsgDao msgDao;
    @Autowired
    private ErrandComplaintDao errandComplaintDao;
    @Autowired
    private ErrandEvaluateDao errandEvaluateDao;
    @Autowired
    private UserMoneyDetailsService userMoneyDetailsService;
    @Autowired
    private UserBrowseDao userBrowseDao;
    @Autowired
    private CashOutService cashOutService;
    @Autowired
    private UserService userService;
    @Autowired
    private AppOrderDao appOrderDao;
    private ReentrantReadWriteLock reentrantReadWriteLock=new ReentrantReadWriteLock(true);

    @Transactional
    @Override
    public Result insertShopAuthentication(GoodsShop goodsShop) {
        Msg byPhoneAndCode = msgDao.findByPhoneAndCode(goodsShop.getPhone(), goodsShop.getCode());
        if(byPhoneAndCode==null){
            return Result.error("请输入正确的验证码！");
        }
        GoodsShop goodsShop1 = baseMapper.selectOne(new QueryWrapper<GoodsShop>().eq("user_id", goodsShop.getUserId()));
        if (goodsShop1==null){
            goodsShop.setCreateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            goodsShop.setStatus(0);
            goodsShop.setCashDeposit(0.00);
            baseMapper.insert(goodsShop);
        }else {
            goodsShop.setCreateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            goodsShop.setStatus(0);
            goodsShop.setCashDeposit(0.00);
            goodsShop.setShopId(goodsShop1.getShopId());
            baseMapper.updateById(goodsShop);
            baseMapper.updateAuditReasonIsNull(goodsShop1.getShopId());
        }
        userService.sendMsg(goodsShop.getPhone(),"jieguo");
        return Result.success();
    }

    @Override
    public Result auditShopAuthentication(Long shopId, Integer auditStatus, String auditReason) {
        reentrantReadWriteLock.writeLock().lock();
        try{
            return auditAuthentication(shopId, auditStatus, auditReason);
        }catch (Exception e){
            e.printStackTrace();
            log.error("操作异常："+e.getMessage(),e);
        }finally {
            reentrantReadWriteLock.writeLock().unlock();
        }
        return Result.error("系统繁忙，请稍后再试！");
    }

    @Transactional
    public Result auditAuthentication(Long shopId, Integer auditStatus, String auditReason){
        GoodsShop goodsShop = new GoodsShop();
        goodsShop.setShopId(shopId);
        goodsShop.setStatus(auditStatus);
        goodsShop.setAuditReason(auditReason);
        goodsShop.setAuditTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        goodsShop.setPutawayFlag(1);
        goodsShop.setBannedFlag(0);
        goodsShop.setShopSales(0);
        goodsShop.setShopScore(Double.valueOf(5));
        baseMapper.updateById(goodsShop);
        GoodsShop goodsShop1 = baseMapper.selectById(shopId);
        //管理端审核入驻信息后，发送成功/失败信息给用户
        CommonInfo one = commonInfoService.findOne(12);
        if(auditStatus==1){
            UserEntity userEntity1 = userService.selectUserById(goodsShop1.getUserId());
            SysUserShop sysUserShop = shopAdminDao.selectOne(new QueryWrapper<SysUserShop>().eq("user_id", userEntity1.getAdminUserId()));
            if(sysUserShop!=null){
                sysUserShop.setShopId(shopId);
                shopAdminDao.updateById(sysUserShop);
            }else{
                //添加管理员账号
                SysUserEntity user = sysUserDao.selectOne(new QueryWrapper<SysUserEntity>().eq("username", goodsShop1.getPhone()));
                if(user==null){
                    user = new SysUserEntity();
                    user.setCreateTime(new Date());
                    user.setUsername(goodsShop1.getPhone());
                    user.setPassword(goodsShop1.getPhone());
                    user.setMobile(goodsShop1.getPhone());
                    List<Long> roleIdList = new ArrayList();
                    roleIdList.add(12L);
                    user.setStatus(1);
                    //sha256加密
                    String salt = RandomStringUtils.randomAlphanumeric(20);
                    user.setPassword(new Sha256Hash(user.getPassword(), salt).toHex());
                    user.setSalt(salt);
                    user.setUserType(2);
                    sysUserDao.insertSysUser(user);
                    sysUserRoleService.saveOrUpdate(user.getUserId(), roleIdList);
                    //返回的主键user_id
                    Long userId = user.getUserId();
                    //添加管理员—商铺关联表
                    sysUserShop = new SysUserShop();
                    sysUserShop.setShopId(shopId);
                    sysUserShop.setUserId(userId);
                    shopAdminDao.insert(sysUserShop);
                }
                //todo 绑定用户和管理用户
                UserEntity userEntity = new UserEntity();
                userEntity.setUserId(goodsShop1.getUserId());
                userEntity.setAdminUserId(user.getUserId());
                userEntity.setShopAdminFlag(1);
                userDao.updateById(userEntity);
            }
            userService.sendMsg(goodsShop1.getPhone(),"chenggong");
        }else if(auditStatus==2){
            userService.sendMsg(goodsShop1.getPhone(),"shibai");
        }
        return Result.success();
    }

    /*private Result sendMsgDXB(String phone, String value, Integer type) {
        CommonInfo three = commonInfoService.findOne(164);
        CommonInfo four = commonInfoService.findOne(165);
        String testUsername = three.getValue(); //在短信宝注册的用户名
        String testPassword = four.getValue(); //在短信宝注册的密码
        StringBuilder httpArg = new StringBuilder();
        httpArg.append("u=").append(testUsername).append("&");
        httpArg.append("p=").append(Md5Utils.md5s(testPassword)).append("&");
        httpArg.append("m=").append(phone).append("&");
        httpArg.append("c=").append(Md5Utils.encodeUrlString(value, "UTF-8"));
        String result = Md5Utils.request("https://api.smsbao.com/sms", httpArg.toString());
        log.error("短信包返回值："+result);
        return Result.success();
    }*/

    @Override
    public Result selectShopMessage(Long shopId) {
        GoodsShop goodsShop = selectShopId(shopId);
        return Result.success().put("data", goodsShop);
    }

    @Override
    public GoodsShop selectShopId(Long shopId) {
        GoodsShop goodsShop = baseMapper.selectOne(new QueryWrapper<GoodsShop>().eq("shop_id", shopId));
        if(goodsShop.getShopRate()==null){
            String value = commonInfoService.findOne(300).getValue();
            goodsShop.setShopRate(BigDecimal.valueOf(1).subtract(new BigDecimal(value)));
        }
        return goodsShop;
    }

    @Override
    public Result selectShopList(Integer page, Integer limit, String shopName, Integer status, Integer shopType) {
        Page<GoodsShop> pages = new Page(page, limit);
        PageUtils pageUtils = new PageUtils(goodsShopDao.selectShopList(pages, shopName, status, shopType));
        return Result.success().put("data", pageUtils);
    }

    @Override
    public Result shopEarnings(Long shopId) {
        HashMap<String, Object> hashMap = new HashMap<>();
        String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        BigDecimal shopAllEarnings = goodsShopDao.shopAllEarnings(shopId);
        BigDecimal shopEarningsDay = goodsShopDao.shopEarningsDay(shopId, date);
        BigDecimal shopEarningsMonth = goodsShopDao.shopEarningsMonth(shopId, date);
        hashMap.put("shopAllEarnings", shopAllEarnings);
        hashMap.put("shopEarningsDay", shopEarningsDay);
        hashMap.put("shopEarningsMonth", shopEarningsMonth);
        //用商户id查询用户id
        GoodsShop goodsShop = goodsShopDao.selectOne(new QueryWrapper<GoodsShop>().eq("shop_id", shopId));
        if(goodsShop!=null){
            Double cashMoney= cashOutService.selectCashOutSumsByNowMonth(goodsShop.getUserId());
            hashMap.put("cashMoney", cashMoney);
        }else {
            return Result.error("用户不存在");
        }
        return Result.success().put("data", hashMap);
    }

    @Override
    public Result updateShopMessage(GoodsShop goodsShop) {
        GoodsShop goodsShop1 = goodsShopDao.selectById(goodsShop.getShopId());
        CommonInfo one = commonInfoService.findOne(270);
        if(goodsShop1.getCashDeposit()<Double.parseDouble(one.getValue())){
            return Result.error("保证金不足，不能进行上线操作！");
        }
        if(StringUtils.isNotEmpty(goodsShop.getSnCode())){
            //判断下本次和上次的一样吗 如果一样则不做校验
            if(StringUtils.isNotEmpty(goodsShop1.getSnCode()) && StringUtils.isNotEmpty(goodsShop1.getValue()) ){
                if(!goodsShop1.getSnCode().equals(goodsShop.getSnCode()) || !goodsShop1.getValue().equals(goodsShop.getValue())){
                    String s = addPrinter(goodsShop);
                    if(!"ok".equals(s)){
                        return Result.error(s);
                    }
                    //删除之前的打印机
//                    String snlist = goodsShop1.getSnCode();
//                    FeiYunUtils.deletePrinter(snlist);
                }
            }else{
                String s = addPrinter(goodsShop);
                if(!"ok".equals(s)){
                    return Result.error(s);
                }
            }
        }else{
            //判断之前有没有写过打印机 如果写过 则删除
            if(StringUtils.isNotEmpty(goodsShop1.getSnCode())){
                //删除之前的打印机
//                String snlist = goodsShop1.getSnCode();
//                FeiYunUtils.deletePrinter(snlist);
            }
        }

        baseMapper.updateById(goodsShop);
        return Result.success();
    }


    /**
     * 绑定打印机推送
     *
     * @param goodsShop
     * @return
     */
    public String addPrinter(GoodsShop goodsShop) {
        //目前只有飞鹅pos机可以推送
        if (goodsShop.getFacility()!=null && goodsShop.getFacility().equals(1)) {
            String snlist = goodsShop.getSnCode() + "#" + goodsShop.getValue() + "#" + goodsShop.getShopName();
            String method = FeiYunUtils.addprinter(snlist);
            JSONObject jsonObject = JSON.parseObject(method);
            if (jsonObject != null) {
                if ("0".equals(jsonObject.getString("ret"))) {
                    JSONObject data = jsonObject.getJSONObject("data");
                    JSONArray no = data.getJSONArray("no");
                    if(no.size()>0){
                        String msg = no.getString(0);
                        if(msg.contains("已被添加过")){
                            return "ok";
                        }
                        return no.getString(0);
                    }
                    return "ok";
                }else{
                    return jsonObject.getString("msg");
                }
            }
            return "pos机添加失败！";
        } else {
            return "ok";
        }
    }




    @Override
    public Result shopHomePage(Long shopId, String startTime, String endTime) {
        HashMap<String, Object> hashMap = new HashMap();
        //总收益
        BigDecimal allMoney = goodsShopDao.allMoney(shopId, startTime, endTime);
        //总销量
        int allCount = goodsShopDao.allCount(shopId, startTime, endTime);
        //用户评价
        Double  countTakingByUserId = errandEvaluateDao.selectEvaluateScoreByShopIdAndTime(shopId, startTime, endTime);
        //订单收入
        BigDecimal orderMoney = goodsShopDao.orderMoney(shopId, startTime, endTime);
        //总订单数
        int sumCountOrder = goodsShopDao.sumCountOrder(shopId, startTime, endTime);
        //退款金额
        BigDecimal refundMoney = goodsShopDao.refundMoney(shopId, startTime, endTime);
        //访客人数
        Integer countByUserId = userBrowseDao.selectCount(new QueryWrapper<UserBrowse>().eq("by_browse_id", shopId));
        //待付款
        int i1 = goodsShopDao.selectCountOrder(shopId, startTime, endTime, 1);
        //制作中
        int i2 = goodsShopDao.selectCountOrder(shopId, startTime, endTime, 6);
        //待取餐
        int i3 = goodsShopDao.selectCountOrder(shopId, startTime, endTime, 3);
        //已完成
        int i4 = goodsShopDao.selectCountOrder(shopId, startTime, endTime, 4);
        //商家待接单
        int i5 = goodsShopDao.selectCountOrder(shopId, startTime, endTime, 7);
        //上架中
        int putawayCount = goodsShopDao.putawayCount(shopId);
        //已下架
        int soldoutCount = goodsShopDao.soldoutCount(shopId);
        hashMap.put("allMoney", allMoney);
        hashMap.put("allCount", allCount);
        hashMap.put("总用户数", null);
        hashMap.put("orderMoney", orderMoney);
        hashMap.put("sumCountOrder", sumCountOrder);
        hashMap.put("refundMoney", refundMoney);
        hashMap.put("访客人数", null);
        hashMap.put("i1", i1);
        hashMap.put("i2", i2);
        hashMap.put("i3", i3);
        hashMap.put("i4", i4);
        hashMap.put("i5", i5);
        hashMap.put("putawayCount", putawayCount);
        hashMap.put("soldoutCount", soldoutCount);
        hashMap.put("countTakingByUserId", countTakingByUserId);
        hashMap.put("countByUserId", countByUserId);
        return Result.success().put("data", hashMap);
    }

    @Transactional
    @Override
    public Result shopRefundCashDeposit(Long shopId) {
        Integer count = appOrderDao.selectCount(new QueryWrapper<TbOrder>().in("status", 3, 6, 7).eq("shop_id", shopId));
        if(count>0){
            return Result.error("当前有未完成的订单，请完成之后进行操作！");
        }
        GoodsShop goodsShop = shopMessageDao.selectById(shopId);
        if(goodsShop.getCashDeposit()<=0){
            return Result.error("你的保证金余额为0，无法退保证金！");
        }
        userMoneyDao.addMoney(goodsShop.getUserId(), BigDecimal.valueOf(goodsShop.getCashDeposit()));
        GoodsShop goodsShop1 = new GoodsShop();
        goodsShop1.setShopId(shopId);
        goodsShop1.setCashDeposit(0.00);
        goodsShop1.setPutawayFlag(1);
        shopMessageDao.updateById(goodsShop1);
        //商户退保证金钱包明细
        UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
        userMoneyDetails.setShopId(shopId);
        userMoneyDetails.setTitle("商户退保证金");
        userMoneyDetails.setType(2);
        userMoneyDetails.setClassify(2);
        userMoneyDetails.setState(2);
        userMoneyDetails.setMoney(BigDecimal.valueOf(goodsShop.getCashDeposit()));
        userMoneyDetails.setContent("商户退保证金："+goodsShop.getCashDeposit()+"元");
        userMoneyDetails.setCreateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        userMoneyDetailsDao.insert(userMoneyDetails);
        UserMoneyDetails userMoneyDetails1 = new UserMoneyDetails();
        userMoneyDetails1.setShopId(shopId);
        userMoneyDetails1.setTitle("商户退保证金");
        userMoneyDetails1.setType(1);
        userMoneyDetails1.setClassify(3);
        userMoneyDetails1.setState(2);
        userMoneyDetails1.setMoney(BigDecimal.valueOf(goodsShop.getCashDeposit()));
        userMoneyDetails1.setContent("商户退保证金："+goodsShop.getCashDeposit()+"元，已退回至钱包账户");
        userMoneyDetails1.setCreateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        userMoneyDetailsDao.insert(userMoneyDetails1);
        return Result.success();
    }

    @Override
    public Result userFeedback(Feedback feedback) {
        String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        shopMessageDao.userFeedback(feedback.getShopId(), feedback.getUserEmail(), feedback.getFeedbackScore(), feedback.getFeedbackMessage(), format);
        return Result.success();
    }

    @Override
    public Result selectShopAuthentication(String phone, String msg) {
        Msg byPhone = msgDao.findByPhoneAndCode(phone, msg);
        if(null==byPhone){
            return Result.error("验证码错误！");
        }
        msgDao.deleteById(byPhone.getId());
        GoodsShop goodsShop = shopMessageDao.selectShopAuthentication(phone);
        return Result.success().put("data", goodsShop);
    }

    @Override
    public Result selectShopByUserId(Long userId) {
        GoodsShop goodsShop = shopMessageDao.selectShopByUserId(userId);
        return Result.success().put("data", goodsShop);
    }

    @Override
    public Result selectComplaint(Long shopId, Integer page, Integer limit) {
        Page<ErrandComplaint> pages = new Page<>(page, limit);
        IPage<ErrandComplaint> errandComplaintIPage = errandComplaintDao.selectComplaint(pages, shopId);
        PageUtils pageUtils = new PageUtils(errandComplaintIPage);
        return Result.success().put("data", pageUtils);
    }

    @Override
    public Result updateShopCashDeposit(Long shopId, BigDecimal money, Integer type) {
        goodsShopDao.updateShopCashDeposit(shopId, money, type);
        UserMoneyDetails userMoneyDetails = new UserMoneyDetails();
        userMoneyDetails.setMoney(money);
        userMoneyDetails.setShopId(shopId);
        if(type.equals(1)){
            userMoneyDetails.setContent("赠送商户保证金："+money+"元");
            userMoneyDetails.setTitle("系统赠送商户保证金");
        }else if(type.equals(2)){
            userMoneyDetails.setContent("扣除商户保证金："+money+"元");
            userMoneyDetails.setTitle("系统扣除商户保证金");
        }
        userMoneyDetails.setType(type);
        userMoneyDetails.setClassify(2);
        userMoneyDetails.setState(2);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        userMoneyDetails.setCreateTime(simpleDateFormat.format(new Date()));
        userMoneyDetailsService.save(userMoneyDetails);
        return Result.success();
    }

    @Override
    public Result selectShopCashDepositList(Integer page, Integer limit, Long shopId) {
        Page<UserMoneyDetails> pages = new Page<>(page, limit);
        PageUtils pageUtils = new PageUtils(userMoneyDetailsDao.selectShopCashDepositList(pages, shopId));
        return Result.success().put("data", pageUtils);
    }

    @Override
    public Result sendMsgs(String phone, String state) {
        return userService.sendMsg(phone,"ruzhu");
    }

    @Override
    public Result sendMsg(String phone, String state) {
        GoodsShop goodsShop = shopMessageDao.selectShopAuthentication(phone);
        if(goodsShop==null){
            return Result.error("该手机号未申请入驻商铺！");
        }
        CommonInfo name = commonInfoService.findOne(12);
        return userService.sendMsg(goodsShop.getPhone(),"ruzhu");
    }


}
