/**
 * 
 */
package com.platomix.userprofile.handler.core;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSONObject;
import com.platomix.userprofile.enums.DsEnum;
import com.platomix.userprofile.handler.AbstractTagHandler;
import com.platomix.userprofile.utils.StrBuilder;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;

/**
 * @author wookvn
 *
 *	聚合所有标签
 */
@Slf4j
@Service
public class CollectAllTagHandler extends AbstractTagHandler{
	
	final static String ZT_TABLE_NAME = "ads.Z_USER_TAG_FLAT_temp";
	/**
	 * before invoke 执行
	 * @return
	 */
	@Override
	public void beforeInvoke(String month) {
		//dynamicExecuteService.execute(DsEnum.clickhouse, String.format("drop table if exists %s",ZT_TABLE_NAME), "删除temp原始数据");
		try {
			TimeUnit.SECONDS.sleep(5);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	@Override
	public void invoke(String month, String mobileLeft, String mobileRight) {
		StrBuilder sqlBuilder = new StrBuilder();
		sqlBuilder.appendLn(super.buildTableSql(ZT_TABLE_NAME, "THEMONTH_V", "USERID_V"));
		sqlBuilder.appendLn("select '"+month+"' as THEMONTH_V,");
		//动态拼接SQL
		List<JSONObject> dataList = dynamicExecuteService.list(DsEnum.clickhouse, "select TABLE_NAME,JOINSTR,JOIN_TABLE from ads.CFG_ZT_TAG_JOIN order by id");
		List<TableParams> tableParamList = new ArrayList<>();
		//格式化数据
		for(JSONObject dataObj : dataList) {
			String tableName = dataObj.getString("TABLE_NAME");
			List<JSONObject> columnList = dynamicExecuteService.list(DsEnum.clickhouse, "desc ads." + tableName);
			TableParams item = new TableParams();
			item.setTableName(tableName);
			//防止后边的字段覆盖主键
			Set<String> _idFoundSet=new HashSet<>();
			for(JSONObject column : columnList) {
				String columnName = column.getString("name");
				if((columnName.contains("USERID") || columnName.contains("DEVICE_NUMBER"))
						&&!_idFoundSet.contains("ID")) {
					item.setUserId(columnName);
					_idFoundSet.add("ID");
				}else if(columnName.contains("MONTH")
						&&!_idFoundSet.contains("MONTH")) {
					item.setMonthId(columnName);
					_idFoundSet.add("MONTH");
				}else {
					item.getCols().add("`"+columnName+"`");
				}
			}
			tableParamList.add(item);
		}
		//拼接 multiIf(userid!='',userid ...) SQL片段
		List<String> userIdIfList = tableParamList.stream().map(item -> String.format("%s!='',%s", item.getUserId(), item.getUserId())).collect(Collectors.toList());
		sqlBuilder.appendLn("multiIf("+String.join(",", userIdIfList)+",'') as USERID_V,");
		//拼接 Columns 修改顺序排列
		List<String> allColumns = new ArrayList<>();
		tableParamList.stream().map(item -> item.getCols()).forEach(allColumns::addAll);
		sqlBuilder.appendLn(String.join(",", allColumns));
		sqlBuilder.appendLn("from");
		Map<String, TableParams> tableParamMap = tableParamList.stream().collect(Collectors.toMap(TableParams::getTableName, t -> t));
		//拼接关联表
		for(JSONObject dataObj : dataList) {
			String tableName = dataObj.getString("TABLE_NAME"),
				   joinTable = dataObj.getString("JOIN_TABLE"),
				   joinStr   = dataObj.getString("JOINSTR");
			TableParams tableParams = tableParamMap.get(tableName);
			String monthSql = StringUtils.isEmpty(tableParams.getMonthId()) ? "1=1" : tableParams.getMonthId() + "='" + month + "'";
			String userIdSql = _getLrMobileSql(mobileLeft, mobileRight, tableParams.getUserId());
			if(!StringUtils.isEmpty(joinStr)) {
				sqlBuilder.append(joinStr + " JOIN ");
			}
			sqlBuilder.appendLn("(select * from ads." + tableName + " where " + monthSql + userIdSql + ") t_" + tableName);
			if(!StringUtils.isEmpty(joinTable)) {
				TableParams joinTableParams = tableParamMap.get(joinTable);
				sqlBuilder.appendLn(String.format("on t_%s.%s = t_%s.%s", 
						tableParams.getTableName(), tableParams.getUserId(), joinTableParams.getTableName(), joinTableParams.getUserId()));
			}
		}
		log.info("\n" + sqlBuilder.toString());
		dynamicExecuteService.execute(DsEnum.clickhouse, sqlBuilder.toString(), "信息化标签生成");
	}

	private String _getLrMobileSql(String mobileLeft, String mobileRight, String fieldName) {
		return mobileLeft == null || mobileRight == null ? "" : String.format(" and %s>='%s' and %s<'%s'", fieldName, mobileLeft, fieldName, mobileRight);
	}
	
	@Data
	static class TableParams {
		private String tableName;
		private String monthId;
		private String userId;
		private List<String> cols = new ArrayList<>();
		public void addCol(String col) {
			cols.add(col);
		}
	}

	@Override
	public boolean executeInBatchs() {
		return true;
	}

}
