from src.batch.ultmarc.utmp_tables.table_mapper.ultmarc_table_mapper import (
    UltmarcTableMapper,
)
from src.batch.ultmarc.utmp_tables.tables.com_prefc_med_sp_outpat import (
    ComPrefcMedSpOutpat,
)


class ComPrefcMedSpOutpatMapper(UltmarcTableMapper):
    """レイアウト区分136: COM_都道府県医療機能情報(専門外来)"""

    # レコード存在確認SQL
    RECORD_EXISTS_QUERY = """\
    SELECT
        COUNT(*) AS count_num
    FROM
        src05.com_prefc_med_sp_outpat
    WHERE
        dcf_dsf_inst_cd = :dcfdsf_inst_code
        AND
        specialclinic_name = :specialclinic_name
    """
    # データ登録用SQL
    INSERT_QUERY = """\
    INSERT INTO src05.com_prefc_med_sp_outpat
    (
        dcf_dsf_inst_cd,
        specialclinic_name,
        sort_key,
        sectsub_cd,
        regist_ymd,
        sys_regist_date,
        regist_prgm_id,
        sys_update_date,
        update_prgm_id
    )
    VALUES (
        :dcfdsf_inst_code,
        :specialclinic_name,
        :sort_key,
        :sectsub_cd,
        :execute_date_str_ymd,
        :execute_datetime,
        :program_name,
        :execute_datetime,
        :program_name
    )
    """

    # データ変更用SQL
    UPDATE_QUERY = """\
        UPDATE
            src05.com_prefc_med_sp_outpat
        SET
            {update_columns}
            update_ymd = :execute_date_str_ymd,
            sys_update_date = :execute_datetime,
            update_prgm_id = :program_name
        WHERE
            dcf_dsf_inst_cd = :dcfdsf_inst_code
            AND
            specialclinic_name = :specialclinic_name
        """

    # 『修正区分がB(修正)かつ追加削除区分が1(退職)』の場合、物理削除
    PHYSICAL_DELETE_QUERY = """\
        DELETE FROM
            src05.com_prefc_med_sp_outpat
        WHERE
            dcf_dsf_inst_cd = :dcfdsf_inst_code
            AND
            specialclinic_name = :specialclinic_name
        """

    record: ComPrefcMedSpOutpat

    def __init__(self, record: list[str], db) -> None:
        super().__init__(record, db, ComPrefcMedSpOutpat)
        program_name = __name__.split(".")[-1]  # 当モジュール名(現行から変わっている)
        # モジュール名をクエリパラメータに設定
        self.query_parameter["program_name"] = program_name
        # 読み込んだレコード値もクエリパラメータに追加
        self.query_parameter = {
            **self.query_parameter,
            **self.record.to_sql_parameter(),
        }

    def make_query(self):
        # 『修正区分がB(修正)かつ追加削除区分が1(退職)』の場合、物理削除
        if self.record.maint_flag == "B" and self.record.adddel_div == "1":
            self.queries.append(self.PHYSICAL_DELETE_QUERY)
            return

        # 追加、更新の場合
        self.queries.append(self.__make_upsert_query())
        return

    def __make_upsert_query(self):
        # 修正のレコードだった場合はNULLに変換する
        if self.record.sectsub_cd == "@":
            self.query_parameter["sectsub_cd"] = None

        # レコードの存在確認
        record_count = self.db.execute_select(
            self.RECORD_EXISTS_QUERY, self.query_parameter
        )
        # 存在しない場合はInsert
        if record_count[0]["count_num"] == 0:
            return self.INSERT_QUERY

        # 存在する場合ではUpdate
        return self.__make_update_query()

    def __make_update_query(self):
        set_clauses = []  # 設定項目

        # ｿｰﾄｷｰ
        if len(self.record.sort_key) > 0:
            set_clauses.append("sort_key = :sort_key")

        # 分類補助ｺｰﾄﾞ
        if len(self.record.sectsub_cd) > 0:
            set_clauses.append("sectsub_cd = :sectsub_cd")

        update_columns = ",".join(set_clauses)
        # 何も更新項目が無い場合はNoneとする（更新処理は行わない）
        if len(update_columns) == 0:
            return None
        else:
            # 末尾にカンマを付けてSET句を完成させる
            update_columns += ","
            update_query = self.UPDATE_QUERY.format(update_columns=update_columns)
            return update_query
