/*
*  Copyright 2019-2020 Zheng Jie
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package cn.ysk.cashier.service.impl.shopimpl;

import cn.ysk.cashier.config.security.security.TokenProvider;
import cn.ysk.cashier.config.security.service.UserCacheManager;
import cn.ysk.cashier.dto.shop.TbShopInfoDto;
import cn.ysk.cashier.dto.shop.TbShopInfoQueryCriteria;
import cn.ysk.cashier.exception.BadRequestException;
import cn.ysk.cashier.exception.EntityNotFoundException;
import cn.ysk.cashier.mapper.shop.TbShopInfoMapper;
import cn.ysk.cashier.pojo.shop.TbMerchantAccount;
import cn.ysk.cashier.pojo.shop.TbMerchantRegister;
import cn.ysk.cashier.pojo.shop.TbPlussShopStaff;
import cn.ysk.cashier.pojo.shop.TbShopInfo;
import cn.ysk.cashier.repository.TbShopPayTypeRepository;
import cn.ysk.cashier.repository.shop.*;
import cn.ysk.cashier.service.shop.TbShopInfoService;
import cn.ysk.cashier.system.domain.Dept;
import cn.ysk.cashier.system.domain.Job;
import cn.ysk.cashier.system.domain.Role;
import cn.ysk.cashier.system.domain.User;
import cn.ysk.cashier.system.repository.UserRepository;
import cn.ysk.cashier.system.service.UserService;
import cn.ysk.cashier.utils.*;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.Instant;
import java.util.*;

/**
* @website https://eladmin.vip
* @description 服务实现
* @author lyf
* @date 2023-11-07
**/
@Service
@RequiredArgsConstructor
public class TbShopInfoServiceImpl implements TbShopInfoService {

    private final TbShopInfoRepository tbShopInfoRepository;
    @Resource
    private TbShopInfoMapper tbShopInfoMapper;

    private final TbMerchantAccountRepository merchantAccountRepository;

    private final UserRepository userRepository;

    private final UserService userService;

    private final UserCacheManager userCacheManager;
    private final TokenProvider tokenProvider;

    private final TbMerchantRegisterRepository merchantRegisterRepository;

    private final PasswordEncoder passwordEncoder;

    private final TbPlussShopStaffRepository shopStaffRepository;

    private final RedisUtils redisUtils;

    private final TbShopPayTypeRepository tbShopPayTypeRepository;

    @Override
    public Map<String,Object> queryAll(TbShopInfoQueryCriteria criteria){
        Sort sort = Sort.by(Sort.Direction.DESC, "id");
        Pageable pageables = PageRequest.of(criteria.getPage(), criteria.getSize(), sort);
        Page<TbShopInfo> page = tbShopInfoRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageables);
        return PageUtil.toPage(page);
    }

