package com.cloudhandson.ddsbackoffice.service;

import com.cloudhandson.ddsbackoffice.domain.DdsMcpEndUserPrincipal;
import com.cloudhandson.vpdbackoffice.service.AppException;
import java.util.List;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

/** Resolves only published local DDS identities. Missing mappings always deny. */
@Service
public class DdsMcpEndUserResolver {

  private final JdbcTemplate jdbcTemplate;

  public DdsMcpEndUserResolver(JdbcTemplate jdbcTemplate) {
    this.jdbcTemplate = jdbcTemplate;
  }

  public DdsMcpEndUserPrincipal resolve(long applicationUserId) {
    try {
      List<DdsMcpEndUserPrincipal> principals = jdbcTemplate.query("""
          SELECT m.application_user_id, m.end_user_name, m.data_role_name, m.lookup_key_ref
          FROM cb_dds_end_user_map m
          JOIN cb_app_user u ON u.user_id = m.application_user_id
          WHERE m.application_user_id = ?
            AND m.publish_status = 'PUBLISHED'
            AND u.active = 'Y'
          """, (row, ignored) -> new DdsMcpEndUserPrincipal(
              row.getLong("application_user_id"),
              row.getString("end_user_name"),
              row.getString("data_role_name"),
              row.getString("lookup_key_ref")), applicationUserId);
      if (principals.size() != 1) {
        throw denied();
      }
      DdsMcpEndUserPrincipal principal = principals.getFirst();
      if (!safeEndUserName(principal.endUserName()) || !safeDataRoleName(principal.dataRoleName())) {
        throw denied();
      }
      return principal;
    } catch (AppException exception) {
      throw exception;
    } catch (DataAccessException exception) {
      throw new AppException("DDS_CONTEXT_UNAVAILABLE: DDS END USER 게시 상태를 확인할 수 없습니다.");
    }
  }

  private AppException denied() {
    return new AppException("AUTHORIZATION_DENIED: DDS END USER가 게시되지 않았습니다.");
  }

  private boolean safeEndUserName(String value) {
    return value != null && value.matches("DDS_U_[0-9]{1,30}");
  }

  private boolean safeDataRoleName(String value) {
    return value != null && value.matches("DDS_U_[0-9]{1,30}_ROLE");
  }
}
