package com.brilliance.isc.common.bop.bopdec.service.imp;


import com.brilliance.mda.runtime.mda.util.MdaUtils;
import com.brilliance.isc.bo.Bopcty;
import com.brilliance.isc.mda.dao.BopctyMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

@Component
public class Pntmod {
    private static Logger log = LoggerFactory.getLogger(Pntmod.class);

    @Autowired
    BopctyMapper bopctyMapper;

    /**
     * 返回勾选框
     * @return
     */
    public String getCheckedChar(){
        return "√";
    }

    /**
     * 将序号填入每个格子
     * @param inputData
     * @param numberStr
     * @param field
     */
    public void setSplitCodeNumber(Map<String, Object> inputData, String numberStr, String field)
    {
        /**
         * 把一个序号传入pdf模版中，使用□□□□□□□□的格子规定好的域中
         * ！注意：pdf中的域名采用（原始字段名_i）的形式,i从1开始
         * eg. 申报号码：数据库中存储为rptno（22位），pdf中域名则相应应为rptno_1,rptno_2,...rptno_22
         * 本函数只是将数据切分后，对应到输入的Map中，并不能对pdf的格式等进行检测，也不会写入到pdf中
         * @param  <inputData> 将要调用外部包传入到pdf中的值映射
         * @param  <numberStr> 在pdf中被分成若干格子的实际值
         * @param  <field> 		字段在实际数据库中存储的名称（也即pdf模版中各个格子对应的域的前缀）
         * @return [void]
         * @Author LHF
         * @version <12926A>
         *          <12927B> 修改了字符截取方式
         *          <12927C> 修正了传入空值导致NullPointer异常的BUG
         *          <12928D> 修正为中文输出
         **/
        //<12927C>
        if(MdaUtils.isEmpty(numberStr))
        {
            log.error("切分字符串时检测到字符串为空.:" + field);
            return;
        }
        //</12927C>
        //! 如果实际的号码长度小于规定的格子，那么缺少的格子的得不到赋值，会保持空
        //! 相反如果其大于规定的格子，那么多于的部分虽然在Map中都有值，但是由于pdf中没有对应域，将不会产生影响
        for(int i = 0; i < numberStr.length(); i ++)
        {
            //获取相应的格子对应的域名
            String eachField = String.format("%s_%d", field, i + 1);
            //<12927B>
            //X应pdf模版中的相应域后缀从1开始，需要使用i+1
            //XString eachValue = numberStr.substring(i, i + 1);
            Character value = numberStr.charAt(i);
            String eachValue = value.toString();
            //</12927B>
            //debug
            //将值传入到输入data中
            inputData.put(eachField, eachValue);
        }
    }

    /**
     * 将码表字段转为pdf中的勾选
     * @param data
     * @param code
     * @param field
     * @param checkString
     */
    public void setCodetableData(Map<String, Object> data, String code, String field, String checkString)
    {
        /**
         * 将数据库中存储为码表的字段转化为相应的pdf模版中的字段为选中
         * pdf模版中命名规则为(字段名_码表值)
         * eg. 数据库中存储为methods字段，对应码表值为L,G,D,T,M,O，则pdf中字段对应为methods_d,methods_g，...
         * 注意这里要求为小写
         * @param  <data>  			输入到pdf模版中的映射值
         * @param  <code>  			字段值（即存储的值）
         * @param  <field> 			数据库对应字段，也即pdf模版前缀
         * @param  <checkString> 检测码表中存储的是否在预期值之内，为空代表不检测，多个值使用:（英文）隔开
         * @return [VOID]
         * @Author LHF
         * @version <12927A>
         *          <12928B> 更新为中文输出
         **/
        log.debug(">-----------------------");
        if(MdaUtils.isEmpty(code))
        {
            log.warn("码表值为空：" + field);
            code = "";
        }
        if(!MdaUtils.isEmpty(checkString))
        {
            checkString = ":" + checkString + ":";			//在首尾加入分隔符，以便直接检测
            String str = ":" + code + ":";
            //出现不包含在检测字符串中的值，但依然会传入到data中去
            if(!checkString.contains(str)){
                log.error("码表不在指定的校验值范围内:" + str + "," + field + "{" + checkString + "}");
            }
        }
        //将对应域的设置为选中符
        data.put(field + "_" + code.toLowerCase(), this.getCheckedChar());
        log.debug("-----------------------<");
    }

