package cn.ezhizao.project.business.keepAccounts.controller;

import cn.ezhizao.common.exception.ServiceException;
import cn.ezhizao.common.utils.SecurityUtils;
import cn.ezhizao.common.utils.poi.ExcelUtil;
import cn.ezhizao.framework.aspectj.lang.annotation.Log;
import cn.ezhizao.framework.aspectj.lang.enums.BusinessType;
import cn.ezhizao.framework.web.controller.BaseController;
import cn.ezhizao.framework.web.domain.AjaxResult;
import cn.ezhizao.framework.web.page.TableDataInfo;
import cn.ezhizao.project.business.company.domain.BizCompany;
import cn.ezhizao.project.business.company.service.IBizCompanyService;
import cn.ezhizao.project.business.keepAccounts.domain.BizFinancialKeepAccount;
import cn.ezhizao.project.business.keepAccounts.domain.BizFinancialKeepAccountDetail;
import cn.ezhizao.project.business.keepAccounts.service.IBizFinancialKeepAccountDetailService;
import cn.ezhizao.project.business.keepAccounts.service.IBizFinancialKeepAccountService;
import cn.ezhizao.project.business.receiveTicket.domain.BizFinancialReceiveTicketFeedback;
import cn.ezhizao.project.business.reportTaxIsZero.domain.BizFinancialReportTaxDetail;
import cn.ezhizao.project.business.reportTaxIsZero.domain.BizFinancialReportTax;
import cn.ezhizao.project.business.reportTaxIsZero.service.IBizFinancialReportTaxDetailService;
import cn.ezhizao.project.business.reportTaxIsZero.service.IBizFinancialReportTaxService;
import cn.ezhizao.project.business.workOrder.domain.BizWorkOrderRecord;
import cn.ezhizao.project.business.workOrder.service.IBizWorkOrderRecordService;
import cn.ezhizao.project.system.domain.SysUser;
import cn.ezhizao.project.system.mapper.SysUserMapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import reactor.util.annotation.Nullable;
import cn.ezhizao.framework.aspectj.lang.enums.BusinessType;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.sql.rowset.serial.SerialException;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@Api(tags = "收票 数据接口")
@RequestMapping(value = "/business/keepAccount")
public class BizFinancialKeepAccountController extends BaseController {

    @Resource
    IBizFinancialKeepAccountService financialKeepAccountService;
    @Resource
    IBizFinancialKeepAccountDetailService financialKeepAccountDetailService;
    @Resource
    IBizFinancialReportTaxService financialReportTaxService;
    @Resource
    private SysUserMapper sysUserMapper;
    @Resource
    IBizFinancialReportTaxDetailService financialReportTaxDetailService;
    @Resource
    IBizCompanyService companyService;
    @Resource
    IBizWorkOrderRecordService bizWorkOrderRecordService;

    @ApiOperation(value = "查询FinancialReceiveTicket", notes = "根据id查询Channel")
    @GetMapping("/getById/{id}")
    @ResponseBody
    public AjaxResult getById(@PathVariable Long id) {
        AjaxResult result;
        try {
            BizFinancialKeepAccount BizFinancialKeepAccount = financialKeepAccountService.getById(id);
            result = success(BizFinancialKeepAccount);
        } catch (Exception ex) {
            result = error(ex.getMessage());
        }
        return result;
    }

    @ApiOperation("根据id获得明细")
    @GetMapping("/getDetailById")
    @ResponseBody
    public AjaxResult getDetailById(@RequestParam @Nullable Long id, @RequestParam Long mainId, @RequestParam String year, @RequestParam String month) {
        BizFinancialKeepAccountDetail conditions = new BizFinancialKeepAccountDetail();
        conditions.setId(id);
        List<BizFinancialKeepAccountDetail> details = financialKeepAccountDetailService.getList(conditions);
        BizFinancialKeepAccount BizFinancialKeepAccount = financialKeepAccountService.getById(mainId);
        BizFinancialKeepAccountDetail detail = details.isEmpty() ? null : details.get(0);
        BizCompany company = companyService.getById(BizFinancialKeepAccount.getCompanyId());
        if (detail == null) {
            detail = new BizFinancialKeepAccountDetail();
            detail.setCompanyName(company.getName());
            detail.setYear(year);
            detail.setMonth(month);
            detail.setCompanyId(BizFinancialKeepAccount.getCompanyId());
            detail.setFinancialKeepAccountId(BizFinancialKeepAccount.getId());
        }
        Map<String, Object> map = new HashMap<>();
        map.put("detail", detail);
        BizFinancialReportTaxDetail financialReportTaxDetail = financialReportTaxDetailService.query().eq("company_id", BizFinancialKeepAccount.getCompanyId()).le("year", year).le("month", month).orderByDesc("year").orderByDesc("month").last("limit 1").one();
        if (financialReportTaxDetail != null) {
            map.put("previousAnnualLosses", financialReportTaxDetail.getPreviousAnnualLosses());
        }
        return success(map);
    }

