package com.cloudhandson.vpdbackoffice.service;

import com.cloudhandson.vpdbackoffice.domain.structured.StructuredDataPreview;
import com.cloudhandson.vpdbackoffice.domain.structured.StructuredDataTable;
import java.util.List;
import java.util.Map;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

@Service
public class StructuredDataService {

  private static final int ROW_LIMIT = 50;
  private final JdbcTemplate jdbcTemplate;
  private final DataCatalog catalog;

  public StructuredDataService(JdbcTemplate jdbcTemplate, DataCatalog catalog) {
    this.jdbcTemplate = jdbcTemplate;
    this.catalog = catalog;
  }

  public List<StructuredDataTable> tables() {
    return catalog.objects();
  }

  public String defaultKey() {
    return catalog.objects().getFirst().key();
  }

  public StructuredDataTable requireTable(String key) {
    return catalog.require(key);
  }

  public StructuredDataPreview preview(String key) {
    StructuredDataTable table = requireTable(key);
    try {
      List<String> columns = jdbcTemplate.query(
          """
              SELECT column_name
              FROM all_tab_columns
              WHERE owner = ?
                AND table_name = ?
              ORDER BY column_id
              """,
          (resultSet, rowNum) -> resultSet.getString(1), catalog.owner(), table.tableName());
      if (columns.isEmpty()) {
        throw new AppException("정형 데이터 테이블의 컬럼 정보를 찾을 수 없습니다.");
      }

      List<Map<String, Object>> rows = jdbcTemplate.queryForList(
          previewSql(table), ROW_LIMIT);
      return new StructuredDataPreview(table, columns, rows, ROW_LIMIT);
    } catch (DataAccessException exception) {
      throw new AppException("카탈로그 데이터를 조회할 수 없습니다. DB 권한과 대상 객체 상태를 확인하세요.");
    }
  }

  private String previewSql(StructuredDataTable table) {
    return "SELECT * FROM \"" + catalog.owner() + "\".\"" + table.tableName() + "\" WHERE ROWNUM <= ?";
  }
}
