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

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.platomix.userprofile.enums.DsEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.platomix.userprofile.handler.AbstractTagHandler;
import com.platomix.userprofile.model.UserprofileTag;
import com.platomix.userprofile.service.UserprofileTagService;
import com.platomix.userprofile.utils.StrBuilder;

import lombok.extern.slf4j.Slf4j;

/**
 * @author wookvn
 *
 *         订购相关标签
 */
@Slf4j
@Service
public class XxhOrderTagHandler extends AbstractTagHandler {

	final static String ZT_TABLE_NAME = "ads.ZT_USER_TAG_ORDER";
	final static long _STEP=50000000L;
	@Autowired
	private UserprofileTagService userprofileTagService;

	@Override
	public void invoke(String month, String mobileLeft, String mobileRight) {
		// 查询所有标签
		List<UserprofileTag> tagList = userprofileTagService.list();
		Map<String, List<UserprofileTag>> tagListMap = tagList.stream().collect(Collectors.groupingBy(t -> t.getEnglishName().toLowerCase()));

		String lrMobileSql = mobileLeft == null || mobileRight == null ? "" : String.format(" and USERID>='%s' and USERID<'%s'", mobileLeft, mobileRight);
		String lrUserIdSql = mobileLeft == null || mobileRight == null ? "" : String.format(" and USERVAL>='%s' and USERVAL<'%s'", mobileLeft, mobileRight);
		
		// 获取开始日期
		String theLeftDay = month + "01";
		String theRightDay = LocalDate.parse(theLeftDay, DateTimeFormatter.BASIC_ISO_DATE).plusMonths(1).format(DateTimeFormatter.ofPattern("yyyyMMdd"));
		
		StrBuilder sqlBuilder = new StrBuilder();
		sqlBuilder.appendLn(super.buildTableSql(ZT_TABLE_NAME, "THEMONTH", "USERID"));
		sqlBuilder.appendLn("with toYYYYMM(ORDERTIME) as OTSTR, toYYYYMM(CANCELTIME) as CTSTR")
				  .appendLn("select THEMONTH,USERID,");
		
		//大网标签-城市
		String citySql = userprofileTagService.genSelectSql("城市", "AREA", "AREA", null);
		sqlBuilder.append(citySql).appendLn(",");
		
		//产品标签-产品类别
		String cpTypeSql = userprofileTagService.genSelectSql("产品类别", "CATEGORYNAME2", "CPTYPE2", null);
		sqlBuilder.append(cpTypeSql).appendLn(",");
		
		//订购产品
		String spSql = userprofileTagService.genSelectSql("订购产品", "SPID", "SPID", null,"#");
		sqlBuilder.append(spSql).appendLn(",");
		
		//产品大类
		String categorySql = userprofileTagService.genSelectSql("产品大类", "CATEGORYNAME", "CPTYPE", null);
		sqlBuilder.append(categorySql).appendLn(",");
		
		//订购渠道
		String channelSql = userprofileTagService.genSelectSql("订购渠道", "CHANNEL", "CHANNEL", null,"#");
		sqlBuilder.append(channelSql).appendLn(",");
		
		//渠道大类
		String belongToSql = userprofileTagService.genSelectSql("渠道大类", "BELONGTO", "BELONGTO", null);
		sqlBuilder.append(belongToSql).appendLn(",");
		
		//权益领取
		String vipSql = userprofileTagService.genSelectSql("权益领取", "VIP_SPNAME", "VIPID", null);
		sqlBuilder.append(vipSql).appendLn(",");
		
		//渠道大类
		String orderTimeSql = userprofileTagService.genSelectSql("订购时间", "ORDER_TIME2", "ORDERTIME", null,"", "tagValue");
		sqlBuilder.append(orderTimeSql).appendLn(",");
		
		//退订时间
		String cancelTimeSql = userprofileTagService.genSelectSql("退订时间", "CANCELTIME2", "CANCELTIME", null, "","tagValue");
		sqlBuilder.append(cancelTimeSql).appendLn(",");
		
		//订购产品时长
		appendEventOrderMonth(sqlBuilder, tagListMap);
		sqlBuilder.appendLn(",");
		
		//退订产品时长
		appendEventCancelDiff(sqlBuilder, tagListMap);
		sqlBuilder.appendLn(",");
		
		//订购产品价格
		appendEventOrderPrice(sqlBuilder, tagListMap);
		sqlBuilder.appendLn(",");
		
		//产品免流量使用比
		appendEventOrderFlowp(sqlBuilder, tagListMap);
		sqlBuilder.appendLn(",");
		
		//产品订购状态
		appendEventOrderState(month, sqlBuilder, tagListMap);
		sqlBuilder.appendLn(",");
		
		//免流流量使用量【20220609_aokunsang_新增标签】
		appendEventFreeLimitFlow(sqlBuilder, tagListMap);
		sqlBuilder.appendLn("");
		
		sqlBuilder.appendLn("from (").appendLn(
				"with toDate(concat(SUBSTRING(toString(THEMONTH),1,4),'-' ,SUBSTRING(toString(THEMONTH),5,2),'-01')) as mstr").appendLn(
				"select THEMONTH ,USERID,PROVINCE,AREA,ORDERTIME,CANCELTIME,ENDTIME,").appendLn(
				"ifNull(CHANNEL,'') as CHANNEL ,BELONGTO,").appendLn(
				"s1.CPID,SPID,SPNAME ,d.CPTYPE ,d.CATEGORYNAME,d.CPTYPE2 ,d.CATEGORYNAME2 ,VIPID, VIP_SPNAME,MAXFLOW,PRICE,").appendLn(
				"ORDERTIME,CANCELTIME,ORDER_TIME2,CANCELTIME2,").appendLn(
				"dateDiff('month', ORDERTIME,mstr) DIFF_MONYH,").appendLn(
				"dateDiff('month', if(CANCELTIME='1970-01-01',addMonths(mstr,1),CANCELTIME),mstr) DIFF_CANCEL_MONYH,").appendLn(
				"USERID2,LLCP,FLOW,if(MAXFLOW=='',0,FLOW/toFloat64OrNull(MAXFLOW))*100 as flow_P").appendLn(
				"from").appendLn(
				"(").appendLn(
				"	select").appendLn(
				"	if(o1.THEMONTH=0,toString(o2.THEMONTH),toString(o1.THEMONTH)) as THEMONTH,").appendLn(
				"	if(isNull(o1.PROVINCE) or o1.PROVINCE='' ,o2.PROVINCE,o1.PROVINCE) as PROVINCE,").appendLn(
				"	if(isNull(o1.AREA) or o1.AREA='',o2.AREA,o1.AREA) as AREA,").appendLn(
				"	CHANNEL,d1.BELONGTO as BELONGTO,").appendLn(
				"	if(isNull(o1.CPID) or o1.CPID='',o2.CPID,o1.CPID) as CPID,").appendLn(
				"	if(isNull(o1.SPID) or o1.SPID='',o2.SPID,o1.SPID) as SPID,").appendLn(
				"	if(o1.USERID='',o2.USERID,o1.USERID) as USERID,").appendLn(
				"	ORDERTIME,CANCELTIME,ENDTIME,").appendLn(
				"	toYear(ORDERTIME) as ORDER_TIME1,").appendLn(
				"	multiIf(ORDER_TIME1<2017,'2017L',ORDER_TIME1>2027,'2027R',toString(ORDER_TIME1)) as ORDER_TIME2,").appendLn(
				"	toYear(CANCELTIME) as CANCELTIME1,").appendLn(
				"	multiIf(CANCELTIME1<2017 and CANCELTIME1!=1970,'2017L',toString(CANCELTIME1)) as CANCELTIME2,").appendLn(
				"	LLCP,VIPID, if(VIPID='','未领取',VIP_SPNAME) as VIP_SPNAME,").appendLn(
				"	if(o2.USERID='',-1,FLOW) as FLOW,").appendLn(
				"	o1.USERID USERID1,").appendLn(
				"	o2.USERID USERID2").appendLn(
				"	from").appendLn(
				" (").append(
				" select * from ads.ETL_TD_ORDER_RELATIONS_YEAR where THEMONTH ='"+month+"'").appendLn(lrMobileSql).appendLn(
				" ) o1").appendLn(
				"	left join (").appendLn(
				"		select any(THEMONTH) as THEMONTH ,USERID,SPID,any(CPID) as CPID,any(SPNAME) as SPNAME ,").appendLn(
				"		toString(groupArray(LLCP)) as LLCP,").appendLn(
				"		sum(FLOW) FLOW,any(PROVINCE) as PROVINCE,any(AREA) as AREA from").appendLn(
				"		(").append(
				"			SELECT * from ads.TD_DXFLOWINPUT_MONTH where THEMONTH ='"+month+"'").appendLn(lrMobileSql).appendLn(
				"		) group by USERID,SPID").appendLn(
				"	)o2").appendLn(
				"	on o1.USERID=o2.USERID and o1.SPID=o2.SPID").appendLn(
				"  left join").appendLn(
				"  (").appendLn(
				"		select USERVAL,VIPID,if(`ds.VIPID`=='','',ds.SPNAME) as VIP_SPNAME").appendLn(
				"		from ads.ETL_TL_VIP_LOG a1").appendLn(
				"		left join (select * from ads.DIM_SXXHY  where SETID =1) ds").appendLn(
				"		on a1.VIPID =ds.VIPID").append(
				"		where THEDAY >='"+theLeftDay+"' and THEDAY<'"+theRightDay+"'").appendLn(lrUserIdSql).appendLn(
//				"		--and VIPID in(select VIPID from ads.DIM_SXXHY where SETID =1)").appendLn(
				"	) o3 on o1.USERID=o3.USERVAL").appendLn(
				"   left join ads.DIM_TB_CHANNELS d1 on o1.CHANNEL=d1.ID").appendLn(
				") s1").appendLn(
				"left join ads.ETL_V_TB_SP_INFO d  on s1.SPID=d.SPID").appendLn(
				") s");
		log.info("\n" + sqlBuilder.toString());
		dynamicExecuteService.execute(DsEnum.clickhouse, sqlBuilder.toString(), "信息化标签生成");
	}
	