    @PreAuthorize("@ss.hasAnyPermi('business:keepAccount:query,business:keepAccount:view')")
    @PostMapping("/getDetail")
    public AjaxResult getDetail(@RequestBody BizFinancialKeepAccountDetail detail) {
        List<BizFinancialKeepAccountDetail> keepAccountDetails = financialKeepAccountDetailService.getList(detail);
        BigDecimal previousAnnualLosses = new BigDecimal(0);
        BizFinancialReportTaxDetail financialReportTaxDetail = financialReportTaxDetailService.query().eq("company_id", detail.getCompanyId()).le("year", detail.getYear()).le("month", detail.getMonth()).orderByDesc("year").orderByDesc("month").last("limit 1").one();
        if (financialReportTaxDetail != null) {
            previousAnnualLosses = financialReportTaxDetail.getPreviousAnnualLosses();
        }
        if (keepAccountDetails.isEmpty()) {
            detail.setPreviousAnnualLosses(previousAnnualLosses);
            return success(detail);
        }
        keepAccountDetails.get(0).setPreviousAnnualLosses(previousAnnualLosses);
        return success(keepAccountDetails.get(0));
    }

    @ApiOperation(value = "带条件List 分页查询", notes = "带条件List 分页查询")
    @GetMapping("/list")
    @PreAuthorize("@ss.hasPermi('business:keepAccount:list')")
    @ResponseBody
    public TableDataInfo getList(BizFinancialKeepAccount conditions) throws NoSuchFieldException, IllegalAccessException {
        String chooseYear = conditions.getYear();
        int nwoYear = LocalDate.now().getYear();
        conditions.setYear(String.valueOf(nwoYear));
        setTenantId(conditions);
        startPage();
        startOrderBy();
        conditions.setIsZero(0);
        conditions.setYear(String.valueOf(nwoYear));
        List<BizFinancialKeepAccount> list = financialKeepAccountService.getList(conditions);
        if (!list.isEmpty()) {
            BizFinancialKeepAccountDetail detailConditions = new BizFinancialKeepAccountDetail();
            if (!chooseYear.equals(nwoYear)){
                detailConditions.setYear(chooseYear);
            }else {
                detailConditions.setYear(conditions.getYear());
            }
            detailConditions.setMainIds(list.stream().map(BizFinancialKeepAccount::getId).collect(Collectors.toList()));
            List<BizFinancialKeepAccountDetail> details = financialKeepAccountDetailService.getList(detailConditions);
            list.forEach(l -> {
                l.setDetails(details.stream().filter(v -> v.getFinancialKeepAccountId().equals(l.getId())).collect(Collectors.toList()));
            });
        }

        return getDataTable(list);
    }

    /**
     * 导出记账任务列表
     */
    @PreAuthorize("@ss.hasPermi('business:keepAccount:export')")
    @Log(title = "记账任务", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, BizFinancialKeepAccount conditions) throws NoSuchFieldException, IllegalAccessException
    {
        setTenantId(conditions);
        startOrderBy();
        conditions.setIsZero(0);
        List<BizFinancialKeepAccount> list = financialKeepAccountService.getList(conditions);
        for(BizFinancialKeepAccount l : list){
            BizFinancialKeepAccountDetail detail = new BizFinancialKeepAccountDetail();
            detail.setFinancialKeepAccountId(l.getId());
            detail.setYear(conditions.getYear());
            detail.setMonth(conditions.getMonth());
            List<BizFinancialKeepAccountDetail> details = financialKeepAccountDetailService.getList(detail);
            if(details.size() ==0){
                detail.setStatus(0);
                l.setServiceName("");
            }else {
                detail=details.get(0);
                BizFinancialReportTaxDetail financialReportTaxDetail = financialReportTaxDetailService.query().eq("company_id", l.getCompanyId()).le("year", detail.getYear()).le("month", detail.getMonth()).orderByDesc("year").orderByDesc("month").last("limit 1").one();
                l.setPreviousAnnualLosses(financialReportTaxDetail.getPreviousAnnualLosses());
                List<BizWorkOrderRecord> records = bizWorkOrderRecordService.query().eq("work_order_id", l.getWorkOrderId()).eq("year", conditions.getYear()).eq("month", conditions.getMonth()).eq("from_id", 0).list();
                if(records.size()>0){
                    SysUser sysUser = sysUserMapper.selectUserById(records.get(0).getRecorderId());
                    l.setServiceName(sysUser==null?"":sysUser.getNickName());
                }else{
                    l.setServiceName("");
                }
            }
            l.setCurrentPeriod(conditions.getYear()+"-"+conditions.getMonth());
            switch (detail.getStatus()){
                case 0:
                    l.setCurrentStatus("未开始");
                    break;
                case 1:
                    l.setCurrentStatus("进行中");
                    break;
                case 2:
                    l.setCurrentStatus("无票据");
                    break;
                case 3:
                    l.setCurrentStatus("已完成");
                    break;
                default:
                    break;
            }
        }
        ExcelUtil<BizFinancialKeepAccount> util = new ExcelUtil<BizFinancialKeepAccount>(BizFinancialKeepAccount.class);
        util.exportExcel(response, list, "记账任务数据");
    }

