package com.cloudhandson.vpdbackoffice.web;

import com.cloudhandson.vpdbackoffice.service.AppException;
import com.cloudhandson.vpdbackoffice.service.SchemaMetadataService;
import org.springframework.dao.DataAccessException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

@Controller
public class SchemaMetadataController {

  private static final Logger log = LoggerFactory.getLogger(SchemaMetadataController.class);

  private final SchemaMetadataService schemaMetadataService;

  public SchemaMetadataController(SchemaMetadataService schemaMetadataService) {
    this.schemaMetadataService = schemaMetadataService;
  }

  @GetMapping("/schema-metadata")
  public String schemaMetadata(@RequestParam(required = false) String table, Model model) {
    String selectedKey = table == null || table.isBlank() ? schemaMetadataService.defaultKey() : table;
    model.addAttribute("tables", schemaMetadataService.tables());
    model.addAttribute("selectedKey", selectedKey);
    try {
      model.addAttribute("metadata", schemaMetadataService.find(selectedKey));
    } catch (AppException | DataAccessException exception) {
      log.warn("Schema metadata lookup failed for table key={}", selectedKey, exception);
      model.addAttribute("errorMessage", readMessage(exception));
    }
    return "schema-metadata";
  }

  @PostMapping("/schema-metadata/table-comment")
  public String updateTableComment(
      @RequestParam String table,
      @RequestParam(required = false) String comment,
      RedirectAttributes redirectAttributes
  ) {
    try {
      schemaMetadataService.updateTableComment(table, comment);
      redirectAttributes.addFlashAttribute("message", "테이블 comment를 저장했습니다.");
    } catch (AppException | DataAccessException exception) {
      redirectAttributes.addFlashAttribute("errorMessage", safeMessage(exception));
    }
    return redirect(table);
  }

  @PostMapping("/schema-metadata/column-comment")
  public String updateColumnComment(
      @RequestParam String table,
      @RequestParam String column,
      @RequestParam(required = false) String comment,
      RedirectAttributes redirectAttributes
  ) {
    try {
      schemaMetadataService.updateColumnComment(table, column, comment);
      redirectAttributes.addFlashAttribute("message", column + " 컬럼 comment를 저장했습니다.");
    } catch (AppException | DataAccessException exception) {
      redirectAttributes.addFlashAttribute("errorMessage", safeMessage(exception));
    }
    return redirect(table);
  }

  @PostMapping("/schema-metadata/table-annotation")
  public String updateTableAnnotation(
      @RequestParam String table,
      @RequestParam String annotationName,
      @RequestParam(required = false) String annotationValue,
      RedirectAttributes redirectAttributes
  ) {
    try {
      schemaMetadataService.updateTableAnnotation(table, annotationName, annotationValue);
      redirectAttributes.addFlashAttribute("message", "테이블 annotation을 저장했습니다.");
    } catch (AppException | DataAccessException exception) {
      redirectAttributes.addFlashAttribute("errorMessage", safeMessage(exception));
    }
    return redirect(table);
  }

  @PostMapping("/schema-metadata/column-annotation")
  public String updateColumnAnnotation(
      @RequestParam String table,
      @RequestParam String column,
      @RequestParam String annotationName,
      @RequestParam(required = false) String annotationValue,
      RedirectAttributes redirectAttributes
  ) {
    try {
      schemaMetadataService.updateColumnAnnotation(table, column, annotationName, annotationValue);
      redirectAttributes.addFlashAttribute("message", column + " 컬럼 annotation을 저장했습니다.");
    } catch (AppException | DataAccessException exception) {
      redirectAttributes.addFlashAttribute("errorMessage", safeMessage(exception));
    }
    return redirect(table);
  }

  private String redirect(String table) {
    return "redirect:/schema-metadata?table=" + (table == null ? "" : table);
  }

  private String safeMessage(Exception exception) {
    return exception instanceof AppException
        ? exception.getMessage()
        : "DB 메타데이터를 저장하지 못했습니다. 권한, 식별자, Oracle annotation 문법을 확인하세요.";
  }

  private String readMessage(Exception exception) {
    return exception instanceof AppException
        ? exception.getMessage()
        : "DB 메타데이터를 조회하지 못했습니다. 카탈로그 소유자 조회 권한과 대상 객체 상태를 확인하세요.";
  }
}
