package com.ghy.payment.service.impl;

import com.ghy.common.adapay.model.PaymentDTO;
import com.ghy.common.core.text.Convert;
import com.ghy.common.enums.PayStatus;
import com.ghy.common.enums.PayTypeEnum;
import com.ghy.payment.domain.FinancialDetail;
import com.ghy.payment.domain.FinancialMaster;
import com.ghy.payment.mapper.FinancialMasterMapper;
import com.ghy.payment.mapper.PaymentMapper;
import com.ghy.payment.service.FinancialDetailService;
import com.ghy.payment.service.FinancialMasterService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;

import static java.time.temporal.ChronoField.*;

/**
 * 商品模块实现类
 *
 * @author clunt
 */
@Service
public class FinancialMasterServiceImpl implements FinancialMasterService {

    private static final Logger logger = LoggerFactory.getLogger(FinancialMasterServiceImpl.class);

    private static final AtomicLong INDEX = new AtomicLong(1L);

    public static final DateTimeFormatter MINI_FORMATTER = new DateTimeFormatterBuilder()
            .appendValue(YEAR, 4).appendValue(MONTH_OF_YEAR, 2)
            .appendValue(DAY_OF_MONTH, 2).appendValue(HOUR_OF_DAY, 2)
            .appendValue(MINUTE_OF_HOUR, 2).appendValue(SECOND_OF_MINUTE, 2).toFormatter();

    @Resource
    private PaymentMapper paymentMapper;
    @Resource
    private FinancialMasterMapper financialMasterMapper;
    @Resource
    private FinancialDetailService financialDetailService;

    @Override
    public int insertFinancialMaster(FinancialMaster financialMaster) {
        return financialMasterMapper.insertFinancialMaster(financialMaster);
    }

    @Override
    public int updateFinancialMaster(FinancialMaster financialMaster) {
        return financialMasterMapper.updateFinancialMaster(financialMaster);
    }

    @Override
    public List<FinancialMaster> selectFinancialMasterList(FinancialMaster financialMaster) {
        return financialMasterMapper.selectFinancialMasterList(financialMaster);
    }

    @Override
    public List<FinancialMaster> selectAppList(FinancialMaster request) {
        List<FinancialMaster> masterList = this.selectFinancialMasterList(request);
        masterList.forEach(master -> {
            FinancialDetail param = new FinancialDetail();
            param.setFinancialMasterId(master.getId());
            param.setPayeeId(request.getUserId());
            List<FinancialDetail> details = financialDetailService.selectFinancialDetailList(param);
            details.forEach(detail -> {

            });
        });
        return null;
    }

    @Override
    public FinancialMaster selectById(Long financialMasterId) {
        return financialMasterMapper.selectById(financialMasterId);
    }

    @Override
    public int deleteFinancialMasterByIds(String ids) {
        Long[] financialMasterIds = Convert.toLongArray(ids);
        return financialMasterMapper.deleteFinancialMasterByIds(financialMasterIds);
    }

    @Override
    public void paySucceeded(String paymentId, String payChannel) {
        int payType;
        try {
            payType = PayTypeEnum.valueOf(payChannel.toUpperCase()).getCode();
        } catch (IllegalArgumentException e) {
            payType = -1;
            logger.error("paymentId[{}] Unknown payChannel [{}]!", paymentId, payChannel);
        }
        PaymentDTO paymentDTO = paymentMapper.selectById(paymentId);
        String orderMasterCode = paymentDTO.getOrderNo().split("_")[0];
        FinancialMaster param = new FinancialMaster();
        param.setOrderMasterCode(orderMasterCode);
        List<FinancialMaster> result = financialMasterMapper.selectFinancialMasterList(param);
        if (!CollectionUtils.isEmpty(result)) {
            financialMasterMapper.updateOrderStatus(result.get(0).getOrderMasterCode(), PayStatus.PAID.getCode());
            if (StringUtils.isEmpty(result.get(0).getPaymentId())) {
                financialMasterMapper.paySucceeded(paymentId, result.get(0).getId(), payType);
            }
            FinancialDetail request = new FinancialDetail();
            request.setFinancialMasterId(result.get(0).getId());
            request.setPayStatus(PayStatus.PAID.getCode());
            request.setPayType(payType);
            request.setPayTime(new Date());
            financialDetailService.updateByFinancialMasterId(request);
        } else {
            logger.error("原单不存在!");
        }
    }

    @Override
    public String createCode() {
        INDEX.compareAndSet(9999L, 1L);
        LocalDateTime now = LocalDateTime.now();
        return "fm" + now.format(MINI_FORMATTER) + INDEX.getAndIncrement();
    }

    @Override
    public FinancialMaster selectByOrderMasterId(Long orderMasterId) {
        return financialMasterMapper.selectByOrderMasterId(orderMasterId);
    }

    @Override
    public int insertPayment(PaymentDTO payment) {
        return paymentMapper.insertPayment(payment);
    }

    @Override
    public int updatePayment(PaymentDTO payment) {
        return paymentMapper.updatePayment(payment);
    }

    @Override
    public PaymentDTO selectPaymentById(String id) {
        return paymentMapper.selectById(id);
    }

    @Override
    public FinancialMaster selectByPaymentId(String paymentId) {
        return financialMasterMapper.selectByPaymentId(paymentId);
    }

    @Override
    public void refundSucceeded(String reverseId) {
        financialMasterMapper.refundSucceeded(reverseId);
    }

    @Override
    public int updatePayStatus(Long id, int payStatus) {
        return financialMasterMapper.updatePayStatus(id, payStatus);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updatePay(Long id, String paymentId, Integer payStatus) {
        FinancialDetail financialDetail = new FinancialDetail();
        financialDetail.setFinancialMasterId(id);
        financialDetail.setPayStatus(payStatus);
        financialDetail.setPayTime(new Date());
        financialDetailService.updateByFinancialMasterId(financialDetail);
        return financialMasterMapper.updatePay(id, paymentId, payStatus);
    }

    @Override
    public List<FinancialMaster> selectByOrderMasterIds(Set<Long> orderMasterIds) {
        if (CollectionUtils.isEmpty(orderMasterIds)) {
            return new ArrayList<>();
        }
        return financialMasterMapper.selectByOrderMasterIds(orderMasterIds);
    }
}