    @ApiOperation(value = "带条件List 分页查询", notes = "带条件List 分页查询")
    @PostMapping("/getDetailList")
    @ResponseBody
    public TableDataInfo getDetailList(@RequestBody BizFinancialKeepAccountDetail conditions) throws NoSuchFieldException, IllegalAccessException {
        setTenantId(conditions);
        Map<String, Object> map = new HashMap<>(16);
        List<BizFinancialKeepAccountDetail> list = financialKeepAccountDetailService.getList(conditions);
        return getDataTable(list);
    }

    @ApiOperation(value = "删除Channel", notes = "根据id删除Channel")
    @DeleteMapping("/deleteById/{id}")
    @ResponseBody
    public AjaxResult deleteById(@PathVariable Long id) {
        try {
            if (financialKeepAccountService.removeById(id)) {
                return success();
            } else {
                return error();
            }
        } catch (Exception e) {
            throw new ServiceException(e.getMessage());
        }
    }

    @ApiOperation(value = "整体保存", notes = "整体保存")
    @PostMapping("/save")
    @Transactional(rollbackFor = Exception.class)
    @ResponseBody
    public AjaxResult save(@RequestBody BizFinancialKeepAccount BizFinancialKeepAccount) throws SerialException {
        AjaxResult result = null;
        Map<String, Object> map = new HashMap<>(16);
        try {
            boolean bool = financialKeepAccountService.saveOrUpdate(BizFinancialKeepAccount);
            if (!bool) {
                throw new RuntimeException("保存主订单发生错误!");
            }
            map.put("id", BizFinancialKeepAccount.getId());
            result = success(map);
        } catch (Exception e) {
            throw new SerialException(e.getMessage());
        }
        return result;
    }

    @ApiOperation("审核")
    @PostMapping("/verify")
    @Transactional(rollbackFor = Exception.class)
    @ResponseBody
    public AjaxResult verify(@RequestBody BizFinancialKeepAccountDetail detail) {
        if (detail.getStatus().equals(3)) {
            QueryWrapper<BizFinancialReportTax> qw = new QueryWrapper<>();
            qw.eq("company_id", detail.getCompanyId());

            BizFinancialReportTax financialReportTax = financialReportTaxService.getOne(qw);
            if (financialReportTax != null) {
                QueryWrapper<BizFinancialReportTaxDetail> kqw = new QueryWrapper<>();
                kqw.eq("financial_report_tax_id", financialReportTax.getId());
                kqw.eq("year", detail.getYear());
                kqw.eq("month", detail.getMonth());
                BizFinancialReportTaxDetail financialReportTaxDetail =
                        financialReportTaxDetailService.getOne(kqw);
                if (financialReportTaxDetail == null) {
                    financialReportTaxDetail = new BizFinancialReportTaxDetail();
                }
                financialReportTaxDetail.setFinancialReportTaxId(financialReportTax.getId());
                financialReportTaxDetail.setYear(detail.getYear());
                financialReportTaxDetail.setMonth(detail.getMonth());
                financialReportTaxDetail.setCompanyId(detail.getCompanyId());
                financialReportTaxDetail.setStatus(financialReportTaxDetail.getStatus() != null && financialReportTaxDetail.getStatus() > 1 ? financialReportTaxDetail.getStatus() : 1);
//                financialKeepAccountDetailService.saveOrUpdate(BizFinancialKeepAccountDetail);
                if (financialReportTaxDetail.getId() == null) {
                    financialReportTaxDetailService.save(financialReportTaxDetail);
                } else {
                    financialReportTaxDetailService.updateById(financialReportTaxDetail);
                }
            }
        }
        return financialKeepAccountDetailService.saveOrUpdate(detail) ? success() : error();
//        return error();
    }

