package cn.ezhizao.project.business.finance.IndividualIncomeTax.controller;

import cn.ezhizao.common.utils.SecurityUtils;
import cn.ezhizao.common.utils.StringUtils;
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.lock.DistributionLock;
import cn.ezhizao.framework.lock.LockKey;
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.deduction.domain.BizDeduction;
import cn.ezhizao.project.business.deduction.service.IBizDeductionService;
import cn.ezhizao.project.business.entrust.domain.BizEntrust;
import cn.ezhizao.project.business.entrust.service.IBizEntrustService;
import cn.ezhizao.project.business.finance.IndividualIncomeTax.domain.BizFinancialIndividualIncomeTax;
import cn.ezhizao.project.business.finance.IndividualIncomeTax.domain.BizFinancialIndividualIncomeTaxDetail;
import cn.ezhizao.project.business.finance.IndividualIncomeTax.service.IBizFinancialIndividualIncomeTaxDetailService;
import cn.ezhizao.project.business.finance.IndividualIncomeTax.service.IBizFinancialIndividualIncomeTaxService;
import cn.ezhizao.project.business.finance.IndividualIncomeTaxIsZero.domain.BizFinancialIndividualIncomeTaxDetailIsZero;
import cn.ezhizao.project.business.finance.IndividualIncomeTaxIsZero.service.IBizFinancialIndividualIncomeTaxDetailIsZeroService;
import cn.ezhizao.project.business.financialBase.domain.BizFinancialMerge;
import cn.ezhizao.project.business.financialBase.service.IBizFinancialMergeService;
import cn.ezhizao.project.business.history.domain.BizHistory;
import cn.ezhizao.project.business.history.service.IBizHistoryService;
import cn.ezhizao.project.business.reportTaxIsZero.domain.BizFinancialReportTaxDetail;
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.SysFileStorage;
import cn.ezhizao.project.system.service.ISysFileStorageService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 个税详情Controller
 *
 * @author ruoyi
 * @date 2023-11-17
 */
@RestController
@RequestMapping("/business/individualIncomeTaxDetail")
public class BizFinancialIndividualIncomeTaxDetailController extends BaseController {
    @Resource
    private IBizFinancialIndividualIncomeTaxDetailService bizFinancialIndividualIncomeTaxDetailService;

    @Resource
    private IBizFinancialIndividualIncomeTaxService bizFinancialIndividualIncomeTaxService;

    @Resource
    private IBizFinancialReportTaxService financialReportTaxService;
    @Resource
    private IBizFinancialReportTaxDetailService financialReportTaxDetailService;

    @Resource
    IBizFinancialMergeService financialMergeService;

    @Resource
    IBizFinancialIndividualIncomeTaxDetailIsZeroService financialIndividualIncomeTaxDetailService;

    @Resource
    private IBizWorkOrderRecordService bizWorkOrderRecordService;

    @Resource
    IBizDeductionService deductionService;

    @Resource
    private ISysFileStorageService fileStorageService;

    @Resource
    private IBizEntrustService bizEntrustService;

    @Resource
    IBizCompanyService companyService;

    @Resource
    private IBizHistoryService bizHistoryService;
    /**
     * 查询个税详情列表
     */
    @PreAuthorize("@ss.hasPermi('business:individualIncomeTaxDetail:list')")
    @GetMapping("/list")
    public TableDataInfo list(BizFinancialIndividualIncomeTaxDetail bizFinancialIndividualIncomeTaxDetail) throws NoSuchFieldException, IllegalAccessException {
        setTenantId(bizFinancialIndividualIncomeTaxDetail);
        startPage();
        List<BizFinancialIndividualIncomeTaxDetail> list = bizFinancialIndividualIncomeTaxDetailService.getList(bizFinancialIndividualIncomeTaxDetail);
        return getDataTable(list);
    }

