/*
 * @Author: Kane
 * @Date: 2022-04-22 10:53:49
 * @LastEditors: Kane
 * @LastEditTime: 2022-04-27 22:55:44
 * @FilePath: \DisasterWarning\src\main\java\com\cpic\xim\wechat\officalAccount\sendMessage.java
 * @Description: 用来推送公众号消息的程序库。
 *
 * Copyright (c) ${2022} by Kane, All Rights Reserved.
 */
package com.cpic.xim.wechat.officalAccount;

import com.cpic.xim.config.db.OracleConfigLoader;
import com.cpic.xim.config.db.OracleConfig;

import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Vector;
import java.util.logging.*;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.cpic.xim.notify.disaster.*;
import com.cpic.xim.httpUtil.HttpUtils;

/**
 * 推送微信公众号消息。
 * 
 * @author Kane
 */
public class sendMessage
{
    private static HashMap<String, String> warningLevel;

    /**
     * 推送天气灾害预警！接口文档参考 彭奕洁 编写《消息发送接口调用文档》
     * 使用 post 方式，请求体内容以最基础的 post 格式。
     * @param officalAccountURL 产险厦门分公司公众号接口网址
     * @param warning           灾害预警对象
     */
    public static void sendWeatherDisasterWarning( String officalAccountURL,
            QWeatherDisasterWarning warning )
    {
        Vector<QWeatherDisasterWarningItem> warningItems = warning.getWarning();
        StringBuilder requestBody = null;

        // 设置请求头参数
        HashMap<String, String> headers = new HashMap<String, String>();

        headers.put( "accept", "*/*" );
        headers.put( "Connection", "Keep-Alive" );
        headers.put( "Content-Type", "application/x-www-form-urlencoded;charset=UTF-8" );

        // 遍历消息，将消息推送出去。
        for ( QWeatherDisasterWarningItem item : warningItems )
        {
            // 拼接消息内容
            String title = item.getTitle();
            String text = item.getText();
            String color = warningLevel.keySet().contains( item.getLevel() )
                    ? warningLevel.get( item.getLevel() )
                    : "#000000";
            requestBody = new StringBuilder();

            requestBody.append( "tplid=57&groupid=1&first=尊敬的#realname#，您好！&" );
            requestBody.append( "keyword1=" ).append( title ).append( "&" );
            requestBody.append( "keyword1color=" ).append( color ).append( "&" );
            requestBody.append( "keyword2=" ).append( text );

            try
            {
                HttpUtils.postHttpRequest( officalAccountURL, headers, requestBody.toString() );
            }
            catch ( MalformedURLException error )
            {
                error.printStackTrace();
            }
        }
    }

    /**
     * 检查预警是否已经推送过，通过 QWeatherDisasterWarningItem 对象的 id 属性。
     * 查询 oracle xmcx1 数据库 wechat 表空间下 weather_disaster_notify 表，
     * 统计 warningID 的数量，如果不为0,说明该预警已经保存过，视为已经推送过。
     * @param warningID 预警的id
     * @return 如果推送过，返回false，否则返回 true。
     */
    public static boolean checkWarningHasSended( String warningID )
            throws ClassNotFoundException, SQLException, IOException
    {
        boolean result = false;

        OracleConfig dbConfig = OracleConfigLoader.getOracleConfig();;

        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;

        String jdbcURL = dbConfig.getJdbcURL();
        String userName = dbConfig.getUserName();
        String password = dbConfig.getPassword();
        String sql = "select count(*) from weather_disaster_notify where notify_id = ?";

        // Logger logger = Logger.getLogger( "com.cpicxim.wechat.officalAccount.sendMessage" );

        try
        {
            Class.forName( "oracle.jdbc.driver.OracleDriver" );

            conn = DriverManager.getConnection( jdbcURL, userName, password );
            stmt = conn.prepareStatement( sql );
            stmt.setString( 1, warningID );

            rs = stmt.executeQuery();

            if ( rs.next() && rs.getInt( 1 ) == 0)
            {
                result = true;
            }
        }
        finally
        {
            try
            {
                if ( rs != null)
                {
                    rs.close();
                }
            }
            catch ( Exception error )
            {
                error.printStackTrace();
            }

            try
            {
                if ( stmt != null)
                {
                    stmt.close();
                }
            }
            catch ( Exception error )
            {
                error.printStackTrace();
            }

            try
            {
                if ( conn != null)
                {
                    conn.close();
                }
            }
            catch ( Exception error )
            {
                error.printStackTrace();
            }
        }

        return result;
    }

