package com.hc.web.controller.browser.front;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hc.business.dto.OrderRefundEntityDto;
import com.hc.business.model.ClassConfig;
import com.hc.business.model.Orders;
import com.hc.business.model.UserInvoices;
import com.hc.business.service.ClassConfigService;
import com.hc.business.service.OrderRefundService;
import com.hc.business.service.OrdersService;
import com.hc.business.service.UserInvoicesService;
import com.hc.core.utils.redis.RedisUtil;
import com.hc.core.utils.result.Result;
import com.hc.core.utils.tool.ResultUtils;
import com.hc.web.config.util.InvoiceHelper;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;


/**
 * 用户发票表(UserInvoices)表控制层
 *
 * @author java
 * @since 2020-12-02 10:50:41
 */

@RestController
@RequestMapping("/new/api/front/userInvoices")
public class FrontUserInvoicesController {

    /**
     * 服务对象
     */
    private final UserInvoicesService userInvoicesService;

    private final OrderRefundService orderRefundService;

    private final ClassConfigService classConfigService;

    private final OrdersService ordersService;
    private final RedisUtil redisUtil;


    public FrontUserInvoicesController(UserInvoicesService userInvoicesService, OrderRefundService orderRefundService, ClassConfigService classConfigService, OrdersService ordersService, RedisUtil redisUtil) {
        this.userInvoicesService = userInvoicesService;
        this.orderRefundService = orderRefundService;
        this.classConfigService = classConfigService;
        this.ordersService = ordersService;
        this.redisUtil = redisUtil;
    }

    @GetMapping("/{id}")
    @ApiOperation(value = "依据主键获取 UserInvoices", response = Result.class)
    public Result selectFrontUserInvoices(@PathVariable("id") Integer id) {
        UserInvoices userInvoices = this.userInvoicesService.queryById(id);

        return Result.success(userInvoices);
    }

    @PostMapping("/addUserInvoices")
    @ApiOperation(value = "新增发票", response = Result.class)
    public Result addUserInvoices(@Valid @RequestBody UserInvoices userInvoices){
        String msg = checkInvoiceContent(userInvoices);
        if (msg != "") {
            return  Result.exception(511, msg);
        }

        //判断订单是否存在
        Orders orders = ordersService.queryById(userInvoices.getOrderId());
        if (orders == null) {
            return Result.exception(511, "订单不存在");
        }

        //nono，发票所处状态-1不开只记录， 0申请中 10申请成功，20开票完成，30开票失败，40开票成功签章失败， 50作废申请，60未作废 70作废中 80作废失败 90作废成功
        //查询这个订单下是否存在未作废的发票
        if(orders.getUserInvoicesId()!=null && orders.getUserInvoicesId()!=0)
        {
            return Result.exception(511, "此订单已经存在发票，请不要重复申请");
        }

        //判断是否存在已经有退费单在处理中
        List<OrderRefundEntityDto> orderRefunds = orderRefundService.queryAll(userInvoices.getOrderId(), "", 0, null, null, null, null);
        if(orderRefunds.stream().count()>0) {
            return Result.exception(511, "此订单已经存退费单，等处理完毕后方可开票");
        }

        userInvoices.setClassId(orders.getClassId());
        userInvoices.setUserId(orders.getUserId());
        userInvoices.setSyncStatus(-1);
        userInvoices.setSyncOrderNo(ResultUtils.generateUniqueNumber());//生成20位的唯一订单，方便回调匹配
        userInvoices.setCreateTime(System.currentTimeMillis());
        userInvoices.setStatus(1);

        //1.进行远程开票(蓝票，普票)
        if (userInvoices.getInvoicesType() == 1 || userInvoices.getInvoicesType() == 0) {
            InvoiceHelper invoiceHelper = new InvoiceHelper(redisUtil);
            ClassConfig classConfig = classConfigService.queryById(userInvoices.getClassId());
            String json = invoiceHelper.GetKPJsonStr(userInvoices,classConfig);
            String result = invoiceHelper.ApplyForInvoice(json);
            JSONObject object = JSON.parseObject(result);
            String code = object.getString("code");
            if (code.equals("E0000")) {
                String result2 = object.getString("result");
                object = JSON.parseObject(result2);
                String invoiceSerialNum = object.getString("invoiceSerialNum");//流水号
                //2.普票进入申请
                userInvoices.setSyncStatus(0);
                userInvoices.setSyncSerialNum(invoiceSerialNum);

            } else {
                String result2 = object.getString("describe");
               return Result.exception(511, result2);
            }
        } else {
            //3,专票只进行记录
            userInvoices.setSyncStatus(-1);
        }
        //3.结束返回
        UserInvoices entity = userInvoicesService.insert(userInvoices);
        orders.setUserInvoicesId(entity.getUserInvoicesId());
        ordersService.update(orders);
        return Result.success(entity);

    }