    /**
     * 导出个税详情列表
     */
    @PreAuthorize("@ss.hasPermi('business:individualIncomeTaxDetail:export')")
    @Log(title = "个税详情", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, BizFinancialIndividualIncomeTaxDetail bizFinancialIndividualIncomeTaxDetail) throws NoSuchFieldException, IllegalAccessException {
        setTenantId(bizFinancialIndividualIncomeTaxDetail);
        List<BizFinancialIndividualIncomeTaxDetail> list = bizFinancialIndividualIncomeTaxDetailService.getList(bizFinancialIndividualIncomeTaxDetail);
        ExcelUtil<BizFinancialIndividualIncomeTaxDetail> util = new ExcelUtil<BizFinancialIndividualIncomeTaxDetail>(BizFinancialIndividualIncomeTaxDetail.class);
        util.exportExcel(response, list, "个税详情数据");
    }

    /**
     * 获取个税详情详细信息
     */
    @PreAuthorize("@ss.hasPermi('business:individualIncomeTaxDetail:query')")
    @GetMapping(value = "/{id}/{year}/{month}")
    public AjaxResult getInfo(@PathVariable("id") Long financialIndividualIncomeTaxId, @PathVariable("year") String year, @PathVariable("month") String month) {
        int nowYear = LocalDate.now().getYear();
        int nowMonth = LocalDate.now().getMonthValue() - 1;
        String formattedMonth = String.format("%02d", nowMonth);
        BizFinancialIndividualIncomeTaxDetail biz = bizFinancialIndividualIncomeTaxDetailService.getOne(new LambdaQueryWrapper<BizFinancialIndividualIncomeTaxDetail>()
                .eq(BizFinancialIndividualIncomeTaxDetail::getFinancialIndividualIncomeTaxId, financialIndividualIncomeTaxId)
                .eq(BizFinancialIndividualIncomeTaxDetail::getYear, year)
                .eq(BizFinancialIndividualIncomeTaxDetail::getMonth, month));
        String s1 = year + month;
        String s2 = nowYear + formattedMonth;
        if (s1.equals(s2) && biz == null) {
            return success(new BizFinancialIndividualIncomeTaxDetail());
        }
        if (biz == null) {
            return error("当前月未找到数据");
        }
        List<SysFileStorage> files = bizFinancialIndividualIncomeTaxDetailService.getFiles(biz.getId());
        if (CollectionUtils.isEmpty(files)) {
            ArrayList<SysFileStorage> objects = new ArrayList<>();
            if (StringUtils.isNotEmpty(biz.getReportFile())) {
                SysFileStorage sysFileStorage = new SysFileStorage();
                sysFileStorage.setFileUrl(biz.getReportFile());
                String[] parts = splitFileName(biz.getReportFile());
                sysFileStorage.setFileName(parts[0]);
                sysFileStorage.setOriginalFileName(parts[1]);
                objects.add(sysFileStorage);
                biz.setReportFiles(objects);
                return success(biz);
            }
        }
        Long id = biz.getFinancialIndividualIncomeTaxId();
        Long workOrderId = bizFinancialIndividualIncomeTaxService.getById(id).getWorkOrderId();
        String s3 = year +"-"+ month+ "-01";
        BizEntrust one = bizEntrustService.getOne(new LambdaQueryWrapper<BizEntrust>()
                .eq(BizEntrust::getWorkOrderId, workOrderId)
                .eq(BizEntrust::getDeleted, 0)
                .eq(BizEntrust::getCurrentMonth, s3 ).orderByDesc(BizEntrust::getCreateTime).last("limit 1"));
        biz.setEntrust(one);
        biz.setReportFiles(bizFinancialIndividualIncomeTaxDetailService.getFiles(biz.getId()));
        return success(biz);
    }

    public String[] splitFileName(String filePath) {
        // 从路径中获取文件名部分
        String[] pathParts = filePath.split("/");
        String fileNameWithExtension = pathParts[pathParts.length - 1]; // 获取最后一部分，即文件名部分

        // 从文件名中去除时间戳部分
        int dotIndex = fileNameWithExtension.lastIndexOf('.');
        String fileName = fileNameWithExtension.substring(0, dotIndex); // 获取文件名（不含扩展名）
        String extension = fileNameWithExtension.substring(dotIndex); // 获取扩展名

        // 去除时间戳部分
        int underscoreIndex = fileName.lastIndexOf('_');
        if (underscoreIndex != -1) {
            String originalFilename = fileName.substring(0, underscoreIndex) + extension;
            return new String[]{fileNameWithExtension, originalFilename};
        } else {
            return new String[]{fileNameWithExtension, fileNameWithExtension}; // 如果没有找到时间戳，则原始文件名与文件名相同
        }
    }