    /**
     * 保存天气预警警报数据。
     * 保存至 oracle xmcx1 数据库 wechat 表空间下 weather_disaster_notify 表。
     * 保存的数据用来判断预警是否已经推送过，以防止反复推送数据。
     * @param city 城市名称
     * @param warning 预警数据，为 QWeatherDisasterWarningItem 对象。
     * @throws SQLException 执行sql时可能抛出的异常。
     * @throws IOException 读取数据库配置文件时可能抛出的异常。
     * @throws ClassNotFoundException 加载oracle jdbc驱动时可能抛出的异常。
     */
    public static void saveWeatherDisasterWarning( String city,
            QWeatherDisasterWarningItem warning )
            throws SQLException, IOException, ClassNotFoundException
    {
        Connection conn = null;
        PreparedStatement stmt = null;

        String sql = "";

        OracleConfig dbConfig = OracleConfigLoader.getOracleConfig();

        String jdbcURL = dbConfig.getJdbcURL();
        String userName = dbConfig.getUserName();
        String password = dbConfig.getPassword();

        try
        {
            Class.forName( "oracle.jdbc.driver.OracleDriver" );

            conn = DriverManager.getConnection( jdbcURL, userName, password );
            stmt = conn.prepareStatement( sql );
            stmt.execute();
        }
        finally
        {
            try
            {
                if ( stmt != null)
                {
                    stmt.close();
                }
            }
            catch ( Exception error )
            {
                error.printStackTrace();
            }

            try
            {
                if ( conn != null)
                {
                    conn.close();
                }
            }
            catch ( Exception error )
            {
                error.printStackTrace();
            }
        }
    }


    static
    {
        // 预警级别色彩
        warningLevel = new HashMap<>();

        warningLevel.put( "蓝色", "#0000FF" );
        warningLevel.put( "黄色", "#FFFF00" );
        warningLevel.put( "橙色", "#FFA500" );
        warningLevel.put( "红色", "#FF0000" );
    }
}


class WechatOfficalAccountMessageParameter
{

    WechatOfficalAccountMessageParameter()
    {
        tplID = 57;
        groupID = 1;
    }

    @JsonProperty( "tplid")
    private int tplID;

    @JsonProperty( "groupid")
    private int groupID;

    @JsonProperty( "first")
    private String first;

    @JsonProperty( "keyword1")
    private String keyword1;

    @JsonProperty( "keyword1color")
    private String keyword1Color;

    @JsonProperty( "keyword2")
    private String keyword2;

    @JsonProperty( "keyword2color")
    private String keyword2Color;

    @JsonProperty( "remark")
    private String remark;

    @JsonProperty( "remarkcolor")
    private String remarkColor;

    @JsonProperty( "url")
    private String url;

    @JsonProperty( "appid")
    private String appid;

    @JsonProperty( "pagepath")
    private String pagePath;

    public int getTplID()
    {
        return tplID;
    }

    public void setTplID( int tplID )
    {
        this.tplID = tplID;
    }

    public int getGroupID()
    {
        return groupID;
    }

    public void setGroupID( int groupID )
    {
        this.groupID = groupID;
    }

    public String getFirst()
    {
        return first;
    }

    public void setFirst( String first )
    {
        this.first = first;
    }

    public String getKeyword1()
    {
        return keyword1;
    }

    public void setKeyword1( String keyword1 )
    {
        this.keyword1 = keyword1;
    }

    public String getKeyword1Color()
    {
        return keyword1Color;
    }

    public void setKeyword1Color( String keyword1Color )
    {
        this.keyword1Color = keyword1Color;
    }

    public String getKeyword2()
    {
        return keyword2;
    }

    public void setKeyword2( String keyword2 )
    {
        this.keyword2 = keyword2;
    }

    public String getKeyword2Color()
    {
        return keyword2Color;
    }

    public void setKeyword2Color( String keyword2Color )
    {
        this.keyword2Color = keyword2Color;
    }

    public String getRemark()
    {
        return remark;
    }

    public void setRemark( String remark )
    {
        this.remark = remark;
    }

    public String getRemarkColor()
    {
        return remarkColor;
    }

    public void setRemarkColor( String remarkColor )
    {
        this.remarkColor = remarkColor;
    }

    public String getUrl()
    {
        return url;
    }

    public void setUrl( String url )
    {
        this.url = url;
    }

    public String getAppid()
    {
        return appid;
    }

    public void setAppid( String appid )
    {
        this.appid = appid;
    }

    public String getPagePath()
    {
        return pagePath;
    }

    public void setPagePath( String pagePath )
    {
        this.pagePath = pagePath;
    }
}
