from src.batch.batch_functions import logging_sql
from src.batch.common.batch_context import BatchContext
from src.db.database import Database
from src.error.exceptions import BatchOperationException
from src.logging.get_logger import get_logger
from src.time.elapsed_time import ElapsedTime

logger = get_logger('納入先処方元マスタ洗替')
batch_context = BatchContext.get_instance()


def exec():
    db = Database.get_instance()
    try:
        db.connect()
        logger.debug('納入先処方元マスタの洗替処理開始')
        # ult_ident_presc_lauをTruncate
        _truncate_ult_ident_presc_lau(db)
        # ult_ident_presc から、ult_ident_presc_lauへInsert
        _insert_into_ult_ident_presc_lau_from_ult_ident_presc(db)
        # v_inst_merge_tから、ult_ident_presc_lauをUpdate
        _update_ult_ident_presc_lau_from_v_inst_merge_t(db)
        # inst_merge_tから、ult_ident_presc_lauをUpdate
        _update_ult_ident_presc_lau_from_inst_merge_t(db)
        logger.debug('納入先処方元マスタの洗替処理製造終了')
    except Exception as e:
        raise BatchOperationException(e)
    finally:
        db.disconnect()


def _truncate_ult_ident_presc_lau(db: Database):
    try:
        db.execute("TRUNCATE TABLE src05.ult_ident_presc_lau")
    except Exception as e:
        logger.debug("納入先処方元マスタ(洗替後)の全件削除に失敗")
        raise e

    logger.debug("納入先処方元マスタ(洗替後)の全件削除に成功")
    return


def _insert_into_ult_ident_presc_lau_from_ult_ident_presc(db: Database):
    try:
        elapsed_time = ElapsedTime()
        sql = "INSERT INTO src05.ult_ident_presc_lau SELECT *, NULL FROM src05.ult_ident_presc"
        res = db.execute(sql)
        logging_sql(logger, sql)
        logger.info(f'処方元マスタから処方元マスタ(洗替後)に全件コピーに成功, {res.rowcount} 行更新 ({elapsed_time.of})')
    except Exception as e:
        logger.debug("処方元マスタから処方元マスタ(洗替後)に全件コピーに失敗")
        raise e

    return


def _update_ult_ident_presc_lau_from_v_inst_merge_t(db: Database):
    # v_inst_merge_tの元となるvop_hco_merge_vはデータが作られないため、この洗い替え処理は基本空振りする
    try:
        select_result = db.execute_select(
            """
            SELECT
                COUNT(v_inst_cd) AS row_count
            FROM
                internal05.v_inst_merge_t
            """
        )
    except Exception as e:
        logger.debug("V施設統合マスタ(洗替処理一時テーブル)からの移行対象施設件数取得失敗")
        raise e
    count = [row for row in select_result][0]['row_count']
    if count == 0:
        logger.info('V施設統合マスタ(洗替処理一時テーブル)からの移行対象施設が存在しません')
        return

    logger.info(f'V施設統合マスタ(洗替処理一時テーブル)からの移行対象施設件数取得成功 移行対象施設件数={count}')

    try:
        elapsed_time = ElapsedTime()
        update_sql = """
            UPDATE
                src05.ult_ident_presc_lau uipl, internal05.v_inst_merge_t vimt
            SET
                uipl.ult_ident_cd = vimt.v_inst_cd_merge,
                uipl.lau_ope_dt = SYSDATE()
            WHERE
                uipl.ult_ident_cd = vimt.v_inst_cd
        """
        res = db.execute(update_sql)
        logging_sql(logger, update_sql)
        logger.info(f'納入先処方元マスタの納入先コードを施設コード移行先に更新成功, {res.rowcount} 行更新 ({elapsed_time.of})')
    except Exception as e:
        logger.debug("納入先処方元マスタの納入先コードを施設コード移行先に更新失敗")
        raise e

    return


def _update_ult_ident_presc_lau_from_inst_merge_t(db: Database):
    # inst_merge_tから、ult_ident_presc_lauをUpdate
    try:
        select_result = db.execute_select(
            """
            SELECT
                COUNT(dcf_dsf_inst_cd) AS row_count
            FROM
                internal05.inst_merge_t
            """
        )
    except Exception as e:
        logger.debug("施設統合マスタ(洗替処理一時テーブル)からの移行対象施設件数取得失敗")
        raise e

    count = [row for row in select_result][0]['row_count']
    if count == 0:
        logger.info('施設統合マスタ(洗替処理一時テーブル)からの移行対象施設が存在しません')
        return

    logger.info(f'施設統合マスタ(洗替処理一時テーブル)からの移行対象施設件数取得成功 移行対象施設件数={count}')
    # inst_merge_tから、ult_ident_presc_lauをUpdate
    try:
        elapsed_time = ElapsedTime()
        update_sql = """
            UPDATE
                src05.ult_ident_presc_lau uipl, internal05.inst_merge_t imt
            SET
                uipl.presc_cd = imt.dup_opp_cd,
                uipl.lau_ope_dt = SYSDATE()
            WHERE
                uipl.presc_cd = imt.dcf_dsf_inst_cd
        """
        res = db.execute(update_sql)
        logging_sql(logger, update_sql)
        logger.info(f'納入先処方元マスタの処方元コードを施設コード移行先に更新成功, {res.rowcount} 行更新 ({elapsed_time.of})')
    except Exception as e:
        logger.debug("納入先処方元マスタの処方元コードを施設コード移行先に更新失敗")
        raise e

    return