    @PreAuthorize("@ss.hasPermi('business:individualIncomeTaxDetail:saveDetail')")
    @ApiOperation("保存detail")
    @Log(title = "个税详情", businessType = BusinessType.UPDATE)
    @PostMapping()
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult saveDetail(@RequestBody BizFinancialIndividualIncomeTaxDetail bizFinancialIndividualIncomeTaxDetail) throws NoSuchFieldException, IllegalAccessException {
        String join = LockKey.join(LockKey.INCOMETAX, getUserId());
        DistributionLock lock = new DistributionLock(join);
        try {
            lock.lock();
            String status = "";
            bizFinancialIndividualIncomeTaxDetail.setVerifierId(getUserId());
            bizFinancialIndividualIncomeTaxDetail.setVerifierTime(new Date());
            boolean bool = bizFinancialIndividualIncomeTaxDetailService.saveOrUpdate(bizFinancialIndividualIncomeTaxDetail);
            switch (bizFinancialIndividualIncomeTaxDetail.getStatus()) {
                case 0:
                    status = "个税未开始";
                    break;
                case 1:
                    status = "个税进行中";
                    break;
                case 3:
                    status = "个税已完成";
                    break;
            }
            bizFinancialIndividualIncomeTaxDetail.setVerifierId(getUserId());
            List<SysFileStorage> fileStorages = bizFinancialIndividualIncomeTaxDetail.getReportFiles();
            bool = bool && checkDeduction(bizFinancialIndividualIncomeTaxDetail);
            fileStorages.forEach(l -> {
                l.setMasterId(bizFinancialIndividualIncomeTaxDetail.getId());
                l.setMasterTableName("biz_financial_individual_income_tax_detail");
            });
            SysFileStorage delConditions = new SysFileStorage();
            delConditions.setMasterId(bizFinancialIndividualIncomeTaxDetail.getId());
            delConditions.setMasterTableName("biz_financial_individual_income_tax_detail");
            fileStorageService.physicalDelete(delConditions);
            bool = bool && (fileStorages.isEmpty() || fileStorageService.saveOrUpdateBatch(fileStorages));
            BizHistory bizHistory = new BizHistory();
            bizHistory.setTableName("biz_financial_individual_income_tax");
            bizHistory.setCompanyId(bizFinancialIndividualIncomeTaxDetail.getCompanyId());
            bizHistory.setEvent("保存");
            bizHistory.setTenantId(getTenantId());
            bizHistory.setBelongPeriod(bizFinancialIndividualIncomeTaxDetail.getYear() + "-" + String.format("%02d", Integer.valueOf(bizFinancialIndividualIncomeTaxDetail.getMonth())));
            bizHistoryService.save(bizHistory);
            return toAjax(addRecord(bizFinancialIndividualIncomeTaxDetail.getFinancialIndividualIncomeTaxId(),
                    bizFinancialIndividualIncomeTaxDetail.getYear(), bizFinancialIndividualIncomeTaxDetail.getMonth(), SecurityUtils.getUserId(), status) && bool);
        } catch (Exception e) {
            e.printStackTrace();
            return error("保存失败");
        } finally {
            lock.unlock();
        }
    }


