/*
 * @Author: Kane
 * @Date: 2023-10-08 15:02:15
 * @LastEditors: Kane
 * @FilePath: /desktop_archievement_backend/src/main/java/com/cpic/xim/utils/data/ImportBIExcelData.java
 * @Description: 坐席业绩相关的数据操作方法。
 * 
 * Copyright (c) ${2023} by Kane, All Rights Reserved. 
 */
package com.cpic.xim.utils.data;

import java.io.File;
import java.io.IOException;
import java.time.LocalDate;
import java.util.ArrayList;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.cpic.xim.mybatis.pojo.BIDepartmentAttachingRateRecord;
import com.cpic.xim.mybatis.pojo.BIDepartmentRenewalRateRecord;
import com.cpic.xim.mybatis.pojo.BITelsalerAttachingRateRecord;
import com.cpic.xim.mybatis.pojo.BITelsalerRenewalRateRecord;
import com.cpic.xim.utils.poi.MyPOIUtils;

/**
 * 坐席业绩相关的数据操作方法。
 */
public final class ImportBIExcelData
{
    private static Logger logger = LoggerFactory.getLogger( ImportBIExcelData.class );

    // 坐席 渗透率
    private static String[] TelsalerAttachingRateExcelTitle = new String[]
    { "部门", "经办", "车险保费(万)", "车险保费占比", "非车保费(万)", "当月保费渗透率", "保费渗透率环比上月", "当月客户渗透率", "客户渗透率环比上月",
            "当月车非客均保费", "客均保费环比上月"};

    // 坐席 续保率
    private static String[] TelSalerRenewalRateExcelTitle = new String[]
    { "责任部门", "责任人", "机构目标值1(%)", "到期数-全月", "序时到期数占比(%)", "个车续保率（序时）(%)", "个车续保率（全月）(%)", "环比昨日(%)",
            "环比上月(%)", "序时-部门内", "全月-部门内"};

    // 机构 渗透率
    private static String[] DepartmentAttachingRateExcelTitle = new String[]
    { "部门", "目标值-机构", "目标差距", "车险保费(万)", "车险保费占比", "非车保费(万)", "当月保费渗透率", "保费渗透率环比上月", "车险客户数", "当月客户渗透率",
            "客户渗透率环比上月", "当月车非客均保费", "客均保费环比上月"};
    // 机构 续保率
    private static String[] DepartmentRenewalRateExcelTitle = new String[]
    { "责任部门", "机构目标值1(%)", "到期数-全月", "序时到期数占比(%)", "个车续保率（序时）(%)", "个车续保率（全月）(%)", "环比昨日(%)",
            "环比上月(%)", "序时-部门内", "全月-部门内",};

    /**
     * 用于通过对比标题行判断excel文件格式的函数。
     * @param sheet
     * @param caption 标题行文字
     * @param captionRowIndex 标题行索引
     * @param title 字段行文字数组
     * @param titleRowIndex 字段行索引
     * @return 返回判断结果
     */
    private static boolean checkExcelFormat( Sheet sheet, String caption, int captionRowIndex,
            String[] title, int titleRowIndex )
    {
        boolean result = true;

        Row captionRow = sheet.getRow( captionRowIndex );
        Row titleRow = sheet.getRow( titleRowIndex );

        if ( caption != null && !caption.isEmpty() )
        {
            try
            {
                int captionCellNum = captionRow.getFirstCellNum();
                String captionString = MyPOIUtils.getStringCellValue( captionRow, captionCellNum );

                if ( !caption.equals( captionString ) )
                {
                    result = false;
                }
            }
            catch ( NullPointerException error )
            {
                result = false;
            }
        }

        if ( title.length != 0 )
        {
            int cellIndex = 0;

            try
            {
                for ( Cell cell : titleRow )
                {
                    String cellString = MyPOIUtils.getStringCellValue( cell );
                    
                    logger.info( "比较报表标题行，待导入报表标题：" + cellString + "；验证标题：" + title[cellIndex] );

                    if ( !cellString.equals( title[cellIndex] ) )
                    {
                        result = false;
                        break;
                    }

                    cellIndex++;
                }
            }
            catch ( NullPointerException error )
            {
                result = false;
            }
        }

        return result;
    }