	/**
	 * 订购产品时长
	 * @param sqlBuilder
	 * @param tagMap
	 */
	public void appendEventOrderMonth(StrBuilder sqlBuilder, Map<String, List<UserprofileTag>> tagListMap) {
		/**
		 * (case when  DIFF_MONYH=0  then 'B112_11_002'
			when  DIFF_MONYH>=1 and DIFF_MONYH<3 then 'B112_11_003'
			when  DIFF_MONYH>=3 and DIFF_MONYH<6 then 'B112_11_004'
			when  DIFF_MONYH>=6 and DIFF_MONYH<12 then 'B112_11_005'
			when  DIFF_MONYH>=12 and DIFF_MONYH<24 then 'B112_11_006'
			when  DIFF_MONYH>=24  then 'B112_11_007'
			 end) EVENT_ORDER_MONTH,
		 */
		String sql = genBucketSql("event_order_month", "DIFF_MONYH", "DIFF_MONYH", tagListMap.get("event_order_month"));
		sqlBuilder.append(sql);
	}

	/**
	 * 退订产品时长
	 * @param sqlBuilder
	 * @param tagMap
	 */
	public void appendEventCancelDiff(StrBuilder sqlBuilder, Map<String, List<UserprofileTag>> tagListMap) {
		/**
		 * (case when  DIFF_CANCEL_MONYH<0  then 'B112_12_001'
			when  DIFF_CANCEL_MONYH=0  then 'B112_12_002'
			when  DIFF_CANCEL_MONYH>=1 and DIFF_CANCEL_MONYH<3 then 'B112_12_003'
			when  DIFF_CANCEL_MONYH>=3 and DIFF_CANCEL_MONYH<6 then 'B112_12_004'
			when  DIFF_CANCEL_MONYH>=6 and DIFF_CANCEL_MONYH<12 then 'B112_12_005'
			when  DIFF_CANCEL_MONYH>=12  then 'B112_12_006'
			 end) EVENT_CANCEL_DIFF,
		 */
		String sql = genBucketSql("event_cancel_diff", "DIFF_CANCEL_MONYH", "DIFF_CANCEL_MONYH", tagListMap.get("event_cancel_diff"));
		sqlBuilder.append(sql);
	}