    private Boolean checkDeduction(BizFinancialIndividualIncomeTaxDetail detail) {
        // 判断当前月是否报税
        // 20230915 假设未报税也插入一条税款，合并税款记录中的是否可扣款未0
        // 判断是否有一条merge
        boolean bool;
        BizFinancialIndividualIncomeTax individualIncomeTax = bizFinancialIndividualIncomeTaxService.getById(detail.getFinancialIndividualIncomeTaxId());

        QueryWrapper<BizFinancialReportTaxDetail> reportTaxDetailQueryWrapper = new QueryWrapper<>();
        reportTaxDetailQueryWrapper.eq("company_id", detail.getCompanyId());
        reportTaxDetailQueryWrapper.eq("year", detail.getYear());
        reportTaxDetailQueryWrapper.eq("month", detail.getMonth());
        reportTaxDetailQueryWrapper.eq("status", 3);
        BizFinancialReportTaxDetail reportTaxDetail = financialReportTaxDetailService.getOne(reportTaxDetailQueryWrapper);

        List<BizFinancialMerge> financialMerges = financialMergeService.query().eq("financial_individual_income_tax_detail_id", detail.getId()).or().eq(reportTaxDetail != null, "financial_report_tax_detail_id", reportTaxDetail == null ? 0L : reportTaxDetail.getId()).list();

        List<BizDeduction> deductions;
        if (financialMerges.isEmpty()) {
            deductions = new ArrayList<>();
        } else {
            deductions = deductionService.query().in("source_id", financialMerges.stream().map(BizFinancialMerge::getId).collect(Collectors.toList())).list();
        }
        BigDecimal amount = reportTaxDetail == null ? detail.getAmount() == null ? BigDecimal.ZERO : detail.getAmount() : reportTaxDetail.getSumTax().add(detail.getAmount() == null ? BigDecimal.ZERO : detail.getAmount());
        if (amount.doubleValue() > 0) {
            if (deductions.isEmpty()) {
                BizFinancialMerge financialMerge = financialMerges.isEmpty() ? new BizFinancialMerge() : financialMerges.get(0);
                financialMerge.setFinancialReportTaxDetailId(reportTaxDetail == null ? 0L : reportTaxDetail.getId());
                financialMerge.setFinancialIndividualIncomeTaxDetailId(detail.getId());
                financialMerge.setType("税款");
                bool = financialMerge.getId() == null ? financialMergeService.save(financialMerge) : financialMergeService.updateById(financialMerge);
                BizDeduction deduction = new BizDeduction();
                deduction.setDeductible(financialMerge.getFinancialIndividualIncomeTaxDetailId().equals(0L) || financialMerge.getFinancialReportTaxDetailId().equals(0L) ? 0 : 1);
                deduction.setSourceName("税款");
                deduction.setSourceTableName("financial_merge");
                deduction.setAmount(reportTaxDetail == null ? detail.getAmount() == null ? BigDecimal.ZERO : detail.getAmount() : reportTaxDetail.getSumTax().add(detail.getAmount() == null ? BigDecimal.ZERO : detail.getAmount()));
                deduction.setYear(detail.getYear());
                deduction.setMonth(detail.getMonth());
                deduction.setSourceId(financialMerge.getId());
                deduction.setCompanyId(detail.getCompanyId());
                BizCompany company = companyService.getById(detail.getCompanyId());
                deduction.setTenantId(company.getTenantId());
                deduction.setWorkOrderId(individualIncomeTax.getWorkOrderId());
                return bool && deductionService.save(deduction);
            } else {
                BizFinancialMerge financialMerge = financialMerges.get(0);
                financialMerge.setFinancialReportTaxDetailId(reportTaxDetail == null ? 0L : reportTaxDetail.getId());
                financialMerge.setFinancialIndividualIncomeTaxDetailId(detail.getId());
                financialMerge.setType("税款");
                bool = financialMerge.getId() == null ? financialMergeService.save(financialMerge) : financialMergeService.updateById(financialMerge);
                BizDeduction deduction = deductions.get(0);
                deduction.setDeductible(financialMerge.getFinancialIndividualIncomeTaxDetailId().equals(0L) || financialMerge.getFinancialReportTaxDetailId().equals(0L) ? 0 : 1);
                deduction.setSourceName("税款");
                deduction.setSourceTableName("financial_merge");
                deduction.setAmount(reportTaxDetail == null ? detail.getAmount() == null ? BigDecimal.ZERO : detail.getAmount() : reportTaxDetail.getSumTax().add(detail.getAmount() == null ? BigDecimal.ZERO : detail.getAmount()));
                deduction.setYear(detail.getYear());
                deduction.setMonth(detail.getMonth());
                deduction.setSourceId(financialMerge.getId());
                deduction.setCompanyId(detail.getCompanyId());
                BizCompany company = companyService.getById(detail.getCompanyId());
                deduction.setTenantId(company.getTenantId());
                deduction.setWorkOrderId(individualIncomeTax.getWorkOrderId());
                return bool && deductionService.updateById(deduction);
            }
        }
        return true;
    }

