package com.ffii.fpsms.modules.usage.web;

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

import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.ffii.core.exception.BadRequestException;
import com.ffii.core.response.DataRes;
import com.ffii.fpsms.modules.common.SecurityUtils;
import com.ffii.fpsms.modules.usage.FeatureUsageLogService;
import com.ffii.fpsms.modules.user.entity.User;

@RestController
@RequestMapping("/feature-usage")
public class FeatureUsageLogController {

	private final FeatureUsageLogService featureUsageLogService;

	public FeatureUsageLogController(FeatureUsageLogService featureUsageLogService) {
		this.featureUsageLogService = featureUsageLogService;
	}

	public static class LogRequest {
		private String featureCode;
		private String actionType;
		private String detail;

		public String getFeatureCode() {
			return featureCode;
		}

		public void setFeatureCode(String featureCode) {
			this.featureCode = featureCode;
		}

		public String getActionType() {
			return actionType;
		}

		public void setActionType(String actionType) {
			this.actionType = actionType;
		}

		public String getDetail() {
			return detail;
		}

		public void setDetail(String detail) {
			this.detail = detail;
		}
	}

	@PostMapping("/log")
	public ResponseEntity<Void> log(@RequestBody LogRequest body) {
		User user = SecurityUtils.getUser().orElseThrow(() -> new BadRequestException("Not authenticated"));
		validateLogRequest(body);
		featureUsageLogService.insert(user, body.getFeatureCode(), body.getActionType(), body.getDetail());
		return ResponseEntity.status(HttpStatus.CREATED).build();
	}

	private void validateLogRequest(LogRequest body) {
		if (body == null || StringUtils.isBlank(body.getFeatureCode()) || StringUtils.isBlank(body.getActionType())) {
			throw new BadRequestException("featureCode and actionType are required");
		}
		String fc = body.getFeatureCode();
		String at = body.getActionType();
		if (!FeatureUsageLogService.FEATURE_REPORT_MANAGEMENT.equals(fc)
				&& !FeatureUsageLogService.FEATURE_TRUCK_ROUTING_SUMMARY.equals(fc)) {
			throw new BadRequestException("Invalid featureCode");
		}
		if (!FeatureUsageLogService.ACTION_PAGE_VIEW.equals(at)
				&& !FeatureUsageLogService.ACTION_DOWNLOAD.equals(at)
				&& !FeatureUsageLogService.ACTION_PRINT.equals(at)) {
			throw new BadRequestException("Invalid actionType");
		}
		if (FeatureUsageLogService.ACTION_PRINT.equals(at)
				&& !FeatureUsageLogService.FEATURE_TRUCK_ROUTING_SUMMARY.equals(fc)) {
			throw new BadRequestException("PRINT is only valid for TRUCK_ROUTING_SUMMARY");
		}
	}

	@GetMapping("/summary")
	@PreAuthorize("hasAnyAuthority('TESTING','ADMIN')")
	public DataRes<Map<String, List<Map<String, Object>>>> summary(
			@RequestParam(value = "startDate", required = false) LocalDate startDate,
			@RequestParam(value = "endDate", required = false) LocalDate endDate) {
		if (startDate != null && endDate != null && startDate.isAfter(endDate)) {
			throw new BadRequestException("startDate must be earlier than or equal to endDate");
		}
		Map<String, List<Map<String, Object>>> data = new HashMap<>(2);
		data.put("reportManagement",
				featureUsageLogService.summarizeByFeature(FeatureUsageLogService.FEATURE_REPORT_MANAGEMENT, startDate, endDate));
		data.put("truckRoutingSummary",
				featureUsageLogService.summarizeByFeature(FeatureUsageLogService.FEATURE_TRUCK_ROUTING_SUMMARY, startDate, endDate));
		return new DataRes<>(data);
	}

}
