package com.ffii.fpsms.modules.usage;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.time.LocalDate;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import com.ffii.core.support.AbstractService;
import com.ffii.core.support.JdbcDao;
import com.ffii.fpsms.modules.user.entity.User;

@Service
public class FeatureUsageLogService extends AbstractService {

	public static final String FEATURE_REPORT_MANAGEMENT = "REPORT_MANAGEMENT";
	public static final String FEATURE_TRUCK_ROUTING_SUMMARY = "TRUCK_ROUTING_SUMMARY";

	public static final String ACTION_PAGE_VIEW = "PAGE_VIEW";
	public static final String ACTION_DOWNLOAD = "DOWNLOAD";
	public static final String ACTION_PRINT = "PRINT";

	public FeatureUsageLogService(JdbcDao jdbcDao) {
		super(jdbcDao);
	}

	@Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class, readOnly = false)
	public void insert(User user, String featureCode, String actionType, String detail) {
		String sql = "INSERT INTO feature_usage_log (`user_id`, `username`, `feature_code`, `action_type`, `detail`) "
				+ "VALUES (:userId, :username, :featureCode, :actionType, :detail)";
		Map<String, Object> args = new HashMap<>(8);
		args.put("userId", user.getId());
		args.put("username", user.getUsername());
		args.put("featureCode", featureCode);
		args.put("actionType", actionType);
		args.put("detail", StringUtils.isBlank(detail) ? null : StringUtils.left(detail, 512));
		jdbcDao.executeUpdate(sql, args);
	}

	@Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class, readOnly = true)
	public List<Map<String, Object>> summarizeByFeature(String featureCode, LocalDate startDate, LocalDate endDate) {
		StringBuilder sql = new StringBuilder("""
				SELECT user_id AS userId, username,
				  SUM(CASE WHEN action_type = 'PAGE_VIEW' THEN 1 ELSE 0 END) AS pageViews,
				  SUM(CASE WHEN action_type = 'DOWNLOAD' THEN 1 ELSE 0 END) AS downloads,
				  SUM(CASE WHEN action_type = 'PRINT' THEN 1 ELSE 0 END) AS prints
				FROM feature_usage_log
				WHERE feature_code = :featureCode
				""");
		Map<String, Object> args = new HashMap<>(4);
		args.put("featureCode", featureCode);
		if (startDate != null) {
			sql.append(" AND created_at >= :startDate");
			args.put("startDate", startDate.atStartOfDay());
		}
		if (endDate != null) {
			sql.append(" AND created_at < :endDateExclusive");
			args.put("endDateExclusive", endDate.plusDays(1).atStartOfDay());
		}
		sql.append("""
				
				GROUP BY user_id, username
				ORDER BY username
				""");
		return jdbcDao.queryForList(sql.toString(), args);
	}

}