    /**
     * 从excel文件读取坐席的车非渗透率数据
     * @param filePath 文件路径
     * @param SheetIndex sheet索引
     * @param firstRow 数据起始行
     * @return 返回一个ArrayList保存的TelsalerAttachingRateRecord记录数组。
     * @throws IOException 打开excel文件错误时抛出。
     * @throws InvalidFormatException excel单元格格式错误时抛出
     */
    public static ArrayList<BITelsalerAttachingRateRecord> importBITelsalerAttachingRateRecordFromXlsx(
            String filePath, int SheetIndex, int firstRow )
            throws IOException, InvalidFormatException
    {
        ArrayList<BITelsalerAttachingRateRecord> records = new ArrayList<>( 200 );

        Workbook wb = null;
        Sheet sheet = null;
        String name = null;
        String departmentName = null;
        String departmentCurrentRow = null;

        try
        {
            wb = WorkbookFactory.create( new File( filePath ) );
            sheet = wb.getSheetAt( SheetIndex );

            // 先验证格式，不对就抛出错误
            if ( !checkExcelFormat( sheet, null, 0, TelsalerAttachingRateExcelTitle, 0 ) )
            {
                throw new InvalidFormatException( "Excel文件格式错误，请检查报表内容！" );
            }

            for ( Row row : sheet )
            {

                int rowIndex = row.getRowNum();

                // 从数据行开始
                if ( row.getRowNum() < firstRow )
                {
                    continue;
                }

                try
                {
                    // 部门
                    try
                    {
                        departmentCurrentRow = MyPOIUtils.getStringCellValue( row, 0 );

                        // 因为是合并列，所以要判断一下是不是空的
                        if ( !departmentCurrentRow.equals( "" )
                                && !departmentCurrentRow.equals( "合计" ) )
                        {
                            // 不是空的，也不是合计，说明是新部门的数据，更新部门名称
                            departmentName = departmentCurrentRow;
                        }
                    }
                    catch ( NullPointerException error )
                    {
                        // cell是空的，说明还是上一行的部门
                    }

                    // 坐席名称
                    name = MyPOIUtils.getStringCellValue( row, 1 );

                    // 忽略坐席名称为空的行
                    if ( name.equals( "全流程" ) || name.equals( "其他" ) || name.isEmpty() )
                    {
                        continue;
                    }

                    // 车险保费
                    double motoPremium = MyPOIUtils.getNumbericCellValue( row, 2 );
                    // 非车险保费
                    double nomotoPremium = MyPOIUtils.getNumbericCellValue( row, 4 );
                    // 车险保费占比
                    double motoPremiumProPortion = MyPOIUtils.getNumbericCellValue( row, 3 ) * 100;
                    // 当月保费渗透率
                    double attachingRate = MyPOIUtils.getNumbericCellValue( row, 5 ) * 100;
                    // 保费渗透率环比上月
                    double attachingRateChange = MyPOIUtils.getNumbericCellValue( row, 6 ) * 100;
                    // 当月客户渗透率
                    double customerHandleRateCell = MyPOIUtils.getNumbericCellValue( row, 7 ) * 100;
                    // 客户渗透率环比上月
                    double customerHandleRateChangeCell =
                            MyPOIUtils.getNumbericCellValue( row, 8 ) * 100;
                    // 当月车非客均保费
                    double noMotoPremiumPerCustomerCell =
                            MyPOIUtils.getNumbericCellValue( row, 9 ) * 100;
                    // 客均保费环比上月
                    double noMotoPremiumPerCustomerChangeCell =
                            MyPOIUtils.getNumbericCellValue( row, 10 ) * 100;

                    BITelsalerAttachingRateRecord record = new BITelsalerAttachingRateRecord(
                            departmentName, name, motoPremium, nomotoPremium,
                            motoPremiumProPortion, attachingRate, attachingRateChange,
                            customerHandleRateCell, customerHandleRateChangeCell,
                            noMotoPremiumPerCustomerCell, noMotoPremiumPerCustomerChangeCell );

                    records.add( record );
                }
                catch ( IllegalStateException error )
                {
                    error.printStackTrace();
                }
                catch ( NumberFormatException error )
                {
                    error.printStackTrace();
                }
                catch ( NullPointerException error )
                {
                    String message = "第" + String.valueOf( rowIndex ) + "行出现NullPointerException异常";
                    logger.error( message, error );
                }
            }
        }
        finally
        {
            try
            {
                if ( wb != null )
                {
                    wb.close();
                }
            }
            catch ( IOException error )
            {
                error.printStackTrace();
            }
        }

        return records;
    }