    @DeleteMapping("/cancelByOrderId")
    @ApiOperation(value = "作废发这张订单的票", response = Result.class)
    public Result cancelByOrderId(@ApiParam(value = "订单id") @RequestParam Integer orderId) {
        Orders orders = ordersService.queryById(orderId);
        if (orders == null) {
           return Result.exception(511, "订单不存在");
        }

        if (orders.getUserInvoicesId() == null) {
            return Result.exception(511, "发票不存在");
        }

        UserInvoices userInvoices = userInvoicesService.queryById(orders.getUserInvoicesId());

        if (userInvoices == null) {
            return Result.exception(511, "发票不存在");
        }
        //如果发票是普通发票
        if(userInvoices.getInvoicesType()==1 ||userInvoices.getInvoicesType()==0)
        {
            //0申请中 10申请成功，20开票完成，30开票失败，40开票成功签章失败
            if(userInvoices.getSyncStatus().equals(20) || userInvoices.getSyncStatus().equals(40))
            {
                InvoiceHelper invoiceHelper = new InvoiceHelper(redisUtil);
                ClassConfig classConfig = classConfigService.queryById(userInvoices.getClassId());
                String json = invoiceHelper.GetCancelKPJsonStr(userInvoices,classConfig);
                String result = invoiceHelper.CancelForInvoice(json);
                JSONObject object = JSON.parseObject(result);
                String code = object.getString("code");
                //提交作废流程，因为已经生成了发票
                if (code.equals("E0000")) {
                    String result2 = object.getString("result");
                    object = JSON.parseObject(result2);
                    String invoiceSerialNum = object.getString("invoiceSerialNum");//流水号
                    //2.普票进入作废申请
                    userInvoices.setSyncStatus(50);
                    userInvoices.setSyncSerialRedNum(invoiceSerialNum);
                    userInvoicesService.update(userInvoices);
                } else {
                    String result2 = object.getString("describe");
                    return Result.exception(511, result2);
                }
            }else {
                //测试用，直接作废
                userInvoices.setSyncStatus(90);
                orders.setUserInvoicesId(0);
                ordersService.update(orders);
            }

        }else {
            userInvoices.setSyncStatus(90);
            orders.setUserInvoicesId(0);
            Orders update = ordersService.update(orders);
            userInvoicesService.update(userInvoices);

        }
        return Result.success(null);
    }

