package cn.com.countrygarden.bi.main.controller.resident;

import cn.com.countrygarden.bi.main.core.Response;
import cn.com.countrygarden.bi.main.exception.ServiceException;
import cn.com.countrygarden.bi.main.model.AccessToken;
import cn.com.countrygarden.bi.main.model.PageData;
import cn.com.countrygarden.bi.main.model.resident.Payment;
import cn.com.countrygarden.bi.main.model.resident.ResidentPaymentData;
import cn.com.countrygarden.bi.main.service.AccessTokenService;
import cn.com.countrygarden.bi.main.service.resident.ResidentPaymentService;
import cn.com.countrygarden.bi.main.util.DateUtil;
import cn.com.countrygarden.bi.main.util.MD5;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.List;

/**
 * Created by chenweijiang on 2017/11/13.
 */
@RestController("ResidentPaymentController")
@RequestMapping("/api/resident/payment")
@PropertySource("classpath:/application.properties")
public class PaymentController {

    @Autowired
    private Environment env;

    @Autowired
    private AccessTokenService accessTokenService;

    @Autowired
    private ResidentPaymentService paymentService;

    @RequestMapping(value = "", method = {RequestMethod.GET}, produces = {"application/json;charset=utf-8"})
    public Object search(@RequestParam(name = "organId", required = false) String organId,
                         @RequestParam(name = "commId", required = false) String commId,
                         @RequestParam(name = "startTime", required = false) String startTime,
                         @RequestParam(name = "endTime", required = false) String endTime,
                         @RequestParam(name = "receivedStartTime", required = false) String receivedStartTime,
                         @RequestParam(name = "receivedEndTime", required = false) String receivedEndTime,
                         @RequestParam(name = "contractCode", required = false) String contractCode,
                         @RequestParam(name = "contractStatus", required = false) String contractStatus,
                         @RequestParam(name = "isPaid", required = false) String isPaid,
                         @RequestParam(name = "hasInvoice", required = false) String hasInvoice,
                         @RequestParam(name = "status", required = false) String status,
                         @RequestParam(name = "page", required = false, defaultValue = "1") int page,
                         @RequestParam(name = "size", required = false, defaultValue = "10") int size,
                         HttpServletRequest request, HttpServletResponse response) {
        String accessToken = request.getParameter("AccessToken");
        AccessToken token = accessTokenService.findByToken(accessToken);
        PageData result = paymentService.search(organId, commId, startTime, endTime, receivedStartTime, receivedEndTime,
                contractCode, contractStatus, isPaid, hasInvoice, status, page, size, token.getUserCode());
        return Response.response(result);
    }