    /**
     * 从excel文件读取坐席的车非渗透率数据。
     * @param filePath
     * @param hasCaptionRow
     * @param summaryDate
     * @return
     */
    public static ArrayList<BITelsalerRenewalRateRecord> importBITelsalerRenewalRateFromXlsx(
            String filePath, int sheetIndex, int firstRow )
            throws IOException, InvalidFormatException
    {
        ArrayList<BITelsalerRenewalRateRecord> records = new ArrayList<>( 200 );

        Workbook wb = null;
        Sheet sheet = null;

        try
        {
            wb = WorkbookFactory.create( new File( filePath ) );
            sheet = wb.getSheetAt( sheetIndex );
            int rowIndex = 0;
            String 责任部门 = null;
            String 当前行责任部门 = null;
            String 责任人 = null;

            if ( !checkExcelFormat( sheet, null, 0, TelSalerRenewalRateExcelTitle, 0 ) )
            {
                throw new InvalidFormatException( "格式错误，请检查报表内容！" );
            }

            for ( Row row : sheet )
            {
                rowIndex = row.getRowNum();

                // 从数据行开始
                if ( row.getRowNum() < firstRow )
                {
                    continue;
                }

                try
                {
                    // 处理责任部门列
                    // 如果读取到的当前行责任部门不为空且与前一行责任部门不同，说明是另一个部门的数据
                    try
                    {
                        当前行责任部门 = MyPOIUtils.getStringCellValue( row, 0 );

                        if ( !当前行责任部门.isEmpty() && !当前行责任部门.equals( 责任部门 ) )
                        {
                            责任部门 = 当前行责任部门;
                        }
                    }
                    catch ( NullPointerException error )
                    {
                    }

                    // 判断责任人，如果是空值，就跳过此行
                    责任人 = MyPOIUtils.getStringCellValue( row, 1 );

                    if ( 责任人.isEmpty() == true )
                    {
                        continue;
                    }

                    double 机构目标值 = MyPOIUtils.getNumbericCellValue( row, 2 ) * 100;
                    double 到期数全月 = MyPOIUtils.getNumbericCellValue( row, 3 );
                    double 序时到期数占比 = MyPOIUtils.getNumbericCellValue( row, 4 ) * 100;
                    double 个车续保率序时 = MyPOIUtils.getNumbericCellValue( row, 5 ) * 100;
                    double 个车续保率全月 = MyPOIUtils.getNumbericCellValue( row, 6 ) * 100;
                    double 环比昨日 = MyPOIUtils.getNumbericCellValue( row, 7 ) * 100;
                    double 环比上月 = MyPOIUtils.getNumbericCellValue( row, 8 ) * 100;
                    // double 平均提前签单天数 = MyPOIUtils.getNumbericCellValue( row, 9 );
                    // double 环比 = MyPOIUtils.getNumbericCellValue( row, 10 );

                    BITelsalerRenewalRateRecord record = new BITelsalerRenewalRateRecord( 责任部门, 责任人,
                            机构目标值, 到期数全月, 序时到期数占比, 个车续保率序时, 个车续保率全月, 环比昨日, 环比上月 );

                    records.add( record );
                }
                catch ( NullPointerException error )
                {
                    String message = "第" + String.valueOf( rowIndex ) + "行出现NullPointerException异常";

                    logger.error( message, error );
                }
            }
        }
        finally
        {
            try
            {
                if ( wb != null )
                {
                    wb.close();
                }
            }
            catch ( Exception error )
            {
                error.printStackTrace();
            }
        }

        return records;
    }

