package com.huiju.estateagents.property.service.impl;

import com.alibaba.fastjson.JSONObject;
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.huiju.estateagents.base.ResponseBean;
import com.huiju.estateagents.center.taUser.entity.TaUser;
import com.huiju.estateagents.center.taUser.mapper.TaUserMapper;
import com.huiju.estateagents.property.common.UserElement;
import com.huiju.estateagents.property.dao.*;
import com.huiju.estateagents.property.exception.WisdomException;
import com.huiju.estateagents.property.model.*;
import com.huiju.estateagents.property.service.IBillInvoiceService;
import com.huiju.estateagents.property.service.IMessageService;
import com.google.common.collect.Maps;
import org.apache.poi.hssf.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.stream.Collectors;

/**
 * <p>
 * 缴费单 服务实现类
 * </p>
 *
 * @author weiximei
 * @since 2019-02-13
 */
@Service
public class BillInvoiceServiceImpl extends ServiceImpl<BillInvoiceMapper, BillInvoice> implements IBillInvoiceService {

    /** 缴费项表 **/
    @Autowired
    private BillMapper billMapper;

    /** 缴费单 **/
    @Autowired
    private BillInvoiceMapper billInvoiceMapper;

    /** 账单流水表 **/
    @Autowired
    private BillStatementMapper billStatementMapper;

    @Autowired
    private TpBuildingOwnerInfoMapper tpBuildingOwnerInfoMapper;

    @Autowired
    private TaUserMapper taUserMapper;

    @Autowired
    private IMessageService iMessageService;

    @Autowired
    private TpRoomNoMapper tpRoomNoMapper;

    @Autowired
    private TaUserVerifyMapper taUserVerifyMapper;

    @Autowired
    private TpBillOrderMapper tpBillOrderMapper;

