package com.ruoyi.web.controller.system;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.system.domain.AmountStatics;
import com.ruoyi.system.domain.BalanceDay;
import com.ruoyi.system.domain.BalancePiece;
import com.ruoyi.system.domain.Income;
import com.ruoyi.system.mapper.IncomeMapper;
import com.ruoyi.system.mapper.StatisticsMapper;
import com.ruoyi.system.mapper.SysBalanceMapper;
import com.ruoyi.web.controller.tool.RedisMapUtil;
import io.swagger.models.auth.In;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Shawn
 */
@RequestMapping("/income")
@RestController
public class SysIncomeController extends BaseController {

    @Autowired
    private SysBalanceMapper balanceMapper;

    @Autowired
    private IncomeMapper incomeMapper;

    @Autowired
    private StatisticsMapper statisticsMapper;

    @GetMapping("/getbalance/{unittype}/{unitNum}/{date}")
    @PreAuthorize("@ss.hasPermi('balance:balanceselect:select')")
    public AjaxResult getBalance(@PathVariable String unittype,@PathVariable String unitNum,@PathVariable String date){

//        System.out.println(unittype);
//        System.out.println(unitNum);
//        System.out.println(date);
        List<BalanceDay> balanceDay = balanceMapper.getBalanceDay(unittype, unitNum, date.split(",")[0], date.split(",")[1]);
        List<BalancePiece> balancePiece = balanceMapper.getBalancePiece(unittype, unitNum, date.split(",")[0], date.split(",")[1]);
        AjaxResult ajaxResult = new AjaxResult();
        ajaxResult.put("balancePiece",balancePiece);
        ajaxResult.put("balanceDay",balanceDay);
        return ajaxResult;
    }

    @PreAuthorize("@ss.hasPermi('income:incomeinfo:select')")
    @GetMapping("/getIncome/{unitNum}/{date}")
    public List<Income> getListByTime(@PathVariable String unitNum,@PathVariable String date) {
        return incomeMapper.selectByTime(unitNum,date.split(",")[0],date.split(",")[1]);
    }

    @PreAuthorize("@ss.hasPermi('income:incomeinfo:upload')")
    @PostMapping("/setIncomeInfo/{userId}/{unitId}/{monthId}")
    @Transactional
    public AjaxResult setSalaryInfo(@RequestBody String jsona,@PathVariable String userId,@PathVariable String unitId,@PathVariable String monthId){
//        System.out.println(jsona);
        Map<String,String> mapType = JSON.parseObject(jsona,Map.class);
        String incomes = mapType.get("SR").substring(1, mapType.get("SR").length() - 1);
        String username = (String) RedisMapUtil.getMapUserIdToUserName().get(userId);
        incomeMapper.insertIncomeStatus(userId,username,unitId,monthId);
        for (String s : incomes.split(Constants.GROUPSPLIT)) {
            Income income = new Income();
            String substring = s.substring(1, s.length() - 1);
            String[] split = substring.split(Constants.SMALLSPLIT);
            income.setYearAndMonth(split[0]);
            income.setUnitNumber(split[1]);
            income.setReportPerson(split[2]);
            income.setUserId(userId);
            income.setFirstParty(split[3]);
            income.setSecondParty(split[4]);
            income.setProjectFullName(split[5]);
            income.setProjectContent(split[6]);
            income.setProjectStartTime(split[7]);
            income.setProjectEndTime(split[8]);
            income.setIsSign(split[9]);
            BigDecimal contractAmount =new BigDecimal(split[10]);
            income.setContractAmount(contractAmount);
            BigDecimal incomeCurrentMonth = new BigDecimal(split[11]);
            income.setIncomeCurrentMonth(incomeCurrentMonth);
            income.setProofType(split[12]);
            income.setClearingMode(split[13]);
            income.setFirstPartyPrincipal(split[14]);
            income.setSecondPartyPrincipal(split[15]);
            income.setFirstPartyConfirmProofNumber(split[16]);
            if(split.length >= 18){
                income.setExplainInfo(split[17]);
            }
            incomeMapper.insertOne(income);
        }
        return AjaxResult.success();
    }