    @GetMapping("/selectDetailByOrderId")
    @ApiOperation(value = "根据订单获取此订单当前有效的发票", response = Result.class)
    public Result selectDetailByOrderId(@ApiParam(value = "订单id") @RequestParam Integer orderId) {
        //判断订单是否存在
        Orders orders = ordersService.queryById(orderId);
        if (orders == null) {
            Result.exception(511, "订单不存在");
        }
        if (orders.getUserInvoicesId() == null) {
            Result.exception(511, "发票不存在");
        }


        UserInvoices userInvoices = this.userInvoicesService.queryById(orders.getUserInvoicesId());

        if(userInvoices!=null) {

            //存在红票
            if(!ResultUtils.isNullOrEmpty(userInvoices.getSyncUrlRed()) && userInvoices.getSyncStatus().equals(20))
            {
                userInvoices.setSyncStatus(90);
                userInvoicesService.update(userInvoices);

                orders.setUserInvoicesId(0);
                ordersService.update(orders);
            }

            //申请中的才处理
            if (userInvoices.getSyncStatus().equals(50) || userInvoices.getSyncStatus().equals(0)) {
                InvoiceHelper invoiceHelper = new InvoiceHelper(redisUtil);
                String json = invoiceHelper.GetKPQueryJsonStr(userInvoices);
                String result = invoiceHelper.QueryInvoiceResult(json);
                if(ResultUtils.isNullOrEmpty(result))
                {
                    Result.exception(511, "发票状态不正确，无法校验");
                }
                JSONObject object = JSON.parseObject(result);
                String code = object.getString("code");
                //提交作废流程，因为已经生成了发票
                if (code.equals("E0000")) {
                    String result2 = object.getString("result");
                    // 去除开头的'['
                    if (result2.charAt(0) == '[') {
                        result2 = result2.substring(1);
                    }

                    // 去除结尾的']'
                    if (result2.charAt(result2.length() - 1) == ']') {
                        result2 = result2.substring(0, result2.length() - 1);
                    }
                    object = JSON.parseObject(result2);
                    String c_status = object.getString("status");//流水号
                    String c_url = object.getString("pdfUrl");//发票pdf地址
                    String c_ourl = object.getString("ofdUrl");//发票pdf地址
                    if (StringUtils.hasText(c_ourl)) {
                        c_url = c_ourl;
                    }
                    String c_errorMessage = object.getString("statusMsg");//信息
                    String c_fpdm = object.getString("invoiceCode");//发票代码
                    String c_fphm = object.getString("invoiceNo");//发票号码
                    String c_remark = object.getString("remark");//对应正数发票代码
                    //作废中
                    if(userInvoices.getSyncStatus().equals(50)) {
                        if(c_status.equals("2")) {
                            userInvoices.setSyncStatus(90);
                        }else if(c_status.equals("3")) {
                            userInvoices.setSyncStatus(90);
                        }else if(c_status.equals("22")) {
                            userInvoices.setSyncStatus(80);
                        }else if(c_status.equals("24")) {
                            userInvoices.setSyncStatus(100);
                        }
                        userInvoices.setSyncUrlRed(c_url);
                        userInvoices.setTaxNoRed(c_fphm);

                        userInvoices.setRemarksSign(c_remark);
                        userInvoices.setSyncMsg(c_errorMessage);
                        userInvoicesService.update(userInvoices);

                        if(userInvoices.getSyncStatus()==90) {
                            orders.setUserInvoicesId(0);
                            ordersService.update(orders);
                        }
                    }else { //正常开票
                        if (c_status.equals("2")) {
                            userInvoices.setSyncStatus(20);
                        } else if (c_status.equals("22")) {
                            userInvoices.setSyncStatus(30);
                        } else if (c_status.equals("24")) {
                            userInvoices.setSyncStatus(40);
                        }
                        userInvoices.setSyncUrl(c_url);
                        userInvoices.setTaxNo(c_fphm);

                        userInvoices.setRemarksSign(c_remark);
                        userInvoices.setSyncMsg(c_errorMessage);
                        userInvoicesService.update(userInvoices);
                    }
                } else {
                    String result2 = object.getString("describe");
                    userInvoices.setRemarksSign(result2);
                    userInvoicesService.update(userInvoices);
                }
            }
        }
        return Result.success(this.userInvoicesService.queryById(orders.getUserInvoicesId()));
    }

    private String checkInvoiceContent(UserInvoices userInvoices) {
        if (!StringUtils.hasText(userInvoices.getInvoicesHead())) {
            return "抬头必须填写";
        }
        if (userInvoices.getInvoicesPrice() == null || userInvoices.getInvoicesPrice() <= 0) {
            return "发票金额必须传入";
        }
        if (userInvoices.getOrderId() == null) {
            return "关联订单必须传入";
        }

        if (userInvoices.getInvoicesType() == 1) {
            if (!StringUtils.hasText(userInvoices.getInvoicesCode())) {
                return "企业税号必须填写";
            }
//            if (!StringUtils.hasText(userInvoices.getBuyerEmail())) {
//                return "邮箱必须填写";
//            }
        } else if (userInvoices.getInvoicesType() == 2) {
            if (!StringUtils.hasText(userInvoices.getInvoicesCode())) {
                return "企业税号必须填写";
            }
            if (!StringUtils.hasText(userInvoices.getInvoicesBank())) {
                return "开户行必须填写";
            }
            if (!StringUtils.hasText(userInvoices.getInvoicesUser())) {
                return "开户名必须填写";
            }
            if (!StringUtils.hasText(userInvoices.getInvoicesNo())) {
                return "开户账号必须填写";
            }
            if (!StringUtils.hasText(userInvoices.getInvoicesAddress())) {
                return "单位地址必须填写";
            }
            if (!StringUtils.hasText(userInvoices.getInvoicesTel())) {
                return "单位电话必须填写";
            }

        }
        return "";
    }

    //nono，发票所处状态-1不开只记录， 0申请中 10申请成功，20开票完成，30开票失败，40开票成功签章失败， 50作废申请，60未作废 70作废中 80作废失败 90作废成功
    @GetMapping("/queryAllByOrderId")
    @ApiOperation(value = "获取订单的所有发票信息列表包括作废的", response = Result.class)
    public Result queryAllByOrderId(@ApiParam(value = "订单id") @RequestParam Integer orderId) {
        return Result.success(userInvoicesService.queryByOrderId(orderId,null));
    }

    @GetMapping("queryAllByUserId")
    @ApiOperation(value = "获取用户发票信息", response = Result.class)
    public Result queryAllByUserId(@ApiParam(value = "用户id") @RequestParam Integer userId) {
        return Result.success(userInvoicesService.queryDetailByUserId(userId));
    }

}