    @PreAuthorize("@ss.hasPermi('business:keepAccount:edit')")
    @PostMapping("/saveDetail")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult saveDetail(@RequestBody BizFinancialKeepAccountDetail receiveTicketDetail) {
        // 判断之前是否有保存一个明细
        BizFinancialKeepAccountDetail conditions = new BizFinancialKeepAccountDetail();
        conditions.setFinancialKeepAccountId(receiveTicketDetail.getFinancialKeepAccountId());
        conditions.setYear(receiveTicketDetail.getYear());
        conditions.setMonth(receiveTicketDetail.getMonth());
        if (!financialKeepAccountDetailService.getList(conditions).isEmpty()) {
            return error("该月已添加收票信息,请刷新列表。");
        }

        receiveTicketDetail.setVerifierTime(new Date());
        receiveTicketDetail.setVerifierId(SecurityUtils.getUserId());
        return toAjax(financialKeepAccountDetailService.save(receiveTicketDetail) && addRecord(receiveTicketDetail.getFinancialKeepAccountId(), receiveTicketDetail.getYear(), receiveTicketDetail.getMonth(), SecurityUtils.getUserId(), "填写记账信息"));
    }

    @PreAuthorize("@ss.hasPermi('business:keepAccount:edit')")
    @PostMapping("/updateDetail")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult updateDetail(@RequestBody BizFinancialKeepAccountDetail bizFinancialSalaryDetail) {
        return toAjax(financialKeepAccountDetailService.updateById(bizFinancialSalaryDetail) && addRecord(bizFinancialSalaryDetail.getFinancialKeepAccountId(), bizFinancialSalaryDetail.getYear(), bizFinancialSalaryDetail.getMonth(), SecurityUtils.getUserId(), "修改记账信息"));
    }

    @PreAuthorize("@ss.hasPermi('business:keepAccount:return')")
    @PostMapping("/turnBackDetail")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult turnBackDetail(@RequestBody BizFinancialKeepAccountDetail detail) {
        // 先判断是否记账完成，记账完成状态不能进行工资退回
//        BizFinancialKeepAccountDetail keepAccountDetail = financialKeepAccountDetailService.query().eq("company_id", detail.getCompanyId()).eq("year", detail.getYear()).eq("month", detail.getMonth()).one();
//        if (keepAccountDetail != null && keepAccountDetail.getStatus() == 3) {
//            return error("请先进行记账退回操作再进行工资退回。");
//        } else {
//            detail.setStatus(2);
//        }
        return toAjax(financialKeepAccountDetailService.updateById(detail) && addRecord(detail.getFinancialKeepAccountId(), detail.getYear(), detail.getMonth(), SecurityUtils.getUserId(), "记账退回"));
    }

    private boolean addRecord(Long financialReceiveTicketId, String year, String month, Long recorderId, String description) {
        // 没拆分合同单价
        BizFinancialKeepAccount receiveTicket = financialKeepAccountService.getById(financialReceiveTicketId);
        Long workOrderId = receiveTicket.getWorkOrderId();
        List<BizWorkOrderRecord> records = bizWorkOrderRecordService.query().eq("work_order_id", workOrderId).eq("year", year).eq("month", month).eq("from_id", 0).list();
        if (records.isEmpty()) {
            // 新增一条记录
            BizWorkOrderRecord record = new BizWorkOrderRecord();
            record.setMonth(month);
            record.setYear(year);
            record.setTenantId(getTenantId());
            record.setWorkOrderId(workOrderId);
            record.setCompanyId(receiveTicket.getCompanyId());
            record.setStatus(1);
            record.setStatusDescript(description);
            record.setRecorderId(recorderId);
            return bizWorkOrderRecordService.save(record);
        } else {
            // 新增一条子记录
            Long fromId = records.get(0).getId();
            BizWorkOrderRecord fromRecord = records.get(0);
            BizWorkOrderRecord record = new BizWorkOrderRecord();
            record.setFromId(fromId);
            record.setMonth(fromRecord.getMonth());
            record.setYear(fromRecord.getYear());
            record.setTenantId(fromRecord.getTenantId());
            record.setCompanyId(receiveTicket.getCompanyId());
            record.setWorkOrderId(fromRecord.getWorkOrderId());
            record.setStatus(fromRecord.getStatus());
            record.setStatusDescript(fromRecord.getStatusDescript());
            record.setRecorderId(fromRecord.getRecorderId());

            fromRecord.setMonth(month);
            fromRecord.setYear(year);
            fromRecord.setTenantId(getTenantId());
            fromRecord.setWorkOrderId(workOrderId);
            record.setCompanyId(receiveTicket.getCompanyId());
            fromRecord.setStatus(1);
            fromRecord.setStatusDescript(description);
            fromRecord.setRecorderId(recorderId);
            return bizWorkOrderRecordService.save(record) &&
                    bizWorkOrderRecordService.updateById(fromRecord);
        }
    }

}
