package com.xinxincaravan.caravan.vehicle.biz;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.wxiaoqi.security.common.exception.BaseException;
import com.xinxincaravan.caravan.vehicle.common.RestResponse;
import com.xinxincaravan.caravan.vehicle.constant.BranchCompanyStockApplyState;
import com.xinxincaravan.caravan.vehicle.constant.RedisKey;
import com.xinxincaravan.caravan.vehicle.constant.ResCode.ResCode;
import com.xinxincaravan.caravan.vehicle.entity.BranchCompanyStockApplyInfo;
import com.xinxincaravan.caravan.vehicle.entity.BranchCompanyStockInfo;
import com.xinxincaravan.caravan.vehicle.mapper.BranchCompanyMapper;
import com.xinxincaravan.caravan.vehicle.mapper.BranchCompanyStockApplyInfoMapper;
import com.xinxincaravan.caravan.vehicle.mapper.BranchCompanyStockInfoMapper;
import com.xinxincaravan.caravan.vehicle.mapper.SysRegionMapper;
import com.xinxincaravan.caravan.vehicle.util.excel.ExcelImport;
import com.xinxincaravan.caravan.vehicle.vo.BranchCompanyStockApplyInfoVo;
import com.xinxincaravan.caravan.vehicle.vo.BranchCompanyStockApplyVo;
import com.xinxincaravan.caravan.vehicle.vo.BranchCompanyStockInfoVo;
import com.xinxincaravan.caravan.vehicle.vo.BranchCompanyStockSearchVo;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class BranchCompanyStockService {


    public static final DateTimeFormatter DEFAULT_DATE_TIME_FORMATTER = DateTimeFormat.forPattern("yyyy-MM-dd");
    public static final DateTimeFormatter YEARMONTH_DATE_TIME_FORMATTER = DateTimeFormat.forPattern("yyyy-MM");

    @Value("${branchCompanyStockPic.baseUploadPath:/data/branchCompanyStock/upload/}")
    private String baseUploadPath;

    @Autowired
    private RedisTemplate customRedisTemplate;

    @Autowired
    BranchCompanyStockInfoMapper branchCompanyStockInfoMapper;

    @Autowired
    BranchCompanyMapper branchCompanyMapper;

    @Autowired
    BranchCompanyStockApplyInfoMapper branchCompanyStockApplyInfoMapper;
    @Autowired
    SysRegionMapper sysRegionMapper;

    public PageInfo<BranchCompanyStockInfoVo> selectAll(Integer page, Integer limit) {
        PageHelper.startPage(page, limit);
        return new PageInfo<>(branchCompanyStockInfoMapper.selectVoAll());
    }

    public PageInfo<BranchCompanyStockInfoVo> search(BranchCompanyStockSearchVo searchVo) {
        PageHelper.startPage(searchVo.getPage(), searchVo.getLimit());
        return new PageInfo<>(branchCompanyStockInfoMapper.search(searchVo));
    }

    public void insert(BranchCompanyStockInfoVo stockInfoVo) {
        BranchCompanyStockInfo stockInfo = new BranchCompanyStockInfo();
        BeanUtils.copyProperties(stockInfoVo, stockInfo);
        if (stockInfo.getBalance() == null) {
            stockInfo.setBalance(stockInfo.getTotal());
        }
        if (stockInfoVo.getState() == null) {
            stockInfo.setState(0);
        }
        branchCompanyStockInfoMapper.insert(stockInfo);
    }


    public void update(BranchCompanyStockInfoVo stockInfoVo) {
        BranchCompanyStockInfo stockInfo = new BranchCompanyStockInfo();
        BeanUtils.copyProperties(stockInfoVo, stockInfo);
        branchCompanyStockInfoMapper.updateByPrimaryKeySelective(stockInfo);
    }


    /**
     * 申请购买
     * @param applyVo
     */
    public void apply(BranchCompanyStockApplyVo applyVo) {
        BranchCompanyStockInfo stockInfo = branchCompanyStockInfoMapper.selectByPrimaryKey(applyVo.getCompanyId());
        if (stockInfo == null) {
            throw new BaseException(ResCode.BRANCH_COMPANY_STOCK_UNEXIST.getDesc(), ResCode.BRANCH_COMPANY_STOCK_UNEXIST.getCode());
        }
        if (stockInfo.getBalance() <= 0) {
            throw new BaseException(ResCode.BRANCH_COMPANY_STOCK_NO_BALANCE.getDesc(), ResCode.BRANCH_COMPANY_STOCK_NO_BALANCE.getCode());
        }
        if (stockInfo.getBalance() < applyVo.getCount()) {
            throw new BaseException(ResCode.BRANCH_COMPANY_STOCK_BALANCE_NOT_ENOUGH.getDesc(), ResCode.BRANCH_COMPANY_STOCK_BALANCE_NOT_ENOUGH.getCode());
        }
        BranchCompanyStockApplyInfo applyInfo = new BranchCompanyStockApplyInfo();
        BeanUtils.copyProperties(applyVo, applyInfo);
        applyInfo.setState(BranchCompanyStockApplyState.Apply.getCode());
        applyInfo.setCreateTime(new Date());
        branchCompanyStockApplyInfoMapper.insertSelective(applyInfo);
    }

    public PageInfo<BranchCompanyStockApplyInfoVo> selectApplyAll(Integer page, Integer limit) {
        PageHelper.startPage(page, limit);
        return new PageInfo<>(branchCompanyStockApplyInfoMapper.selectVoAll());
    }

    /**
     * 取消申请,修改申请状态
     * @param applyId
     */
    public void cancelApply(Integer applyId) {
        BranchCompanyStockApplyInfo applyInfo = branchCompanyStockApplyInfoMapper.selectByPrimaryKey(applyId);
        if (applyInfo == null) {
            throw new BaseException(ResCode.BRANCH_COMPANY_STOCK_APPLY_INFO_UNEXIST.getDesc(),
                    ResCode.BRANCH_COMPANY_STOCK_APPLY_INFO_UNEXIST.getCode());
        }
        applyInfo.setState(BranchCompanyStockApplyState.Cancel.getCode());
        applyInfo.setUpdateTime(new Date());
        branchCompanyStockApplyInfoMapper.updateByPrimaryKey(applyInfo);
    }

    /**
     * 确认申请购买股权，修改库存
     * @param applyId
     */
    @Transactional
    public void buy(Integer applyId) {
        BranchCompanyStockApplyInfo applyInfo = branchCompanyStockApplyInfoMapper.selectByPrimaryKey(applyId);
        if (applyInfo == null) {
            throw new BaseException(ResCode.BRANCH_COMPANY_STOCK_APPLY_INFO_UNEXIST.getDesc(),
                    ResCode.BRANCH_COMPANY_STOCK_APPLY_INFO_UNEXIST.getCode());
        }
        if (!applyInfo.getState().equals(BranchCompanyStockApplyState.Apply.getCode())) {
            throw new BaseException(ResCode.BRANCH_COMPANY_STOCK_APPLY_INFO_STATE_LOCKED.getDesc(),
                    ResCode.BRANCH_COMPANY_STOCK_APPLY_INFO_STATE_LOCKED.getCode());
        }

        BranchCompanyStockInfo stockInfo = branchCompanyStockInfoMapper.selectByPrimaryKey(applyInfo.getCompanyId());
        if (stockInfo == null) {
            throw new BaseException(ResCode.BRANCH_COMPANY_STOCK_UNEXIST.getDesc(), ResCode.BRANCH_COMPANY_STOCK_UNEXIST.getCode());
        }

        if (stockInfo.getBalance() < applyInfo.getCount()) {
            throw new BaseException(ResCode.BRANCH_COMPANY_STOCK_BALANCE_NOT_ENOUGH.getDesc(), ResCode.BRANCH_COMPANY_STOCK_BALANCE_NOT_ENOUGH.getCode());
        }

        int result = branchCompanyStockInfoMapper.updateBalance(applyInfo.getCompanyId(), stockInfo.getBalance() - applyInfo.getCount(), stockInfo.getBalance());
        if (result == 0) {
            throw new BaseException(ResCode.BRANCH_COMPANY_STOCK_BALANCE_NOT_ENOUGH.getDesc(), ResCode.BRANCH_COMPANY_STOCK_BALANCE_NOT_ENOUGH.getCode());
        }

        applyInfo.setState(BranchCompanyStockApplyState.Buy.getCode());
        applyInfo.setUpdateTime(new Date());
        branchCompanyStockApplyInfoMapper.updateByPrimaryKey(applyInfo);
    }

    /**
     * 获取所有的股权单价
     * @return
     */
    public List<Integer> getAllPrice() {
        return branchCompanyStockInfoMapper.selectAllPrice();
    }


    public BranchCompanyStockInfo selectById(Integer id) {
        return branchCompanyStockInfoMapper.selectByPrimaryKey(id);
    }

    public void delete(Integer id) {
        branchCompanyStockInfoMapper.deleteByPrimaryKey(id);
    }

    public BranchCompanyStockApplyInfo getApplyById(Integer id) {
        return branchCompanyStockApplyInfoMapper.selectByPrimaryKey(id);
    }

    public void updateApply(BranchCompanyStockApplyInfo applyInfo) {
        branchCompanyStockApplyInfoMapper.updateByPrimaryKeySelective(applyInfo);
    }

    public void deleteApply(Integer id) {
        branchCompanyStockApplyInfoMapper.deleteByPrimaryKey(id);
    }

    /**
     * 写入上传文件，返回相对路径
     * @param file
     * @return
     */
    public RestResponse<String> uploadCompanyPic(MultipartFile file) throws Exception{
        //创建本日存放目录
        DateTime now = DateTime.now();
        String dirPathToday =  File.separator + now.toString(DEFAULT_DATE_TIME_FORMATTER);
        String redisNoKey = RedisKey.UPLOAD_FILE_NO_PREFIX + now.toString(DEFAULT_DATE_TIME_FORMATTER);
        Long no = customRedisTemplate.opsForValue().increment(redisNoKey);
        if(no.equals(1l)){
            customRedisTemplate.expire(redisNoKey,1, TimeUnit.DAYS);
        }
        String fileName = file.getOriginalFilename();
        String realFileRelPath = dirPathToday + File.separator + no + fileName.substring(fileName.lastIndexOf("."));
        //文件存放路径
        String filePath = baseUploadPath + realFileRelPath;
        //将文件写入指定位置
        FileUtils.copyInputStreamToFile(file.getInputStream(), new File(filePath));
        return RestResponse.suc(realFileRelPath);
    }

    public ResponseEntity<byte[]> downloadCompanyPic(String realFileRelPath) throws IOException {
        String filePath = baseUploadPath + realFileRelPath;
        File file = new File(filePath);//新建一个文件
        HttpHeaders headers = new HttpHeaders();//http头信息
        String downloadFileName = new String(file.getName());//设置编码
        headers.setContentDispositionFormData("attachment", downloadFileName);
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),headers, HttpStatus.CREATED);
    }

    public RestResponse<String> importExcel(MultipartFile multipartfile, HttpServletRequest request){
        try {
            List<String[]> readExcel = ExcelImport.getExcelData(multipartfile);
            if(readExcel.size()<4){
                return RestResponse.codeAndMessage(1001,"导入不能没数据！！！");
            }
            List<BranchCompanyStockInfo> list=new ArrayList<>();
           for (int i = 3; i < readExcel.size(); i++) {
               BranchCompanyStockInfo stockInfoVo=new BranchCompanyStockInfo();
                String[] str = readExcel.get(i);
                String province = str[2];
                String city = str[3];
                Integer addr_province=sysRegionMapper.getNumber(province);
               Integer addr_city=sysRegionMapper.getNumber(city);
                String company_name = str[5];
                String str6=str[6];
                if(StringUtils.isNotBlank(str6)){
                    if(str6.contains("万港币/股")){
                        str6=str6.replace("万港币/股","");
                    }else {
                        str6=str6.replace("万/股","");
                    }

                }else{
                    str6="0";
                }
                BigDecimal price = new BigDecimal(str6);
                price=price.multiply(new BigDecimal("10000"));
                Integer balance = Integer.parseInt(str[8]);
                Integer total =Integer.parseInt(str[7])+balance;
                stockInfoVo.setCompanyName(company_name);
                stockInfoVo.setPrice(price);
                stockInfoVo.setBalance(balance);
                stockInfoVo.setTotal(total);
                stockInfoVo.setState(2);
                stockInfoVo.setAddrProvince(addr_province);
                stockInfoVo.setAddrCity(addr_city);
                stockInfoVo.setCompanyPic("/2019-04-30/2.jpg");
                list.add(stockInfoVo);
               //branchCompanyStockInfoMapper.insertSelective(stockInfoVo);
            }
               branchCompanyStockInfoMapper.addCompamyList(list);
        }catch (Exception e){
            e.printStackTrace();
            return RestResponse.codeAndMessage(10001,"网络异常！");
        }
        return RestResponse.suc();
    }

    public String getInfoById(Integer id) {
        return branchCompanyStockInfoMapper.selectInfoById(id);
    }
}