    /**
     * 币种及金额格式化
     * @param ccy
     * @param amt
     * @return
     */
    public  String getFormatedMoney(String ccy, BigDecimal amt)
    {
        /**
         * 将币种及金额格式化为字符串
         *
         * @param  <ccy> 币种（USD,...)
         * @param  <amt> 金额，无小数点整数
         * @return [String] 格式化后的字符串，例如 USD 2,010,340
         * @Author LHF
         * @version <12927A>
         *          <12928B> 增加了空值检测（依然可以输出）；增加了货币格式处理
         **/
        if(MdaUtils.isEmpty(ccy) || MdaUtils.isEmpty(amt)){
            log.warn("格式化币种及金额，检测到币种或金额为空");
        }
        String amtStr = amt.toString();
        //剔除小数
        String[] strs = amtStr.split("\\.");
        if(strs.length > 1){
            amtStr = strs[0];
        }
        int length = amtStr.length();
        //从末位开始，循环插入逗号作为分隔符
        //无此函数
        StringBuffer sb = new StringBuffer(amtStr);
        //将字符串反转，以便每三个字符添加一个逗号
        sb = sb.reverse();
        //每隔三个字符插入一个逗号
        for(int i = 3; i < sb.length(); i += 4){
            sb.insert(i, ",");
        }
        //最后再次将数值反转回来
        sb = sb.reverse();
        String ccyStr = ccy;
        if(null == ccyStr){
            ccyStr = "";
        }

        //拼接上小数位
        String finstr = "";
        if(strs.length > 1){
            finstr = ccyStr + "  " + sb.toString() + "."+strs[1];
        }else{
            finstr = ccyStr + "  " + sb.toString();
        }


        return finstr;
    }

    /**
     * 金额格式化，插入逗号
     * @param amt
     * @return
     */
    public  String getMoney(BigDecimal amt)
    {
        if(MdaUtils.isEmpty(amt)){
            log.warn("格式化币种及金额，检测到币种或金额为空");
        }
        String amtStr = amt.toString();
        //剔除小数
        String[] strs = amtStr.split("\\.");
        if(strs.length > 1){
            amtStr = strs[0];
        }
        int length = amtStr.length();
        //从末位开始，循环插入逗号作为分隔符
        //无此函数
        StringBuffer sb = new StringBuffer(amtStr);
        //将字符串反转，以便每三个字符添加一个逗号
        sb = sb.reverse();
        //每隔三个字符插入一个逗号
        for(int i = 3; i < sb.length(); i += 4){
            sb.insert(i, ",");
        }
        //最后再次将数值反转回来
        sb = sb.reverse();

        //拼接上小数位
        String finstr = "";
        if(strs.length > 1){
            finstr = sb.toString() + "."+strs[1];
        }else{
            finstr = sb.toString();
        }
        return finstr;
    }

    /**
     * 金额转为汉语大写
     * @param amt
     * @return
     */
    public String covCnAmt(BigDecimal amt)
    {
        ///转化金额为汉语大写
        try
        {
            if (amt == null){
                return "";
            }
            String strAmt = amt.setScale(2, BigDecimal.ROUND_HALF_UP).toString();
            String[] number = {"壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};
            String[] radices = {"仟", "", "拾", "佰"};
            String[] bigRadices = {"", "万", "亿", "万亿", "亿亿"};
            int idx = strAmt.indexOf(".");
            String sInt = strAmt.substring(0, idx);
            String sFlt = strAmt.substring(idx + 1);
            String cn = "";
            int zeroC = 0;
            int len = sInt.length();
            for (int i = 0; i < len; i++)
            {
                if (sInt.charAt(i) == '0'){
                    zeroC++;
                }
                else
                {
                    if (zeroC > 0)
                    {
                        cn += "零";
                        zeroC = 0;
                    }
                    cn += number[sInt.charAt(i) - 49];
                    cn += radices[(len - i) % 4];
                }
                if ((len - i) % 4 == 1 && zeroC < 4){
                    cn += bigRadices[(len - i) / 4];
                }
            }
            cn += "元";
            if (sFlt.equals("00")){
                cn += "整";
            }
            else
            {
                if (!sFlt.substring(0, 1).equals("0")){
                    cn += number[sFlt.charAt(0) - 49] + "拾";
                }
                else{
                    cn += "零";
                }
                if (!sFlt.substring(1, 2).equals("0")){
                    cn += number[sFlt.charAt(1) - 49];
                }
                cn += "分";
            }
            log.debug("cn===" + cn);
            return cn;
        }
        catch (Exception e)
        {
            log.error("covCnAmt error", e);
            return "";
        }
    }

    /**
     *
     * @param country_cod
     * @return
     */
    public String[] getCountryNumCodeAndName(String country_cod)
    //参数为英文国家代码，返回值为国家名称和数字国家代码
    {
        String[] numCodeAndName = new String[2];
        String sql = "";
        if (!MdaUtils.isEmpty(country_cod))
        {
            List<Bopcty> bopctylist = bopctyMapper.listByCod(country_cod);
            String country_Name = bopctylist.get(0).getTxt();
            country_Name = country_Name.replaceAll("[a-zA-Z]","" );
            numCodeAndName[0] = bopctylist.get(0).getNumcod();
            numCodeAndName[1] = country_Name;
        }
        else
        {
            numCodeAndName[0] = "";
            numCodeAndName[1] = "";
        }

        return numCodeAndName;
    }

}