    @Override
    public ResponseBean getBillList(String parameter, TaUser userElement) {
        ResponseBean responseBean = new ResponseBean();
        JSONObject jsonObject = JSONObject.parseObject(parameter);

        Integer pageNum = jsonObject.getInteger("pageNum");
        Integer pageSize = jsonObject.getInteger("pageSize");
        // 缴费项ID
        Integer billId = jsonObject.getInteger("billId");
        // 期
        String phase = jsonObject.getString("phase");
        // 栋
        String building = jsonObject.getString("building");
        // 单元
        String unit = jsonObject.getString("unit");
        // 户号
        String roomNo = jsonObject.getString("roomNo");
        // 业主姓名
        String ownerName = jsonObject.getString("ownerName");
        // 缴费状态
        Integer billStatus = jsonObject.getInteger("billStatus");
        // 缴费人姓名
        String payName = jsonObject.getString("payName");

        Map<String, Object> map = Maps.newHashMap();
        map.put("billId", billId);
        map.put("phase", phase);
        map.put("building", building);
        map.put("unit", unit);
        map.put("roomNo", roomNo);
        map.put("ownerName", ownerName);
        map.put("billStatus", billStatus);
        map.put("payName", payName);
        map.put("communityId", userElement.getOrgId());


        Page<BillInvoice> page = new Page<>();
        page.setCurrent(pageNum);
        page.setSize(pageSize);
        IPage<BillInvoice> invoiceIPage = billInvoiceMapper.selectBillInvoice(page, map);

        // 缴费项目
        Bill bill = billMapper.selectById(billId);

        Map<String, Object> respMap = Maps.newHashMap();
        respMap.put("pageNum", invoiceIPage.getCurrent());
        respMap.put("pageSize", invoiceIPage.getSize());
        respMap.put("total", invoiceIPage.getTotal());
        respMap.put("list", invoiceIPage.getRecords());
        respMap.put("billName", bill.getBillName());
        respMap.put("billExplain", bill.getBillExplain());
        respMap.put("endDate", bill.getEndDate());

        responseBean.addSuccess(respMap);

        return responseBean;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseBean deleteBillInvoice(List<Integer> ids, TaUser userElement) {
        ResponseBean responseBean = new ResponseBean();
        if (null == userElement) {
            responseBean.addError("请登录后操作");
            return responseBean;
        }

        ids.stream().forEach(e -> {
            BillInvoice billInvoice = billInvoiceMapper.selectById(e);
            if (!"0".equals(billInvoice.getBillStatus())) {
                throw new WisdomException("费用已缴，无法删除");
            }
            billInvoiceMapper.deleteById(e);
            Bill bill = billMapper.selectById(billInvoice.getBillId());
            bill.setPayTotalNum(bill.getPayTotalNum() - 1);
            bill.setUnpayedNum(bill.getUnpayedNum() - 1);
            if (bill.getPayTotalNum() <= 0) {
                bill.setPayTotalNum(0);
            }
            if (bill.getUnpayedNum() <= 0) {
                bill.setBillStatus("1");
                bill.setUnpayedNum(0);
            }
            billMapper.updateById(bill);
        });

        responseBean.addSuccess("操作成功");
        return responseBean;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseBean offlinePayment(List<Integer> ids, TaUser userElement) {
        ResponseBean responseBean = new ResponseBean();
        if (null == userElement) {
            responseBean.addError("请登录后操作");
            return responseBean;
        }

        ids.stream().forEach(e -> {
            BillInvoice billInvoice = billInvoiceMapper.selectById(e);
            if ("1".equals(billInvoice.getBillStatus()) || "2".equals(billInvoice.getBillStatus())) {
                throw new WisdomException("费用已缴，无法更改");
            }

            billInvoice.setBillStatus("1");
            billInvoice.setPayType("1");
            int rows = billInvoiceMapper.updateById(billInvoice);
            if (rows > 0) {
                TpBuildingOwnerInfo buildingOwnerInfo = tpBuildingOwnerInfoMapper.selectById(billInvoice.getBuildingOwnerInfoId());

                // 插入流水
                BillStatement billStatement = new BillStatement();
                billStatement.setCommunityId(userElement.getOrgId());
                billStatement.setBillInvoiceId(billInvoice.getId());
                billStatement.setTaUserId(billInvoice.getTaUserId());
                billStatement.setPayPrice(billInvoice.getPayPrice());
                // TODO 缴费人，因为有一个情况就是没有业主
//                 billStatement.setPayName(buildingOwnerInfo.getOwnerName());
                billStatement.setPayRemark(billInvoice.getBillInvoiceExplain());
                billStatement.setPayType("1");
                billStatement.setCreateTime(new Date());
                billStatementMapper.insert(billStatement);

                // 更新缴费单信息
                billInvoice.setBillStatementId(billStatement.getId());
                billInvoice.setPayName(billStatement.getPayName());
                billInvoice.setPayDate(new Date());
                billInvoiceMapper.updateById(billInvoice);

                // 修改缴费户数
                Bill bill = billMapper.selectById(billInvoice.getBillId());
                bill.setPayedNum(bill.getPayedNum() + 1);
                bill.setUnpayedNum(bill.getUnpayedNum() - 1);
                // 未交户数为0时, 收费组状态变更为 1 , 收费完成
                if (bill.getUnpayedNum() <= 0) {
                    bill.setBillStatus("1");
                    bill.setUnpayedNum(0);
                }
                billMapper.updateById(bill);

                // 生成订单
                TpBillOrder tpBillOrder = new TpBillOrder();
                tpBillOrder.setCommunityId(userElement.getOrgId());
                tpBillOrder.setTpBillId(billInvoice.getBillId());
                tpBillOrder.setTpBillInvoiceId(billInvoice.getId());

                Random random = new Random();
                String orderNo = String.valueOf(System.currentTimeMillis()) + random.nextInt();
                tpBillOrder.setOrderBumber(orderNo);
                // 缴费状态  0：未支付  1: 已支付 2: 正在支付中
                tpBillOrder.setOrderStatus("1");
                tpBillOrder.setCreateDate(LocalDateTime.now());
                tpBillOrder.setCreateUser(userElement.getUserId());
                tpBillOrder.setUpdateDate(LocalDateTime.now());
                tpBillOrder.setUpdateUser(userElement.getUserId());

                tpBillOrderMapper.insert(tpBillOrder);



                // 把相对应的 APP端用户的代办消息进行设置为无效
                QueryWrapper<Message> messageQueryWrapper = new QueryWrapper<>();
                messageQueryWrapper.eq("community_id", userElement.getOrgId());
                messageQueryWrapper.eq("bill_id", billInvoice.getId());
                messageQueryWrapper.eq("uuid_type", "1");
                messageQueryWrapper.eq("uuid", billInvoice.getTaUserId());
                messageQueryWrapper.eq("message_type", "7");
                messageQueryWrapper.eq("advice_type", "1");
                messageQueryWrapper.eq("source", "2");

                Message one = iMessageService.getOne(messageQueryWrapper);
                if (null != one) {
                    one.setStatus("0");
                    iMessageService.updateById(one);
                }


            }
        });

        responseBean.addSuccess("操作成功");
        return responseBean;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseBean addTempBillInvoice(String parameter, TaUser userElement) {
        ResponseBean responseBean = new ResponseBean();
        JSONObject jsonObject = JSONObject.parseObject(parameter);
        // 收费项ID
        Integer billId = jsonObject.getInteger("billId");
        // 区/期
        Integer phase = jsonObject.getInteger("phase");
        // 栋
        Integer building = jsonObject.getInteger("building");
        // 单元
        Integer unit = jsonObject.getInteger("unit");
        // 楼层
        Integer level = jsonObject.getInteger("level");
        // 户号
        Integer roomNo = jsonObject.getInteger("roomNo");
        // 催缴日期
        // Date worthOf = jsonObject.getDate("worthOf");
        // 收费单说明
        String billInvoiceExplain = jsonObject.getString("billInvoiceExplain");
        // 收费金额
        Double payPrice = jsonObject.getDouble("payPrice");

        // 判断是不是已经 收费完成
//        Bill bill = billMapper.selectById(billId);
//        if ("1".equals(bill.getBillStatus())) {
//            // 状态 收费完成, 不允许添加收费单
//            responseBean.addError("不能给收费已完成的收费组添加收费单!");
//            return responseBean;
//        }

        // 校验 期/区/栋/单元/楼层/户号
        QueryWrapper<TpRoomNo> roomNoQueryWrapper = new QueryWrapper<>();
        roomNoQueryWrapper.eq("community_id", userElement.getOrgId());
        roomNoQueryWrapper.eq("phase_id", phase);
        roomNoQueryWrapper.eq("building_id", building);
        roomNoQueryWrapper.eq("unit_id", unit);
        roomNoQueryWrapper.eq("level_id", level);
        roomNoQueryWrapper.eq("id", roomNo);
        TpRoomNo tpRoomNo = tpRoomNoMapper.selectOne(roomNoQueryWrapper);
        if (null == tpRoomNo) {
            responseBean.addError("房产不存在！");
            return responseBean;
        }


        BillInvoice billInvoice = new BillInvoice();

        /**
         * 缴费单挂靠在 房产下面
         */

        // 设置房号
        billInvoice.setBillId(billId);
        billInvoice.setCommunityId(userElement.getOrgId());
        billInvoice.setBillInvoiceExplain(billInvoiceExplain);
//        billInvoice.setPayPrice(PayPriceUtils.yuanConversionPoints(payPrice));
        billInvoice.setBillStatus("0");
        billInvoice.setCreateUser(userElement.getUserId());
        billInvoice.setCreateDate(new Date());
        billInvoice.setRoomNoId(roomNo);
        billInvoice.setStatus(0);

        int result = billInvoiceMapper.insert(billInvoice);
        if (result <= 0) {
            throw new WisdomException("添加失败");
        }

        responseBean.addSuccess("操作成功");
        return responseBean;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseBean updateBillInvoiceStatus(List<Integer> ids, TaUser userElement) {
        ResponseBean responseBean = new ResponseBean();

        List<BillInvoice> billInvoices = ids.stream().map(e -> {
            BillInvoice billInvoice = billInvoiceMapper.selectById(e);
            billInvoice.setStatus(1);
            return billInvoice;
        }).collect(Collectors.toList());

        boolean b = this.updateBatchById(billInvoices);
        // 修改为有效时, 修改应缴费户数
        Bill bill = billMapper.selectById(billInvoices.get(0).getBillId());
        bill.setPayTotalNum(bill.getPayTotalNum() + billInvoices.size());
        bill.setUnpayedNum(bill.getUnpayedNum() + billInvoices.size());
        bill.setBillStatus("0");
        billMapper.updateById(bill);

        if (b == false) {
            throw new WisdomException("操作失败");
        }

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm");
        List<Message> messageList = billInvoices.stream().map(e -> {

            // 往APP端用户上面的每一个用户推送
            Message messageModelAPP = new Message();
            messageModelAPP.setCommunityId(userElement.getOrgId());
            messageModelAPP.setMessageType("7");
            messageModelAPP.setAdviceType("1");
            messageModelAPP.setModelType("2");
            messageModelAPP.setUuid(e.getTaUserId());
            messageModelAPP.setUuidType("1");
            // 消息是物业端 发过来的, 就是 2
            messageModelAPP.setSource("2");
            messageModelAPP.setMessageContent("您有待缴费的账单，点击查看并缴费 " + dateFormat.format(new Date()) + bill.getBillName());
            messageModelAPP.setStatus("1");
            messageModelAPP.setCreateDate(LocalDateTime.now());
            messageModelAPP.setCreateUser(userElement.getUserId());
            messageModelAPP.setBillId(e.getId());

            return messageModelAPP;
        }).collect(Collectors.toList());

        iMessageService.saveBatch(messageList);

        responseBean.addSuccess("操作成功");
        return responseBean;
    }

    @Override
    public ResponseBean getTempBillInvoice(Integer billId,TaUser userElement) {
        ResponseBean responseBean = new ResponseBean();
        Map<String, Object> map = Maps.newHashMap();
        map.put("billId", billId);
        map.put("communityId", userElement.getOrgId());

        List<BillInvoice> billInvoices = billInvoiceMapper.selectBillInvoiceTemp(map);

        responseBean.addSuccess(billInvoices);
        return responseBean;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseBean deleteTempBillInvoice(Integer billId, TaUser userElement) {
        ResponseBean responseBean = new ResponseBean();
        if (null == userElement) {
            responseBean.addError("未登录,无法操作!");
            return responseBean;
        }

        BillInvoice billInvoice = billInvoiceMapper.selectById(billId);
        if (billInvoice.getStatus() != 0) {
            responseBean.addError("只能删除作废的收费单");
            return responseBean;
        }
        int result = billInvoiceMapper.deleteById(billId);
        if (result <= 0) {
            throw new WisdomException("操作失败");
        }
        responseBean.addSuccess("操作成功");
        return responseBean;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseBean updateBillInvoiceIdPayPrice(Integer billId, Integer payPrice, TaUser userElement) {
        ResponseBean responseBean = new ResponseBean();
        BillInvoice billInvoice = billInvoiceMapper.selectById(billId);
        if ("1".equals(billInvoice.getBillStatus()) || "2".equals(billInvoice.getBillStatus())) {
            responseBean.addError("不能修改已缴费");
            return responseBean;
        }
        // 此处存储的是已经转换过的金额
        billInvoice.setPayPrice(payPrice);
        billInvoice.setUpdateUser(userElement.getUserId());
        billInvoice.setUpdateDate(new Date());

        int result = billInvoiceMapper.updateById(billInvoice);
        if (result <= 0) {
            throw new WisdomException("操作失败");
        }
        responseBean.addSuccess("操作成功");
        return responseBean;
    }

    @Override
    public ResponseBean exportExcel(TaUser userElement, Integer billId) {
        ResponseBean responseBean = new ResponseBean();
        String [] title = new String[] { "收费单号","房屋信息","收费单说明","金额(元)","流水","缴费状态","缴费人","缴费时间","新建时间","新建人","修改人","修改时间" };

        HSSFWorkbook excel = excel(title, userElement, billId,null);
        responseBean.addSuccess(excel);
        return responseBean;
    }

    /**
     * 表格
     * @param title
     * @param workbook
     * @return
     */
    private HSSFWorkbook excel(String[] title, TaUser userElement, Integer billId, HSSFWorkbook workbook) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

        if (null == workbook) {
            workbook = new HSSFWorkbook();
        }
        HSSFSheet sheet = workbook.createSheet("缴费单");
        // 行数标记
        int rowNum = 0;
        // 创建一行,用作标题
        HSSFRow row = sheet.createRow(rowNum);
        // 创建样式
        HSSFCellStyle style = workbook.createCellStyle();
        // 居中
//        style.setAlignment(HSSFCellStyle.ALIGN_CENTER);

        // 创建列对象
        HSSFCell cell = null;

        // 写入表头
        for (int i = 0; i<title.length; i++) {
            cell = row.createCell(i);
            cell.setCellValue(title[i]);
            cell.setCellStyle(style);
        }

        Map<String, Object> map = Maps.newHashMap();
        map.put("billId", billId);
        map.put("communityId", userElement.getOrgId());

        Page<BillInvoice> page = new Page<>();
        page.setCurrent(1);
        page.setSize(500);
        IPage<BillInvoice> billInvoiceIPage = billInvoiceMapper.selectBillInvoiceEffective(page, map);
        List<BillInvoice> records = billInvoiceIPage.getRecords();


        // 写入内容
        for (int i = 1; i<= billInvoiceIPage.getPages(); i++) {
            for (int t = 0; t<records.size(); t++) {
                row = sheet.createRow(++rowNum);
                // 收费单号
                cell = row.createCell(0);
                cell.setCellValue(records.get(t).getId());
                cell.setCellStyle(style);
                // 房屋信息
                cell = row.createCell(1);
                cell.setCellValue(records.get(t).getPhase() + records.get(t).getBuilding() + records.get(t).getUnit() + records.get(t).getRoomNo());
                cell.setCellStyle(style);
                // 业主姓名
//                cell = row.createCell(2);
//                cell.setCellValue(records.get(t).getOwnerName());
//                cell.setCellStyle(style);
                // 收费单说明
                cell = row.createCell(2);
                cell.setCellValue(records.get(t).getBillInvoiceExplain());
                cell.setCellStyle(style);
                // 金额(元)
                cell = row.createCell(3);
                double price = Double.valueOf(records.get(t).getPayPrice()) / 100.00;
                cell.setCellValue(price);
                cell.setCellStyle(style);
                if (null != records.get(t).getBillStatementId()) {
                    // 流水
                    cell = row.createCell(4);
                    cell.setCellValue(records.get(t).getBillStatementId());
                    cell.setCellStyle(style);
                }
                // 缴费状态
                cell = row.createCell(5);
                cell.setCellValue("0".equals(records.get(t).getBillStatus()) ? "未交费" : "1".equals(records.get(t).getBillStatus()) ? "已线上缴费" : "已线下缴费");
                cell.setCellStyle(style);
                // 缴费人
                cell = row.createCell(6);
                cell.setCellValue(records.get(t).getPayName());
                cell.setCellStyle(style);
                if (null != records.get(t).getPayDate()) {
                    // 缴费时间
                    cell = row.createCell(7);
                    cell.setCellValue(dateFormat.format(records.get(t).getPayDate()));
                    cell.setCellStyle(style);
                }
                // 新建时间
                cell = row.createCell(8);
                cell.setCellValue(dateFormat.format(records.get(t).getCreateDate()));
                cell.setCellStyle(style);
                // 新建人
                cell = row.createCell(9);
                cell.setCellValue(records.get(t).getCreateUserName());
                cell.setCellStyle(style);
                // 修改人
                cell = row.createCell(10);
                cell.setCellValue(records.get(t).getUpdateUserName());
                cell.setCellStyle(style);
                if (null != records.get(t).getUpdateDate()) {
                    // 修改时间
                    cell = row.createCell(11);
                    cell.setCellValue(dateFormat.format(records.get(t).getUpdateDate()));
                    cell.setCellStyle(style);
                }
            }
            page.setCurrent(i);
            page.setSize(500);
            billInvoiceIPage = billInvoiceMapper.selectBillInvoiceEffective(page, map);
            records = billInvoiceIPage.getRecords();

        }

        return workbook;
    }


    @Override
    public ResponseBean getInvoiceInvalid(TaUser userElement, String parameter) {
        ResponseBean responseBean = new ResponseBean();
        JSONObject jsonObject = JSONObject.parseObject(parameter);
        Integer pageNum = jsonObject.getInteger("pageNum");
        Integer pageSize = jsonObject.getInteger("pageSize");
        Integer billId = jsonObject.getInteger("billId");

        Bill bill = billMapper.selectById(billId);

        Page page = new Page();
        page.setCurrent(pageNum);
        page.setSize(pageSize);

        QueryWrapper<BillInvoice> billInvoiceQueryWrapper = new QueryWrapper<>();
        billInvoiceQueryWrapper.eq("bill_id", billId);
        billInvoiceQueryWrapper.eq("community_id", userElement.getOrgId());

        IPage<BillInvoice> billInvoiceIPage = billInvoiceMapper.selectPage(page, billInvoiceQueryWrapper);
        List<BillInvoice> records = billInvoiceIPage.getRecords();
        records.forEach(e->{
            TpBuildingOwnerInfo buildingOwnerInfo = tpBuildingOwnerInfoMapper.selectById(e.getBuildingOwnerInfoId());
            if (null != buildingOwnerInfo) {
                e.setOwnerName(buildingOwnerInfo.getOwnerName());
            }
            TpRoomNo tpRoomNo = tpRoomNoMapper.selectById(e.getRoomNoId());
            e.setPhase(tpRoomNo.getPhaseName());
            e.setBuilding(tpRoomNo.getBuildingName());
            e.setUnit(tpRoomNo.getUnitName());
            e.setLevel(tpRoomNo.getLevelName());
        });

        Map<String, Object> map = Maps.newHashMap();
        map.put("bill", bill);
        map.put("billInvoice", records);
        map.put("total", billInvoiceIPage.getTotal());
        map.put("pageNum", billInvoiceIPage.getCurrent());
        map.put("pageSize", billInvoiceIPage.getSize());

        responseBean.addSuccess(map);
        return responseBean;
    }
    
    /**
     * 按小区统计所有的金额
     *
     * @return
     */
    @Override
    public List<Map<String, Object>> getPriceCount() {
        return billInvoiceMapper.getPriceCount();
    }
}