//    @Override
//    public List<TbShopInfoDto> queryAll(TbShopInfoQueryCriteria criteria){
//        return tbShopInfoMapper.toDto(tbShopInfoRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
//    }

    @Override
    @Transactional
    public TbShopInfoDto findById(Integer id) {
        TbShopInfo tbShopInfo = tbShopInfoRepository.findById(id).orElseGet(TbShopInfo::new);
        ValidationUtil.isNull(tbShopInfo.getId(),"TbShopInfo","id",id);
        return tbShopInfoMapper.toDto(tbShopInfo);
    }

    @Override
    public TbShopInfo findByIdInfo(Integer id) {
        TbShopInfo tbShopInfo = tbShopInfoRepository.findById(id).orElseGet(TbShopInfo::new);
        return tbShopInfo;
    }

    @Override
    public TbShopInfoDto finByAccount(String account) {
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TbShopInfoDto create(TbShopInfoDto resources) {
        if ("release".equals(resources.getProfiles())){
            if (resources.getRegisterCode() == null){
                throw new BadRequestException("未绑定激活码");
            }
        }
        TbShopInfo byAccount = tbShopInfoRepository.findByAccount(resources.getAccount());
        User byUsername = userRepository.findByUsername(resources.getAccount());
        if (byAccount != null || byUsername != null){
            throw new BadRequestException("登录名已注册");
        }

        TbShopInfo tbShopInfo = new TbShopInfo();
        BeanUtils.copyProperties(resources,tbShopInfo);
        tbShopInfo.setCreatedAt(Instant.now().toEpochMilli());
        tbShopInfo.setUpdatedAt(Instant.now().toEpochMilli());
        tbShopInfo.setOnSale(1);
        tbShopInfo.setIsOpenYhq(resources.getIsOpenYhq());
        //激活码
        TbMerchantRegister tbMerchantRegister = new TbMerchantRegister();
        if (resources.getRegisterCode() != null){
            tbMerchantRegister = merchantRegisterRepository.findByRegisterCode(resources.getRegisterCode());
            if(tbMerchantRegister == null){
                throw new BadRequestException("激活码有误");
            }
            if (tbMerchantRegister.getStatus() == 1){
                throw new BadRequestException("激活码已激活，不能重复绑定");
            }
            tbShopInfo.setExpireAt(DateUtil.addMonthsAndGetTimestamp(tbMerchantRegister.getPeriodYear()));
            //向redis中存入key
            redisUtils.set(CacheKey.ACT_CODE+resources.getAccount(),"1",tbShopInfo.getExpireAt()-Instant.now().toEpochMilli());
        }
        //增加商户详情
        TbShopInfo save = tbShopInfoRepository.save(tbShopInfo);
        if (resources.getRegisterCode() != null) {
            //激活码绑定
            tbMerchantRegister.setStatus(1);
            tbMerchantRegister.setShopId(String.valueOf(save.getId()));
            tbMerchantRegister.setName(save.getShopName());
            merchantRegisterRepository.save(tbMerchantRegister);
        }
        //增加商户登录账号
        TbMerchantAccount tbMerchantAccount = new TbMerchantAccount();
        tbMerchantAccount.setAccount(resources.getAccount());
        tbMerchantAccount.setPassword(MD5Utils.encrypt(resources.getPassword()));
        tbMerchantAccount.setShopId(String.valueOf(save.getId()));
        tbMerchantAccount.setIsAdmin(0);
        tbMerchantAccount.setIsMercantile(0);
        tbMerchantAccount.setStatus(1);
        tbMerchantAccount.setMsgAble(0);
        TbMerchantAccount save1 = merchantAccountRepository.save(tbMerchantAccount);
        //绑定accountId
        tbShopInfo.setMerchantId(String.valueOf(save1.getId()));
        tbShopInfoRepository.save(tbShopInfo);

        //添加收银系统后台账号
        User user = new User();
        user.setPassword(passwordEncoder.encode(resources.getPassword()));
        user.setUsername(resources.getAccount());
        user.setNickName(resources.getShopName());
        user.setPhone(resources.getPhone());
        user.setCreateBy("admin");
        user.setEnabled(true);

        Dept dept = new Dept();
        dept.setId(18L);
        user.setDept(dept);

        Set<Role> roles = new HashSet<>();
        Role role = new Role();
        role.setId(2L);
        roles.add(role);
        user.setRoles(roles);

        Set<Job> jobs = new HashSet<>();
        Job job = new Job();
        job.setId(10L);
        jobs.add(job);
        user.setJobs(jobs);
        userRepository.save(user);

        //增加员工表中的员工
        TbPlussShopStaff tbPlussShopStaff = new TbPlussShopStaff();
        tbPlussShopStaff.setShopId(String.valueOf(save.getId()));
        tbPlussShopStaff.setType("master");
        tbPlussShopStaff.setName(resources.getShopName());
        tbPlussShopStaff.setAccount(resources.getAccount());
        tbPlussShopStaff.setPassword(MD5Utils.encrypt(resources.getPassword()));
        tbPlussShopStaff.setStatus(1);
        tbPlussShopStaff.setCreatedAt(Instant.now().toEpochMilli());
        tbPlussShopStaff.setUpdatedAt(Instant.now().toEpochMilli());
        tbPlussShopStaff.setCode(save.getPhone());
        shopStaffRepository.save(tbPlussShopStaff);
        //增加默认支付方式
        Integer integer = tbShopPayTypeRepository.creatPayType(save.getId().toString());
        if (integer<4){
            throw new BadRequestException("请重试");
        }

        return tbShopInfoMapper.toDto(new TbShopInfo());
    }

    @Override
    @Transactional
    public void upShopPass(String username,String password){
        User user = userRepository.findByUsername(username);
        if (user == null) {
            throw new EntityNotFoundException(User.class, "username", username);
        }
        String encPass = MD5Utils.encrypt(password);
        shopStaffRepository.updatePass(username,encPass,System.currentTimeMillis());
        merchantAccountRepository.updatePass(username,encPass,System.currentTimeMillis());
//        passwordEncoder.encode(passwordEncoder.encode(password))
        userService.updatePass(username,passwordEncoder.encode(password));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(TbShopInfo resources) {
        TbShopInfo tbShopInfo = tbShopInfoRepository.findById(resources.getId()).orElseGet(TbShopInfo::new);
        if (!resources.getShopName().equals(tbShopInfo.getShopName())) {
            shopStaffRepository.updateNameById(resources.getShopName(),resources.getId().toString());
            userRepository.updateNickName(resources.getAccount(),resources.getShopName());
        }
        ValidationUtil.isNull( tbShopInfo.getId(),"TbShopInfo","id",resources.getId());
        tbShopInfo.copy(resources);
        tbShopInfo.setUpdatedAt(Instant.now().toEpochMilli());
        tbShopInfoRepository.save(tbShopInfo);
    }

    @Override
    public void updateShopId(TbShopInfo resources) {
        TbShopInfo tbShopInfo = tbShopInfoRepository.findById(resources.getId()).orElseGet(TbShopInfo::new);
        ValidationUtil.isNull( tbShopInfo.getId(),"TbShopInfo","id",resources.getId());
        tbShopInfo.copy(resources);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(String account) {
        tbShopInfoRepository.updateByAcc(account);
    }

    @Override
    public void deleteAll(Integer[] ids) {
        for (Integer id : ids) {
            tbShopInfoRepository.deleteById(id);
        }
    }

    @Override
    public void download(List<TbShopInfoDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (TbShopInfoDto tbShopInfo : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("店铺帐号", tbShopInfo.getAccount());
            map.put("店铺代号，策略方式为city +店铺号（8位）", tbShopInfo.getShopCode());
            map.put("店铺口号", tbShopInfo.getSubTitle());
            map.put("商户Id", tbShopInfo.getMerchantId());
            map.put("店铺名称", tbShopInfo.getShopName());
            map.put("连锁店扩展店名", tbShopInfo.getChainName());
            map.put("背景图", tbShopInfo.getBackImg());
            map.put("门头照", tbShopInfo.getFrontImg());
            map.put("联系人姓名", tbShopInfo.getContactName());
            map.put("联系电话", tbShopInfo.getPhone());
            map.put("店铺log", tbShopInfo.getLogo());
            map.put("是否参与代收 0--不参与  1参与 ", tbShopInfo.getIsDeposit());
            map.put("是否为供应商", tbShopInfo.getIsSupply());
            map.put("封面图", tbShopInfo.getCoverImg());
            map.put("店铺分享图", tbShopInfo.getShareImg());
            map.put("轮播图", tbShopInfo.getView());
            map.put("店铺简介", tbShopInfo.getDetail());
            map.put("经纬度", tbShopInfo.getLat());
            map.put("经纬度", tbShopInfo.getLng());
            map.put("未用", tbShopInfo.getMchId());
            map.put(" registerType",  tbShopInfo.getRegisterType());
            map.put("是否独立的微信小程序", tbShopInfo.getIsWxMaIndependent());
            map.put("详细地址", tbShopInfo.getAddress());
            map.put("类似于这种规则51.51.570", tbShopInfo.getCity());
            map.put("店铺类型 超市--MARKET---其它店SHOP", tbShopInfo.getType());
            map.put("行业", tbShopInfo.getIndustry());
            map.put("行业名称", tbShopInfo.getIndustryName());
            map.put("营业时间", tbShopInfo.getBusinessTime());
            map.put("配送时间", tbShopInfo.getPostTime());
            map.put(" postAmountLine",  tbShopInfo.getPostAmountLine());
            map.put("0停业1，正常营业,网上售卖", tbShopInfo.getOnSale());
            map.put("0今日，1次日", tbShopInfo.getSettleType());
            map.put("时间", tbShopInfo.getSettleTime());
            map.put("入驻时间", tbShopInfo.getEnterAt());
            map.put("到期时间", tbShopInfo.getExpireAt());
            map.put("门店状态", tbShopInfo.getStatus());
            map.put("人均消费", tbShopInfo.getAverage());
            map.put("订单等待时间", tbShopInfo.getOrderWaitPayMinute());
            map.put("支持登陆设备个数", tbShopInfo.getSupportDeviceNumber());
            map.put("分销层级（1-下级分销 2-两下级分销）", tbShopInfo.getDistributeLevel());
            map.put(" createdAt",  tbShopInfo.getCreatedAt());
            map.put(" updatedAt",  tbShopInfo.getUpdatedAt());
            map.put(" proxyId",  tbShopInfo.getProxyId());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }
}