    @RequestMapping(value = "export", method = {RequestMethod.GET}, produces = {"application/json;charset=utf-8"})
    public Object export(@RequestParam(name = "organId", required = false) String organId,
                         @RequestParam(name = "commId", required = false) String commId,
                         @RequestParam(name = "startTime", required = false) String startTime,
                         @RequestParam(name = "endTime", required = false) String endTime,
                         @RequestParam(name = "receivedStartTime", required = false) String receivedStartTime,
                         @RequestParam(name = "receivedEndTime", required = false) String receivedEndTime,
                         @RequestParam(name = "contractCode", required = false) String contractCode,
                         @RequestParam(name = "contractStatus", required = false) String contractStatus,
                         @RequestParam(name = "isPaid", required = false) String isPaid,
                         @RequestParam(name = "hasInvoice", required = false) String hasInvoice,
                         @RequestParam(name = "status", required = false) String status,
                         HttpServletRequest request, HttpServletResponse response) {
        String accessToken = request.getParameter("AccessToken");
        AccessToken token = accessTokenService.findByToken(accessToken);
        PageData result = paymentService.search(organId, commId, startTime, endTime, receivedStartTime, receivedEndTime,
                contractCode, contractStatus, isPaid, hasInvoice, status, 1, 0, token.getUserCode());
        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet();
        PaymentExporter exporter = new PaymentExporter();
        exporter.createHeader(workbook, sheet);
        String urlBase = env.getProperty("resident.file.url.base", "");
        String fileBase = env.getProperty("resident.file.path", "");
        exporter.createBody((List<ResidentPaymentData>) result.getData(), workbook, sheet, urlBase, fileBase);

        response.setContentType("multipart/form-data");
        String fileName = "export.xlsx";
        try {
            fileName = URLEncoder.encode("收费.xlsx", "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        response.setHeader("Content-Disposition", "attachment;fileName=" + fileName);

        OutputStream outputStream = null;
        try {
            outputStream = response.getOutputStream();
            workbook.write(outputStream);
        } catch (Exception ex) {

        } finally {
            try {
                workbook.close();
            } catch (Exception ex) {

            }
        }

        return Response.response(result);
    }

    @RequestMapping(value = "", method = {RequestMethod.POST}, produces = {"application/json;charset=utf-8"})
    @ResponseBody
    public Object paid(@RequestParam(name = "id") Integer id,
                       @RequestParam(name = "fixAmount") String fixAmount,
                       @RequestParam(name = "floatAmount") String floatAmount,
                       @RequestParam(name = "receivedTime") String receivedTime,
                       @RequestParam(name = "remark", required = false) String remark,
                       @RequestParam(name = "receipt") MultipartFile receipt,
                       @RequestParam(name = "batch", defaultValue = "false", required = false) boolean batch,
                       HttpServletRequest request, HttpServletResponse response) {
        String accessToken = request.getParameter("AccessToken");
        AccessToken token = accessTokenService.findByToken(accessToken);
        if (receipt == null || receipt.isEmpty()) {
            return Response.responseFail("请上传收费凭证");
        }

        if (StringUtils.isEmpty(receivedTime)) {
            return Response.responseFail("请输入收款日期");
        }

        if (StringUtils.isEmpty(fixAmount)) {
            return Response.responseFail("请输入固定收费金额");
        }

        //save file
        String basePath = env.getProperty("resident.file.path");
        if (StringUtils.isEmpty(basePath)) {
            basePath = request.getServletContext().getRealPath("");
        }

        Instant instant = Instant.now();
        LocalDateTime dateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());

        String fileName = receipt.getOriginalFilename();
        String saveDirectory = "/uploadFile/" + dateTime.getYear() + "/" + dateTime.getMonthValue() + "/" + dateTime.getDayOfMonth();
        String saveFileName = saveDirectory + "/" + MD5.GetMD5Code(dateTime.toString()) + "." + FilenameUtils.getExtension(fileName);

        File dir = new File(basePath + saveDirectory);
        if (!dir.exists()) {
            dir.mkdirs();
        }

        File saveFile = new File(basePath + saveFileName);

        try {
            ((CommonsMultipartFile) receipt).getFileItem().write(saveFile);
        } catch (Exception e) {
            throw new ServiceException("无法保存上传文件：" + e.getMessage());
        }

        Payment payment = new Payment();
        payment.setFixAmount(new BigDecimal(fixAmount));
        if (!StringUtils.isEmpty(floatAmount)) {
            payment.setFloatAmount(new BigDecimal(floatAmount));
        }

        payment.setRemark(remark);
        payment.setReceivedTime(DateUtil.parseDate(receivedTime));

        payment.setReceipt(saveFileName);

        if (batch == true) {
            payment.setContractId(id);

            paymentService.paidBatch(payment, token.getUserCode());
        } else {
            payment.setId(id);

            paymentService.paid(payment, token.getUserCode());
        }
        return Response.response("");
    }


    @RequestMapping(value = "/check", method = {RequestMethod.POST}, produces = {"application/json;charset=utf-8"})
    public Object check(@RequestParam(name = "id") Integer id,
                        @RequestParam(name = "status") String status,
                        HttpServletRequest request, HttpServletResponse response) {
        String accessToken = request.getParameter("AccessToken");
        AccessToken token = accessTokenService.findByToken(accessToken);

        paymentService.check(id, status, token.getUserCode());
        return Response.response("");
    }


    @RequestMapping(value = "/invoice", method = {RequestMethod.POST}, produces = {"application/json;charset=utf-8"})
    public Object invoice(@RequestParam(name = "id") Integer id,
                          @RequestParam(name = "amount") String amount,
                          @RequestParam(name = "amountWithoutTax") String amountWithoutTax,
                          @RequestParam(name = "valueAddedTax") String valueAddedTax,
                          @RequestParam(name = "invoiceNumber") String invoiceNumber,
                          @RequestParam(name = "invoiceImg") MultipartFile invoiceImg,
                          HttpServletRequest request, HttpServletResponse response) {
        String accessToken = request.getParameter("AccessToken");
        AccessToken token = accessTokenService.findByToken(accessToken);
        if (invoiceImg == null || invoiceImg.isEmpty()) {
            return Response.responseFail("请上传收费凭证");
        }
        Payment payment = new Payment();
        payment.setId(id);
        if (StringUtils.isEmpty(amount)) {
            return Response.responseFail("请输入总金额");
        }
        payment.setAmount(new BigDecimal(amount));
        if (StringUtils.isEmpty(amountWithoutTax)) {
            return Response.responseFail("请输入免税金额");
        }
        payment.setAmountWithoutTax(new BigDecimal(amountWithoutTax));

        if (StringUtils.isEmpty(valueAddedTax)) {
            return Response.responseFail("请输入增值税金额");
        }
        payment.setValueAddedTax(new BigDecimal(valueAddedTax));

        if (StringUtils.isEmpty(invoiceNumber)) {
            return Response.responseFail("请输入税票号");
        }
        payment.setInvoiceNumber(invoiceNumber);


        String basePath = env.getProperty("resident.file.path");
        if (StringUtils.isEmpty(basePath)) {
            basePath = request.getServletContext().getRealPath("");
        }
        //save file
        Instant instant = Instant.now();
        LocalDateTime dateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());

        String fileName = invoiceImg.getOriginalFilename();
        String saveDirectory = "/uploadFile/" + dateTime.getYear() + "/" + dateTime.getMonthValue() + "/" + dateTime.getDayOfMonth();
        String saveFileName = saveDirectory + "/" + MD5.GetMD5Code(dateTime.toString()) + "." + FilenameUtils.getExtension(fileName);

        File dir = new File(basePath + saveDirectory);
        if (!dir.exists()) {
            dir.mkdirs();
        }

        File saveFile = new File(basePath + saveFileName);

        try {
            ((CommonsMultipartFile) invoiceImg).getFileItem().write(saveFile);
        } catch (Exception e) {

            throw new ServiceException("无法保存上传文件：" + e.getMessage());
        }

        payment.setInvoiceImg(saveFileName);
        paymentService.invoice(payment, token.getUserCode());
        return Response.response("");
    }
}