	/**
	 * 订购产品价格
	 * @param sqlBuilder
	 * @param tagMap
	 */
	public void appendEventOrderPrice(StrBuilder sqlBuilder, Map<String, List<UserprofileTag>> tagListMap) {
		/**
		 * (case when  PRICE=0  then 'B112_16_002'
			when  PRICE>=1 and PRICE<=3 then 'B112_16_003'
			when  PRICE>3 and PRICE<=8 then 'B112_16_004'
			when  PRICE>8 and PRICE<=15 then 'B112_16_005'
			when  PRICE>15 and PRICE<=20 then 'B112_16_006'
			when  PRICE>20  then 'B112_16_007'
			else 'B112_16_001'
			 end) EVENT_ORDER_PRICE,
		 */
		String sql = genBucketSql("event_order_price", "PRICE", "PRICE", tagListMap.get("event_order_price"));
		sqlBuilder.append(sql);
	}

	/**
	 * 产品免流量使用比
	 */
	public void appendEventOrderFlowp(StrBuilder sqlBuilder, Map<String, List<UserprofileTag>> tagListMap) {
		/**
		 * (case when flow_P>=0 and flow_P<=5 then 'B112_17_001'
			when  flow_P>5 and flow_P<=20 then 'B112_17_002'
			when  flow_P>20 and flow_P<=50 then 'B112_17_003'
			when  flow_P>50 and flow_P<=80 then 'B112_17_004'
			when  flow_P>80 then 'B112_17_005'
			else 'B112_17_006'
			 end) EVENT_ORDER_FLOWP,
		 */
		String sql = genBucketSql("event_order_flowp", "flow_P", "flow_P", tagListMap.get("event_order_flowp"));
		sqlBuilder.append(sql);
	}
	
