from abc import ABCMeta, abstractmethod
from src.repositories.emp_chg_inst_repository import EmpChgInstRepository
from src.logging.get_logger import get_logger

logger = get_logger('マスターメンテ')


class MasterMainteEmpChgInstFunction(metaclass=ABCMeta):
    insert_data: list[dict]
    table_name: str
    select_table_message: str
    user_name: str
    emp_chginst_repository: EmpChgInstRepository

    def __init__(
        self,
        insert_data,
        table_name: str,
        select_table_message: str,
        user_name: str,
        emp_chginst_repository: EmpChgInstRepository
    ):
        self.insert_data = insert_data
        self.table_name = table_name
        self.select_table_message = select_table_message
        self.user_name = user_name
        self.emp_chginst_repository = emp_chginst_repository

    def save(self):
        error_list = []
        try:
            self.emp_chginst_repository.begin()
            self.emp_chginst_repository.to_jst()
            (result_message, error_list) = self.write_emp_chg_inst_table()
            if len(error_list) > 0:
                self.emp_chginst_repository.rollback()
            else:
                self.emp_chginst_repository.commit()
        except Exception as e:
            self.emp_chginst_repository.rollback()
            raise e

        return (result_message, error_list)

    def add_emp_chg_inst_table(self, data, start_date, end_date):
        self.emp_chginst_repository.insert_emp_chg_inst(
            data['施設コード'],
            data['領域コード'],
            data['担当者種別コード'],
            data['MUID'],
            data['ビジネスユニットコード'],
            start_date,
            end_date,
            self.user_name,
            self.table_name)

    @abstractmethod
    def write_emp_chg_inst_table(self):
        pass


class NewEmpChgInstFunction(MasterMainteEmpChgInstFunction):

    def __init__(
        self,
        insert_data_list: list[dict],
        table_name: str,
        select_table_message: str,
        user_name: str,
        emp_chginst_repository: EmpChgInstRepository
    ):
        super().__init__(
            insert_data_list,
            table_name,
            select_table_message,
            user_name,
            emp_chginst_repository
        )

    def write_emp_chg_inst_table(self):
        error_list = []

        add_count = 0
        for row_no, data in enumerate(self.insert_data, start=1):
            try:
                self.add_emp_chg_inst_table(data, data['適用開始日'], data['適用終了日'])
                add_count += 1
            except Exception as e:
                error_list.append(f'{str(row_no)}行目がSQL実行エラーです。CSVファイルを確認してください。')
                logger.info(f'新規施設登録時に{row_no}行目でエラーが発生しました: {e}')

        result_message_list = []
        if len(error_list) == 0:
            result_message_list.append('新規施設登録を行いました')
            result_message_list.append('対象：' + self.select_table_message)
            result_message_list.append('追加：' + str(add_count) + '件')
        return (result_message_list, error_list)


class ChangeEmpChgInstFunction(MasterMainteEmpChgInstFunction):

    def __init__(
        self,
        insert_data: list[dict],
        table_name: str,
        select_table_message: str,
        user_name: str,
        emp_chginst_repository: EmpChgInstRepository

    ):
        super().__init__(
            insert_data,
            table_name,
            select_table_message,
            user_name,
            emp_chginst_repository
        )

    def write_emp_chg_inst_table(self):
        add_count = 0
        end_count = 0
        modify_count = 0
        error_list = []
        for row_no, data in enumerate(self.insert_data, start=1):
            try:
                if data['コメント'] == '追加':
                    self.add_emp_chg_inst_table(data, data['施設担当_開始日'], data['施設担当_終了日'])
                    add_count += 1
                elif data['コメント'] == '終了':
                    self.__end_emp_chg_inst(data)
                    end_count += 1
                elif data['コメント'] == '担当者修正':
                    self.__modify_emp_chg_inst(data)
                    modify_count += 1
            except Exception as e:
                error_list.append(f'{str(row_no)}行目がSQL実行エラーです。CSVファイルを確認してください。')
                logger.info(f'施設担当者変更時に{row_no}行目でエラーが発生しました: {e}')

        result_message_list = []
        if len(error_list) == 0:
            result_message_list.append('施設担当者変更を行いました')
            result_message_list.append('対象：' + self.select_table_message)
            result_message_list.append('追加：' + str(add_count) + '件')
            result_message_list.append('修正：' + str(modify_count) + '件')
            result_message_list.append('終了：' + str(end_count) + '件')
        return (result_message_list, error_list)

    def __end_emp_chg_inst(self, data: dict):
        self.emp_chginst_repository.end_emp_chg_inst(
            data['施設コード'],
            data['領域コード'],
            data['担当者種別コード'],
            data['施設担当_開始日'],
            data['終了日の変更'],
            self.user_name,
            self.table_name)

    def __modify_emp_chg_inst(self, data: dict):
        self.emp_chginst_repository.modify_emp_chg_inst(
            data['施設コード'],
            data['領域コード'],
            data['施設担当_開始日'],
            data['担当者種別コード'],
            data['MUID'],
            self.user_name,
            self.table_name)
