<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="provisioning">

  <select id="existsCompanyCode" parameterType="map" resultType="int">
    SELECT 1 FROM COMPANY_MNG WHERE COMPANY_CODE = #{company_code} LIMIT 1
  </select>

  <select id="existsSubdomain" parameterType="map" resultType="int">
    SELECT 1 FROM COMPANY_MNG WHERE SUBDOMAIN = #{subdomain} LIMIT 1
  </select>

  <select id="existsDbName" parameterType="map" resultType="int">
    SELECT 1 FROM COMPANY_MNG WHERE DB_NAME = #{db_name} LIMIT 1
  </select>

  <insert id="insertCompanyWithTenant" parameterType="map">
    INSERT INTO COMPANY_MNG (
        COMPANY_CODE
        , COMPANY_NAME
        , BUSINESS_REGISTRATION_NUMBER
        , REPRESENTATIVE_NAME
        , REPRESENTATIVE_PHONE
        , EMAIL
        , WEBSITE
        , ADDRESS
        , STATUS
        , DB_NAME
        , SUBDOMAIN
        , DB_HOST
        , DB_STATUS
        , PLAN
        , INDUSTRY
        , TEMPLATES_COUNT
        , WRITER
        , CREATED_DATE
    ) VALUES (
        #{company_code}
        , #{company_name}
        , #{business_registration_number}
        , #{representative_name}
        , #{representative_phone}
        , #{email}
        , #{website}
        , #{address}
        , COALESCE(#{status}, 'active')
        , #{db_name}
        , #{subdomain}
        , #{db_host}
        , COALESCE(#{db_status}, 'provisioning')
        , COALESCE(#{plan}, 'Starter')
        , #{industry}
        , COALESCE(#{templates_count}, 0)
        , #{writer}
        , NOW()
    )
  </insert>

  <!--
    회사관리 UI (v9 accordion) 렌더용 전체 목록.
    정적 필드만 반환. users / active30 / db_size / spark 등 derived 는 CompanyStatsService 가 덧붙임.
  -->
  <select id="listCompaniesForUi" resultType="map">
    SELECT
        COMPANY_CODE                    as company_code
      , COMPANY_NAME                    as company_name
      , SUBDOMAIN                       as subdomain
      , DB_NAME                         as db_name
      , DB_HOST                         as db_host
      , DB_STATUS                       as db_status
      , STATUS                          as status
      , COALESCE(PLAN, 'Starter')       as plan
      , INDUSTRY                        as industry
      , REPRESENTATIVE_NAME             as owner
      , BUSINESS_REGISTRATION_NUMBER    as brn
      , EMAIL                           as email
      , COALESCE(TEMPLATES_COUNT, 0)    as templates
      , COALESCE(DB_QUOTA_GB, 20)       as db_quota_gb
      , CREATED_DATE                    as created
      , WRITER                          as writer
    FROM COMPANY_MNG
    ORDER BY CREATED_DATE DESC NULLS LAST, COMPANY_CODE
  </select>

  <update id="updateDbStatus" parameterType="map">
    UPDATE COMPANY_MNG
       SET DB_STATUS = #{db_status}
     WHERE COMPANY_CODE = #{company_code}
  </update>

  <!-- 부팅 시 스키마 마이그레이션 러너용: 활성 테넌트 DB 이름 목록 -->
  <select id="listActiveDbNames" resultType="string">
    SELECT DB_NAME
      FROM COMPANY_MNG
     WHERE DB_STATUS = 'active'
       AND DB_NAME IS NOT NULL
  </select>

  <!-- 회사 상세 조회 (lifecycle 관리 액션 수행 전 검증용) -->
  <select id="selectCompanyByCode" parameterType="map" resultType="map">
    SELECT
        COMPANY_CODE                    as company_code
      , COMPANY_NAME                    as company_name
      , SUBDOMAIN                       as subdomain
      , DB_NAME                         as db_name
      , DB_HOST                         as db_host
      , DB_STATUS                       as db_status
      , STATUS                          as status
      , COALESCE(INSTALLED_GROUPS, '[]'::jsonb) as installed_groups
      , DEACTIVATED_AT                  as deactivated_at
      , DEACTIVATION_REASON             as deactivation_reason
      , CREATED_DATE                    as created
    FROM COMPANY_MNG
    WHERE COMPANY_CODE = #{company_code}
  </select>

  <!-- 비활성화: DB_STATUS='suspended' + 타임스탬프/사유 기록 -->
  <update id="deactivateCompany" parameterType="map">
    UPDATE COMPANY_MNG
       SET DB_STATUS           = 'suspended'
         , DEACTIVATED_AT      = NOW()
         , DEACTIVATION_REASON = #{reason}
     WHERE COMPANY_CODE = #{company_code}
  </update>

  <!-- 재활성화: DB_STATUS='active' + 타임스탬프/사유 클리어 -->
  <update id="reactivateCompany" parameterType="map">
    UPDATE COMPANY_MNG
       SET DB_STATUS           = 'active'
         , DEACTIVATED_AT      = NULL
         , DEACTIVATION_REASON = NULL
     WHERE COMPANY_CODE = #{company_code}
  </update>

  <!-- 영구 삭제 (메타 DB row). 실제 DROP DATABASE 는 서비스 레이어가 먼저 실행 -->
  <delete id="deleteCompany" parameterType="map">
    DELETE FROM COMPANY_MNG
     WHERE COMPANY_CODE = #{company_code}
  </delete>

  <!-- installed_groups 저장 (provisioning 시 selected_groups 를 JSONB 로) -->
  <update id="updateInstalledGroups" parameterType="map">
    UPDATE COMPANY_MNG
       SET INSTALLED_GROUPS = #{installed_groups_json}::jsonb
     WHERE COMPANY_CODE = #{company_code}
  </update>

  <!-- ─────────────── 회사 관리 감사 로그 (COMPANY_AUDIT_LOG) ─────────────── -->

  <insert id="insertAuditLog" parameterType="map">
    INSERT INTO COMPANY_AUDIT_LOG (
        COMPANY_CODE
      , ACTOR_USER_ID
      , ACTION
      , TARGET
      , DETAILS
      , SUCCESS
      , ERROR_MESSAGE
      , CREATED_AT
    ) VALUES (
        #{company_code}
      , #{actor_user_id}
      , #{action}
      , #{target}
      , <choose>
          <when test="details_json != null">#{details_json}::jsonb</when>
          <otherwise>NULL</otherwise>
        </choose>
      , COALESCE(#{success}, TRUE)
      , #{error_message}
      , NOW()
    )
  </insert>

  <select id="selectAuditLog" parameterType="map" resultType="map">
    SELECT
        ID             as id
      , COMPANY_CODE   as company_code
      , ACTOR_USER_ID  as actor_user_id
      , ACTION         as action
      , TARGET         as target
      , DETAILS        as details
      , SUCCESS        as success
      , ERROR_MESSAGE  as error_message
      , CREATED_AT     as created_at
    FROM COMPANY_AUDIT_LOG
    <where>
      <if test="company_code != null">AND COMPANY_CODE = #{company_code}</if>
      <if test="action != null">AND ACTION = #{action}</if>
    </where>
    ORDER BY CREATED_AT DESC, ID DESC
    LIMIT #{limit} OFFSET #{offset}
  </select>

  <select id="countAuditLog" parameterType="map" resultType="long">
    SELECT COUNT(*) FROM COMPANY_AUDIT_LOG
    <where>
      <if test="company_code != null">AND COMPANY_CODE = #{company_code}</if>
      <if test="action != null">AND ACTION = #{action}</if>
    </where>
  </select>

  <!--
    Phase A (cross-tenant 집계, 2026-04-27): SUPER_ADMIN fan-out 대상 회사 목록.
    listCompaniesForUi 와 다름 — 그 쿼리는 회사관리 화면 렌더용으로 모든 상태 포함.
    이건 active 상태만, 라우팅 가능한(DB_NAME 박힌) 회사만.
  -->
  <select id="listActiveCompanies" resultType="map">
    SELECT
        COMPANY_CODE   AS company_code
      , COMPANY_NAME   AS company_name
      , DB_NAME        AS db_name
    FROM COMPANY_MNG
    WHERE DB_STATUS = 'active'
      AND DB_NAME IS NOT NULL
    ORDER BY COMPANY_CODE
  </select>

  <!--
    company_code 로 db_name 직접 조회 (cross-tenant write 라우팅용).
    SUPER_ADMIN 이 admin 도메인에서 특정 회사 DB 로 임시 컨텍스트 전환할 때
    CrossTenantExecutor 가 호출. active 회사만 라우팅 허용.
  -->
  <select id="resolveDbNameByCompanyCode" parameterType="map" resultType="string">
    SELECT DB_NAME
    FROM COMPANY_MNG
    WHERE COMPANY_CODE = #{company_code}
      AND DB_STATUS = 'active'
      AND DB_NAME IS NOT NULL
    LIMIT 1
  </select>

</mapper>