	/**
	 * 产品订购状态
	 * @param sqlBuilder
	 * @param tagMap
	 */
	public void appendEventOrderState(String month, StrBuilder sqlBuilder, Map<String, List<UserprofileTag>> tagListMap) {
		/**
		 * (case when OTSTR = '202111' AND CTSTR <> '202111' then 'B112_25_001'
			when OTSTR = '202111' AND CTSTR = '202111' then 'B112_25_002'
			when OTSTR < '202111' AND (CANCELTIME > '1970-01-01' and CTSTR < '202111') then 'B112_25_003'
			when OTSTR < '202111' AND (CANCELTIME = '1970-01-01' or CTSTR > '202111') then 'B112_25_004'
			when OTSTR < '202111' AND CTSTR = '202111' then 'B112_25_005'
			else 'B112_25_006'
		   end) EVENT_ORDER_STATE,
		 */
		Map<String, String> params = new HashMap<>();
		params.put("yearmonth", month);
		String sql = genBucketSql("event_order_state", "", "EVENT_ORDER_STATE_C", tagListMap.get("event_order_state"), params);
		sqlBuilder.append(sql);
	}
	
	/**
	 * 产品免流量使用比
	 */
	public void appendEventFreeLimitFlow(StrBuilder sqlBuilder, Map<String, List<UserprofileTag>> tagListMap) {
		String sql = genBucketSql("event_freelimit_flowp", "FLOW", "FLOW", tagListMap.get("event_freelimit_flowp"));
		sqlBuilder.append(sql);
	}
	
	@Override
	public boolean executeInBatchs() {
		return true;
	}

	@Override
	public long calcMobileRangeStep() {
		return _STEP;
	}
}