package com.cloudhandson.ddsbackoffice.web;

import com.cloudhandson.ddsbackoffice.domain.DdsProvisioningPlan;
import com.cloudhandson.ddsbackoffice.service.DdsGrantPublisher;
import com.cloudhandson.ddsbackoffice.service.DdsMcpEndUserPublisher;
import com.cloudhandson.ddsbackoffice.service.DdsProtectionEvidenceStore;
import com.cloudhandson.ddsbackoffice.service.DdsProtectionFingerprint;
import com.cloudhandson.ddsbackoffice.domain.DdsPublishedProtectionSpec;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

@Controller
public class DdsProvisionController {

  private final DdsGrantPublisher publisher;
  private final DdsMcpEndUserPublisher mcpEndUserPublisher;
  private final DdsProtectionEvidenceStore evidenceStore;

  public DdsProvisionController(
      DdsGrantPublisher publisher,
      DdsMcpEndUserPublisher mcpEndUserPublisher,
      DdsProtectionEvidenceStore evidenceStore
  ) {
    this.publisher = publisher;
    this.mcpEndUserPublisher = mcpEndUserPublisher;
    this.evidenceStore = evidenceStore;
  }

  @GetMapping("/dds-provision")
  public String page(Model model) {
    loadPlan(model);
    return "dds-provision";
  }

  @PostMapping("/dds-provision/publish")
  public String publish(RedirectAttributes redirectAttributes) {
    try {
      DdsProvisioningPlan plan = publisher.publish();
      var mcpResult = mcpEndUserPublisher.publish();
      redirectAttributes.addFlashAttribute(
          "successMessage",
          plan.publishableCount() + "개 직접 DDS DATA GRANT와 "
              + mcpResult.publishedUsers() + "개 MCP local END USER 권한을 게시했습니다."
      );
      if (mcpResult.defaultDeniedUsers() > 0 || mcpResult.revokedUsers() > 0) {
        redirectAttributes.addFlashAttribute("warningMessage",
            "MCP 기본 거부 " + mcpResult.defaultDeniedUsers() + "명, 비활성 사용자 권한 회수 "
                + mcpResult.revokedUsers() + "명을 반영했습니다.");
      }
      try {
        plan.grants().forEach(grant -> evidenceStore.recordPublished(
            new DdsPublishedProtectionSpec(
                "DIRECT", grant.userKey(), DdsProtectionFingerprint.direct(grant), java.time.Instant.now()),
            "DDS Backoffice", "DDS 권한 반영"
        ));
      } catch (DataAccessException exception) {
        redirectAttributes.addFlashAttribute("warningMessage",
            "DDS Grant는 게시됐지만 상태 이력 저장에 실패했습니다. 상태 이력 DB 설정을 확인하세요.");
      }
      if (plan.hasWarnings()) {
        redirectAttributes.addFlashAttribute("warningMessage", String.join(" / ", plan.warnings()));
      }
    } catch (DataAccessException | IllegalArgumentException exception) {
      redirectAttributes.addFlashAttribute("errorMessage", exception.getMessage());
    }
    return "redirect:/dds-provision";
  }

  private void loadPlan(Model model) {
    try {
      model.addAttribute("plan", publisher.preview());
    } catch (DataAccessException | IllegalArgumentException exception) {
      model.addAttribute("plan", new DdsProvisioningPlan(java.util.List.of(),
          java.util.List.of(exception.getMessage()), 0));
    }
  }
}