    /**
     * 读取BI机构当月个车续保率跟踪表
     * @param filePath
     * @param sheetIndex
     * @param firstRow
     * @return
     * @throws IOException
     * @throws InvalidFormatException
     */
    public static ArrayList<BIDepartmentAttachingRateRecord> importBIDepartmentAttachingRateRecordsFromXlsx(
            String filePath, int sheetIndex, int firstRow )
            throws IOException, InvalidFormatException
    {
        ArrayList<BIDepartmentAttachingRateRecord> records = new ArrayList<>( 5 );

        Workbook wb = null;

        try
        {
            wb = WorkbookFactory.create( new File( filePath ) );

            Sheet sheet = wb.getSheetAt( sheetIndex );
            int rowIndex = 0;

            if ( !checkExcelFormat( sheet, null, 0, DepartmentAttachingRateExcelTitle, 0 ) )
            {
                throw new InvalidFormatException( "Excel文件格式错误，请检查报表内容！" );
            }

            for ( Row row : sheet )
            {
                rowIndex = row.getRowNum();

                // 从数据行开始
                if ( row.getRowNum() < firstRow )
                {
                    continue;
                }

                try
                {
                    String departmentName = MyPOIUtils.getStringCellValue( row, 0 );

                    if ( departmentName.isEmpty() || departmentName.equals( "合计" ) )
                    {
                        continue;
                    }

                    double departmentObject = MyPOIUtils.getNumbericCellValue( row, 1 ) * 100;
                    double objectGap = MyPOIUtils.getNumbericCellValue( row, 2 ) * 100;
                    double motoPremium = MyPOIUtils.getNumbericCellValue( row, 3 );
                    double motoPremiumProPortion = MyPOIUtils.getNumbericCellValue( row, 4 ) * 100;
                    double nomotoPremium = MyPOIUtils.getNumbericCellValue( row, 5 );
                    double attachingRate = MyPOIUtils.getNumbericCellValue( row, 6 ) * 100;
                    double attachingRateChange = MyPOIUtils.getNumbericCellValue( row, 7 ) * 100;
                    int motoInsuranceCustomerCount = (int)MyPOIUtils.getNumbericCellValue( row, 8 );
                    double customerHandleRate = MyPOIUtils.getNumbericCellValue( row, 9 ) * 100;
                    double customerHandleRateChange =
                            MyPOIUtils.getNumbericCellValue( row, 10 ) * 100;
                    double premiumPerCustomer = MyPOIUtils.getNumbericCellValue( row, 11 ) * 100;
                    double premiumPerCustomerChange =
                            MyPOIUtils.getNumbericCellValue( row, 12 ) * 100;

                    BIDepartmentAttachingRateRecord record = new BIDepartmentAttachingRateRecord(
                            departmentName, departmentObject, objectGap, motoPremium,
                            motoPremiumProPortion, nomotoPremium, attachingRate,
                            attachingRateChange, motoInsuranceCustomerCount, customerHandleRate, customerHandleRateChange,
                            premiumPerCustomer, premiumPerCustomerChange );

                    records.add( record );
                }
                catch ( NullPointerException error )
                {
                    String message = "第" + String.valueOf( rowIndex ) + "行出现NullPointerException异常";

                    logger.error( message, error );
                }
            }
        }
        finally
        {
            try
            {
                if ( wb != null )
                {
                    wb.close();
                }
            }
            catch ( Exception error )
            {
                String message = "关闭" + filePath + "时出现异常！";

                logger.error( message, error );
            }
        }

        return records;
    }

    public static ArrayList<BIDepartmentRenewalRateRecord> importBIDepartmentRenewalRateRecordsFromXlsx(
            String filePath, int sheetIndex, int firstRow )
            throws IOException, InvalidFormatException
    {
        ArrayList<BIDepartmentRenewalRateRecord> records = new ArrayList<>( 20 );

        Workbook wb = null;

        try
        {
            wb = WorkbookFactory.create( new File( filePath ) );

            Sheet sheet = wb.getSheetAt( sheetIndex );
            int rowIndex = 0;

            if ( !checkExcelFormat( sheet, null, 0, DepartmentRenewalRateExcelTitle, 0 ) )
            {
                throw new InvalidFormatException( "Excel文件格式错误，请检查报表内容！" );
            }

            for ( Row row : sheet )
            {
                rowIndex = row.getRowNum();

                if ( rowIndex < firstRow )
                {
                    continue;
                }

                try
                {
                    String 责任部门 = MyPOIUtils.getStringCellValue( row, 0 );

                    // 部门为空或者是合计行，就跳过
                    if ( 责任部门.isEmpty() || 责任部门.equals( "合计" ) )
                    {
                        continue;
                    }

                    double 机构目标值 = MyPOIUtils.getNumbericCellValue( row, 1 ) * 100;
                    int 到期数全月 = (int) MyPOIUtils.getNumbericCellValue( row, 2 );
                    double 序时到期数占比 = MyPOIUtils.getNumbericCellValue( row, 3 ) * 100;
                    double 个车续保率序时 = MyPOIUtils.getNumbericCellValue( row, 4 ) * 100;
                    double 个车续保率全月 = MyPOIUtils.getNumbericCellValue( row, 5 ) * 100;
                    double 环比昨日 = MyPOIUtils.getNumbericCellValue( row, 6 ) * 100;
                    double 环比上月 = MyPOIUtils.getNumbericCellValue( row, 7 ) * 100;
                    // int 平均提前签单天数 = (int) MyPOIUtils.getNumbericCellValue( row, 8 );
                    // double 环比 = MyPOIUtils.getNumbericCellValue( row, 9 ) * 100;

                    BIDepartmentRenewalRateRecord record = new BIDepartmentRenewalRateRecord( 责任部门,
                            机构目标值, 到期数全月, 序时到期数占比, 个车续保率序时, 个车续保率全月, 环比昨日, 环比上月 );

                    records.add( record );
                }
                catch ( NullPointerException error )
                {
                    String message = "第" + String.valueOf( rowIndex ) + "行出现NullPointerException异常";

                    logger.error( message, error );
                }
            }
        }
        finally
        {
            if ( wb != null )
            {
                try
                {
                    wb.close();
                }
                catch ( Exception error )
                {
                    error.printStackTrace();
                }
            }
        }

        return records;
    }
}