    @PreAuthorize("@ss.hasPermi('income:incomeinfo:upload')")
    @GetMapping("/getIncomeStatus/{userId}/{unitId}/{monthId}")
    public AjaxResult getSalaryStatus(@PathVariable String userId,@PathVariable String unitId,@PathVariable String monthId){
        String s = incomeMapper.selectIncomeStatus(userId, unitId, monthId);
        return AjaxResult.success(s);
    }

    @RequestMapping("/incomedownload")
    public String downloadsalaryFile(HttpServletResponse response) {
        try {
            // path是指欲下载的文件的路径。
//            String path = "C:\\Users\\Eric\\Desktop\\新建文件夹 (2)\\模板\\每月收入表-空白模板.xlsx";
            String path = "/usr/local/src/templates/每月收入表-模板.xlsx";
            File file = new File(path);
            // 取得文件名。
            String filename = file.getName();
            // 取得文件的后缀名。
            String ext = filename.substring(filename.lastIndexOf(".") + 1).toUpperCase();

            // 以流的形式下载文件。
            InputStream fis = new BufferedInputStream(new FileInputStream(path));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            // 清空response
            response.reset();
            // 设置response的Header
            response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes()));
            response.addHeader("Content-Length", "" + file.length());
            OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setContentType("application/json;charset=utf-8");
            response.setCharacterEncoding("utf-8");
            toClient.write(buffer);
            toClient.flush();
            toClient.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return null;
    }

    @RequestMapping("/balancedownload")
    public String downloadbanlanceFile(HttpServletResponse response) {
        try {
            // path是指欲下载的文件的路径。
//            String path = "C:\\Users\\Eric\\Desktop\\新建文件夹 (2)\\模板\\每月支援表-模板.xlsx";
            String path = "/usr/local/src/templates/每月支援表-模板.xlsx";
            File file = new File(path);
            // 取得文件名。
            String filename = file.getName();
            // 取得文件的后缀名。
            String ext = filename.substring(filename.lastIndexOf(".") + 1).toUpperCase();

            // 以流的形式下载文件。
            InputStream fis = new BufferedInputStream(new FileInputStream(path));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            // 清空response
            response.reset();
            // 设置response的Header
            response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes()));
            response.addHeader("Content-Length", "" + file.length());
            OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setContentType("application/json;charset=utf-8");
            response.setCharacterEncoding("utf-8");
            toClient.write(buffer);
            toClient.flush();
            toClient.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return null;
    }


    @PreAuthorize("@ss.hasPermi('balance:balanceupload:upload')")
    @PostMapping("/uploadbalance/{userId}/{unitId}/{monthId}")
    @Transactional
    public AjaxResult setBalanceInfo(@RequestBody String jsona,@PathVariable String userId,@PathVariable String unitId,@PathVariable String monthId){
        String userName = (String) RedisMapUtil.getMapUserIdToUserName().get(userId);
        balanceMapper.insertBalanceStatus(userId,userName,unitId,monthId);
//        System.out.println(jsona);
        Map<String,String> mapType = JSON.parseObject(jsona,Map.class);
//        System.out.println(mapType.get("GRZY").substring(1, mapType.get("GRZY").length() - 1).split("\\|"));
//        System.out.println(mapType.get("JJZY").substring(1, mapType.get("JJZY").length() - 1).split("\\|"));
        for (String s : mapType.get("GRZY").substring(1, mapType.get("GRZY").length() - 1).split(Constants.GROUPSPLIT)) {
            String[] split = s.substring(1, s.length() - 1).split(Constants.SMALLSPLIT);
            BalanceDay balanceDay = new BalanceDay();
            balanceDay.setAssistPerson(split[0]);
            balanceDay.setUserId(userId);
            balanceDay.setAssistUnit(split[1]);
            balanceDay.setBeAssistedUnit(split[2]);
            balanceDay.setAssistDate(split[3]);
            balanceDay.setStayType(split[4]);
            BigDecimal settlementAmount = new BigDecimal(split[5]);
            balanceDay.setSettlementAmount(settlementAmount);
            balanceDay.setUploadPerson(split[6]);
            if (split.length >= 8){
                balanceDay.setExplainInfo(split[7]);
            }else{
                balanceDay.setExplainInfo("");
            }
            balanceMapper.insertBalanceDay(balanceDay);
        }

        for (String s : mapType.get("JJZY").substring(1, mapType.get("JJZY").length() - 1).split(Constants.GROUPSPLIT)) {
            String[] split = s.substring(1, s.length() - 1).split(Constants.SMALLSPLIT);
            BalancePiece balancePiece = new BalancePiece();
            balancePiece.setAssistPerson(split[0]);
            balancePiece.setUserId(userId);
            balancePiece.setAssistUnit(split[1]);
            balancePiece.setBeAssistedUnit(split[2]);
            balancePiece.setAssistDate(split[3]);
            balancePiece.setStationAndPartAndWorkInfo(split[4]);
            balancePiece.setWorkType(split[5]);
            balancePiece.setWorkUnit(split[6]);
            BigDecimal amount = new BigDecimal(split[7]);
            balancePiece.setAmount(amount);
            BigDecimal unitPrice = new BigDecimal(split[8]);
            balancePiece.setUnitPrice(unitPrice);
            BigDecimal settlementAmount = new BigDecimal(split[9]);
            balancePiece.setSettlementAmount(settlementAmount);
            balancePiece.setUploadPerson(split[10]);
            if (split.length >= 12){
                balancePiece.setExplainInfo(split[11]);
            }else{
                balancePiece.setExplainInfo("");
            }
            balanceMapper.insertBalancePiece(balancePiece);
        }
        return AjaxResult.success();
    }

    @PreAuthorize("@ss.hasPermi('balance:balanceupload:upload')")
    @GetMapping("/getBalanceStatus/{userId}/{unitId}/{monthId}")
    public AjaxResult getBalanceStatus(@PathVariable String userId,@PathVariable String unitId,@PathVariable String monthId){
        String s = balanceMapper.selectBalanceStatus(userId, unitId, monthId);
        return AjaxResult.success(s);
    }

    @PreAuthorize("@ss.hasPermi('income:statictics')")
    @GetMapping("/getMonthStatics/{unitId}")
    public AjaxResult getMonthStatics(@PathVariable String unitId){
//        String yearMonth = DateUtils.getDate().replace("-","").substring(0,6);
//        String yearMonth = DateUtils.getDate().replace("-","").substring(0,6);
        List<String> monthsBetween = DateUtils.getMonthsBetween(DateUtils.getFullYear() + "-01", DateUtils.getDate().substring(0, 7));
        List<AmountStatics> amountStaticsResult = new ArrayList<>();
        String allStaticsInfo = getAllStaticsInfo();
        List<AmountStatics> amountStaticsList = JSONObject.parseArray(allStaticsInfo, AmountStatics.class);
        BigDecimal netProfit = new BigDecimal(0);
        BigDecimal Income = new BigDecimal(0);
        BigDecimal Cost = new BigDecimal(0);
        for (AmountStatics amountStatics : amountStaticsList) {
            for (String s : monthsBetween) {
                if (amountStatics.getUnit().equals(unitId) && amountStatics.getYearMonth().equals(s.replace("-",""))){
                    amountStaticsResult.add(amountStatics);
                }
            }
        }
        for (AmountStatics amountStatics : amountStaticsResult) {
            netProfit = netProfit.add(amountStatics.getNetProfit());
            Income = Income.add(amountStatics.getIncome());
            Cost = Cost.add(amountStatics.getCost());
        }

        AjaxResult ajaxResult = AjaxResult.success(amountStaticsResult);
        ajaxResult.put("netProfit",netProfit);
        ajaxResult.put("Income",Income);
        ajaxResult.put("Cost",Cost);
        ajaxResult.put("yearAndMonth",DateUtils.getFullYear()+"年01月"+"至"+DateUtils.getFullYearAndMonth().substring(0,4)+"年"+DateUtils.getFullYearAndMonth().substring(4,6)+"月");
        if (Income.doubleValue() == 0){
            ajaxResult.put("netProfitPersent",0);
        }else{
            ajaxResult.put("netProfitPersent",Income.subtract(Cost).divide(Income,2,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)));
        }
        return ajaxResult;
    }

    @PreAuthorize("@ss.hasPermi('income:statictics')")
    @GetMapping("/getMonthsStatics/{unitId}/{fromTo}")
    public AjaxResult getMonthsStatics(@PathVariable String unitId,@PathVariable String fromTo){
        List<String> monthBetween = getMonthBetween(fromTo.split(",")[0], fromTo.split(",")[1]).stream().peek(x -> x = x.replace("-", "")).collect(Collectors.toList());
        List<String> finalMonthBetween = new ArrayList<>();
        List<AmountStatics> finalAmount = new ArrayList<>();
        int flag = 0;
        for (String s : monthBetween) {
            finalMonthBetween.add(s.replace("-",""));
            flag++;
            if (Integer.parseInt(s.replace("-","")) > Integer.parseInt(DateUtils.getFullYearAndMonth())){
                return AjaxResult.error("不能查询未来的数据");
            }
        }

        if(flag <= 12){
            String allStaticsInfo = getAllStaticsInfo();
            List<AmountStatics> amountStaticsList = JSONObject.parseArray(allStaticsInfo, AmountStatics.class);
//            System.out.println(amountStaticsList);
            BigDecimal netProfit = new BigDecimal(0);
            BigDecimal Income = new BigDecimal(0);
            BigDecimal Cost = new BigDecimal(0);
            for (AmountStatics amountStatics : amountStaticsList) {
                for (String s : finalMonthBetween) {
                    if (amountStatics.getUnit().equals(unitId) && s.equals(amountStatics.getYearMonth())){
                        finalAmount.add(amountStatics);
                    }
                }
            }
            for (AmountStatics amountStatics : finalAmount) {
                netProfit = netProfit.add(amountStatics.getNetProfit());
                Income = Income.add(amountStatics.getIncome());
                Cost = Cost.add(amountStatics.getCost());
            }

            AjaxResult ajaxResult = AjaxResult.success(finalAmount);
            ajaxResult.put("netProfit",netProfit);
            ajaxResult.put("Income",Income);
            ajaxResult.put("Cost",Cost);
            if (Income.doubleValue() == 0){
                ajaxResult.put("netProfitPersent",0);
            }else{
                ajaxResult.put("netProfitPersent",Income.subtract(Cost).divide(Income,2,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)));
            }
            return ajaxResult;
        }else{
            return AjaxResult.error("只能查询一年以内的数据");
        }
    }

    public static String getAllStaticsInfo(){
//        Path path = Paths.get("H:\\AllStatics.txt");
        Path path = Paths.get("/usr/local/src/AllStatics.txt");
//        Path path = Paths.get("C:\\Users\\86180\\Desktop\\fsdownload\\AllStatics.txt");
        byte[] data = new byte[0];
        try {
            data = Files.readAllBytes(path);
        } catch (IOException e) {
            e.printStackTrace();
        }
        String result = new String(data, StandardCharsets.UTF_8);
        return result;
    }


    public static List<String> getMonthBetween(String minDate, String maxDate) {
        ArrayList<String> result = new ArrayList<String>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");// 格式化为年月
        try {
            Calendar min = Calendar.getInstance();
            Calendar max = Calendar.getInstance();

            min.setTime(sdf.parse(minDate));
            min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1);

            max.setTime(sdf.parse(maxDate));
            max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);

            Calendar curr = min;
            while (curr.before(max)) {
                result.add(sdf.format(curr.getTime()));
                curr.add(Calendar.MONTH, 1);
            }

            // 实现排序方法
            Collections.sort(result, new Comparator<Object>() {
                @Override
                public int compare(Object o1, Object o2) {
                    String str1 = (String) o1;
                    String str2 = (String) o2;
                    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
                    Date date1 = null;
                    Date date2 = null;
                    try {
                        date1 = format.parse(str1);
                        date2 = format.parse(str2);
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }

                    if (date2.compareTo(date1) > 0) {
                        return -1;
                    }
                    return 1;
                }
            });
        }catch (ParseException e) {
            e.printStackTrace();
        }
        return result;
    }




}