    @ApiOperation("退回")
    @PostMapping("/deductionTurnBack")
    @PreAuthorize("@ss.hasPermi('business:individualIncomeTaxDetail:deductionTurnBack')")
    @Transactional(rollbackFor = Exception.class)
    @Log(title = "个税详情-退回", businessType = BusinessType.UPDATE)
    @ResponseBody
    public AjaxResult deductionTurnBack(@RequestBody BizFinancialIndividualIncomeTaxDetail detail) {
        detail.setStatus(1);
        QueryWrapper<BizFinancialMerge> qw = new QueryWrapper<>();
        qw.eq("financial_individual_income_tax_detail_id", detail.getId());
        BizFinancialMerge merge = financialMergeService.getOne(qw);
        if (merge != null) {
            merge.setFinancialIndividualIncomeTaxDetailId(0L);
            if (merge.getFinancialIndividualIncomeTaxDetailId().equals(0L) && merge.getFinancialReportTaxDetailId().equals(0L)) {
                removeDeductionByMerge(merge);
            } else {
                BizFinancialReportTaxDetail financialReportTaxDetail = financialReportTaxDetailService.getById(merge.getFinancialReportTaxDetailId());
                if (financialReportTaxDetail.getSumTax().doubleValue() > 0) {
                    financialMergeService.updateById(merge);
                    BizDeduction deduction = deductionService.getOne(Wrappers.<BizDeduction>lambdaQuery().eq(BizDeduction::getSourceTableName, "financial_merge").eq(BizDeduction::getSourceId, merge.getId()));
                    deduction.setDeductible(0);
                    deductionService.updateById(deduction);
                } else {
                    removeDeductionByMerge(merge);
                }
            }
        }
        //非零申报
        BizHistory bizHistory2 = new BizHistory();
        bizHistory2.setTableName("biz_financial_individual_income_tax");
        bizHistory2.setCompanyId(detail.getCompanyId());
        bizHistory2.setEvent("退回");
        bizHistory2.setReason(detail.getRefuseReason());
        bizHistory2.setTenantId(getTenantId());
        bizHistory2.setBelongPeriod(detail.getYear() + "-" + String.format("%02d", Integer.valueOf(detail.getMonth())) );
        bizHistoryService.save(bizHistory2);


        return bizFinancialIndividualIncomeTaxDetailService.updateById(detail) ? success() : error();
    }

    private boolean removeDeductionByMerge(BizFinancialMerge merge) {
        Map<String, Object> delCondition = new HashMap<>(2);
        delCondition.put("id", merge.getId());
        List<BizDeduction> deductions = deductionService.query().eq("source_table_name", "financial_merge").eq("source_id", merge.getId()).list();
        if (deductions.isEmpty()) {
            return false;
        } else {
            return financialMergeService.physicallyDelete(delCondition) > 0 && deductionService.removeBatchByIds(deductions.stream().map(BizDeduction::getId).collect(Collectors.toList()));
        }
    }


    /**
     * 删除个税详情
     */
    @PreAuthorize("@ss.hasPermi('business:individualIncomeTaxDetail:remove')")
    @Log(title = "个税详情", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable List<Long> ids) {
        return toAjax(bizFinancialIndividualIncomeTaxDetailService.removeBatchByIds(ids));
    }

    private boolean addRecord(Long bizFinancialSalaryId, String year, String month, Long recorderId, String description) {
        // 获取个税任务信息
        BizFinancialIndividualIncomeTax bizFinancialSalary = bizFinancialIndividualIncomeTaxService.getById(bizFinancialSalaryId);

        //查询work_order_id
        Long workOrderId = bizFinancialSalary.getWorkOrderId();

        //查询在biz_work_order_record表中是否有数据
        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.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.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);
            fromRecord.setStatus(1);
            fromRecord.setStatusDescript(description);
            fromRecord.setRecorderId(recorderId);
            return bizWorkOrderRecordService.save(record) &&
                    bizWorkOrderRecordService.updateById(fromRecord);
        }
    }
}
