package com.nokia.tsl_data.dao;

import com.nokia.tsl_data.entity.WorkFlowBasicData;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.object.BatchSqlUpdate;
import org.springframework.stereotype.Component;

import java.sql.Timestamp;
import java.sql.Types;
import java.util.List;
import java.util.Objects;

/**
 * tslData 直接使用jdbcTemplate完成的操作
 */
@Component
public class TslDataDao {

    private final JdbcTemplate jdbcTemplate;

    public TslDataDao(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    /**
     * 采用BatchSqlUpdate的方法批量insert到表tableName(可以是临时表)
     */
    public void batchInsertWorkFlowBasicData(List<WorkFlowBasicData> data, String tableName) {
        String sqlFormat = "INSERT INTO %s " +
                "(order_no,is_effctive, kfsn, city_id, region_id, kd_accept_time, kd_request_reply_time, re_is_status_id, "
                + " kf_file_time, kf_file_type, work_flow_create_time, work_flow_update_time) " +
                "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
        BatchSqlUpdate batchSqlUpdate = new BatchSqlUpdate(Objects.requireNonNull(jdbcTemplate.getDataSource()),
                String.format(sqlFormat, tableName));
        batchSqlUpdate.setBatchSize(1000);
        batchSqlUpdate.setTypes(new int[] {
                Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
                Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
                Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
                Types.VARCHAR, Types.TIMESTAMP, Types.TIMESTAMP
        });
        for (WorkFlowBasicData item : data) {
            batchSqlUpdate.update(
                    item.getOrderNo(),
                    item.getIsEffctive(),
                    item.getKfsn(),
                    item.getCityId(),
                    item.getRegionId(),
                    item.getKdAcceptTime(),
                    item.getKdRequestReplyTime(),
                    item.getReIsStatusId(),
                    item.getKfFileTime(),
                    item.getKfFileType(),
                    item.getWorkFlowCreateTime() == null ? null : Timestamp.from(item.getWorkFlowCreateTime()),
                    item.getWorkFlowUpdateTime() == null ? null : Timestamp.from(item.getWorkFlowUpdateTime()));
        }
        batchSqlUpdate.flush();
    }

    /**
     * 创建临时表
     */
    public void createTempTableOfWorkFlowBasicData(String tempTableName) {
        String sql = "CREATE TABLE %s (  " + //
                " order_no varchar(50) not null,  " + //
                " is_effctive varchar(50) not null,  " + //
                " kfsn varchar(50) NOT NULL,  " + //
                " city_id varchar(50) NULL,  " + //
                " region_id varchar(50) NULL,  " + //
                " kd_accept_time varchar(50) NULL,  " + //
                " kd_request_reply_time varchar(50) NULL,  " + //
                " re_is_status_id varchar(50) NULL,  " + //
                " kf_file_time varchar(50) NULL,  " + //
                " kf_file_type varchar(50) NULL,  " + //
                " work_flow_create_time timestamp NULL,  " + //
                " work_flow_update_time timestamp NULL " + //
                ");";
        jdbcTemplate.update(String.format(sql, tempTableName));
    }

    /**
     * 删除临时表
     */
    public void dropTempTable(String tempTableName) {
        if (!tempTableName.contains("_temp_")) {
            throw new RuntimeException("仅支持删除命名带有 _temp_ 的临时表");
        }
        jdbcTemplate.execute("drop table tsl_data." + tempTableName);
    }

    public List<String> selectTempTableNames() {
        String sql = "select tablename  from pg_catalog.pg_tables where schemaname = 'tsl_data' and tablename like '%_temp_%'";
        return jdbcTemplate.queryForList(sql, String.class);
    }

    /**
     * 清空表
     */
    public void truncate(String tableName) {
        jdbcTemplate.execute("truncate table tsl_data." + tableName);
    }

    /**
     * 从临时表中查找新增内容并插入work_flow_basic_data表
     */
    public int insertWorkFlowBasicDataFromTempTable(String tempTableName) {
        String sqlFormat = "insert into tsl_data.work_flow_basic_data" +
                " (order_no, is_effctive, kfsn, city_id, region_id, kd_accept_time, kd_request_reply_time, re_is_status_id, "
                + " kf_file_time, kf_file_type, work_flow_create_time, work_flow_update_time)" +
                " select t.order_no, t.is_effctive, t.kfsn, t.city_id, t.region_id, t.kd_accept_time, t.kd_request_reply_time,"
                + " t.re_is_status_id, t.kf_file_time, t.kf_file_type, t.work_flow_create_time, t.work_flow_update_time"
                + " from %s t " +
                " left join tsl_data.work_flow_basic_data b" +
                " on t.order_no = b.order_no" +
                " where b.order_no is null";
        return jdbcTemplate.update(String.format(sqlFormat, tempTableName));
    }

    /**
     * 从临时表中查找需要更新内容并更新到work_flow_basic_data表
     */
    public int updateWorkFlowBasicDataFromTempTable(String tempTableName) {
        String sqlFormat = "update tsl_data.work_flow_basic_data b\n" +
                "set kfsn = t.kfsn, is_effctive = t.is_effctive, city_id = t.city_id, region_id = t.region_id, "
                + " kd_accept_time = t.kd_accept_time, kd_request_reply_time = t.kd_request_reply_time, " +
                " re_is_status_id = t.re_is_status_id, kf_file_time = t.kf_file_time, " +
                " kf_file_type = t.kf_file_type, work_flow_create_time = t.work_flow_create_time, " +
                " work_flow_update_time = t.work_flow_update_time " +
                " from (select order_no, is_effctive, kfsn, city_id, region_id, kd_accept_time, kd_request_reply_time, "
                + " re_is_status_id, kf_file_time, kf_file_type, work_flow_create_time, work_flow_update_time " +
                " from %s ) t" +
                " where b.order_no = t.order_no";
        return jdbcTemplate.update(String.format(sqlFormat, tempTableName));
    }

    /**
     * high_quality_list_day 河北_CEM高品质2日明细
     */
    public void batchInsertHighQualityListDay(List<Object[]> data) {
        String sql = "INSERT INTO tsl_data.high_quality_list_day\n" +
                "(month_id, day_id, contact_id, busino_area_name, busino_prov_name, sheet_no, busi_number," +
                " cust_star_name, sheet_type_name, serv_type_name, last_deal_content, accept_time, archived_time," +
                " data_type_name, channel_name, profes_dep, big_type_name, small_type_name, is_dispatch_cloud," +
                " accept_channel_name, duty_reason_name, duty_major_name, is_online_complete, is_call_complete," +
                " is_cusser_complete, is_distr_complete, caller_number, compl_area_name, compl_prov_name," +
                " submit_channel, solved_result_desc, cust_level_name, busi_type_name, urgent_level_name," +
                " important_type_name, is_upgrade, actual_total_len, nature_actual_total_len, cust_satis_desc," +
                " auto_is_ok, auto_cust_satis_desc, nonauto_is_ok_name, nonauto_cust_satis_desc, prod_type_name," +
                " proc_name, merge_satis_desc, serv_type_name_new, is_svip_keyman, customer_label, prov_name," +
                " area_id, area_name, city_id, city_name, grid_id, grid_name, is_distri_area, cp_satisfaction," +
                " cp_is_ok, cp_timely_contact, cp_type, novisit_tag, serv_content, gis_area, gis_area_name," +
                " gis_city, gis_city_name, use_gis, month_date, day_date)" +
                " VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?," +
                " ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?," +
                " ?, ?, ?, ?, ?, ?, ?, ?, ?)";
        jdbcTemplate.batchUpdate(sql, data);
    }

    /**
     * high_quality_count_day 河北_CEM高品质2日统计 数据入库
     */
    public void batchInsertHighQualityCountDay(List<Object[]> data) {
        String sql = "insert into tsl_data.high_quality_count_day (month_id,day_id,acct_date,businoareaname," +
                " profes_dep,big_type_name,small_type_name,total_complaints,hotline_complaints,other_complaint," +
                " litigation_volume,satisfaction_rate,satisfaction_count,total_evaluation,complaint_satisfied," +
                " complaint_satisfied_list,complaint_satisfied_count,complaint_resolution,complaint_resolution_list," +
                " complaint_resolution_count,complaint_response,complaint_response_list,complaint_response_count," +
                " complaint,fault_satisfaction_rate,fault_satisfaction_list,fault_satisfaction_count," +
                " fault_resolution_rate,fault_resolution_list,fault_resolution_count,fault_response_rate," +
                " fault_response_list,fault_response_count)" +
                " values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
        jdbcTemplate.batchUpdate(sql, data);
    }

    /**
     * MOBILE_COMPLAINT_DETAILS_DAY 河北_CEM移网质量投诉明细 数据入库
     */
    public void batchInsertMobileComplaintDay(List<Object[]> data) {
        String sql = "insert into tsl_data.mobile_complaint_day (month_id,day_id,acct_date,sheet_no," +
                " is_online_complete,contact_no,busi_no,serv_content,last_deal_content,deal_depart_name," +
                " deal_opinion,serv_type,bus_type,duty_reason,accept_channel,submit_channel,compl_area_local," +
                " duty_major,product_name,sp_product_code,pre_repair_name,pre_repair_charges,fault_location," +
                " cust_level,satisfaction_in_reply,is_ok_in_reply,accept_time,end_time,proce_time,cust_area," +
                " is_cust_serv_complete,is_send_sheet_complete,is_repeat,is_upgrade,is_timeout,gis_city," +
                " process_nums,deal_depart_name_1,deal_depart_name_2,deal_depart_name_3,first_call_back_time," +
                " proce_remark,duty_major_day,duty_reason_id_day,duty_major_month,duty_reason_id_month,voice_text)" +
                " values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
        jdbcTemplate.batchUpdate(sql, data);
    }

    /**
     * COMPLAINT_DETAILS_FIX_YWD_DAY 河北客户体验管理智能定责投诉明细月累计接口日 数据入库
     */
    public void batchInsertComplaintDetailsFixYwdDay(List<Object[]> data) {
        String sql = "INSERT INTO tsl_data.complaint_details_fix_ywd_day " +
                "(month_id, day_id, month_id1, day_id1, sheet_no, is_online_complete, contact_no, busi_no," +
                " serv_content, last_deal_content, deal_depart_name, deal_user, deal_opinion, complete_user_code," +
                " serv_type, bus_type, duty_reason, problem_duty, problem_solving_con, code_urgent_level," +
                " code_important_type, cust_name, accept_user, cust_level, accept_channel, submit_channel," +
                " compl_area_local, compl_city_local, compl_grid_local, cust_province, accept_time, end_time," +
                " cust_area, duty_major, is_call_center_complete, is_cust_serv_complete, is_send_sheet_complete," +
                " sp_code, sp_name, is_repeat, is_timeout, duty_dept, proce_user_code, proce_time," +
                " proce_depart_name, proce_remark, satisfaction, is_ok, is_ok_in_reply, product_name," +
                " pre_repair_name, pre_repair_charges, actual_total_len, timeout_len, timeout_depart_name," +
                " sp_product_code, sp_product_name, process_nums, deal_depart_name_1, deal_user_1, sended_user_1," +
                " deal_depart_name_2, deal_user_2, sended_user_2, deal_depart_name_3, deal_user_3, sended_user_3," +
                " deal_depart_name_end, deal_user_end, sended_depart_name_last, first_call_back_time," +
                " duty_reason_id_day, duty_major_day, duty_reason_id_month, duty_major_month, voice_text," +
                " fault_location, satisfaction_in_reply, is_upgrade, gis_city, data_source, code_answer_way," +
                " success_call_back, last_satisfaction, last_is_ok, design_profess, deal_unit, province_deal_unit," +
                " if_direct, is_proself, timely_contact, is_repeat_5times_m, is_repeat_2times_m, is_repeat_2times_2m," +
                " is_repeat_2times_3m, create_time)" +
                "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?," +
                " ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?," +
                " ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, now());";
        jdbcTemplate.batchUpdate(sql, data);
    }

    /**
     * 按照账期清空 complaint_details_fix_ywd_day 表某天的数据
     */
    public int deleteComplaintDetailsFixYwdDay(String day) {
        String sql = "delete from tsl_data.complaint_details_fix_ywd_day where month_id = ? and day_id = ?";
        return jdbcTemplate.update(sql, (ps) -> {
            ps.setString(1, day.substring(0, 6));
            ps.setString(2, day.substring(6, 8));
        });
    }

    /**
     * 河北客户体验管理系统移网网络体验明细日信息 cem_mobile_experience_list 数据入库
     */
    public void batchInsertCemMobileExperienceList(List<Object[]> data) {
        String sql = "INSERT INTO tsl_data.cem_mobile_experience_list " + //
                "(month_id, day_id, service_id, contact_id, create_time, mobile_no, service_type_name1," +
                " pro_name, code_cust_area, zyx, lwly_name, big_type_name, small_type_name, acct_month," +
                " day_id1, sheet_no, compl_city_local) " + //
                "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);";
        jdbcTemplate.batchUpdate(sql, data);
    }

    /**
     * 河北客户体验管理系统移网网络体验明细日信息 cem_mobile_experience_list 按照帐期清空
     */
    public int deleteCemMobileExperienceList(String day) {
        String sql = "delete from tsl_data.cem_mobile_experience_list where month_id = ? and day_id = ?";
        return jdbcTemplate.update(sql, (ps) -> {
            ps.setString(1, day.substring(0, 6));
            ps.setString(2, day.substring(6, 8));
        });
    }
}
