from kontur_focus.req import Request
from dotenv import load_dotenv
import os
from datetime import datetime


class FocusCompliance(Request):
    _basedir = os.path.abspath(os.path.dirname(__file__))
    _focus_base_url = None
    check_models = [
        {
            'name': 'corporate',
            'description': 'Корпоративный сегмент', 
            'risk_model_id': 'a9457161-0454-448a-bc2c-83a89cd51b42'
        },
        {
            'name': '115-fz',
            'description': '115 ФЗ для некредитных финансовых организаций', 
            'risk_model_id': '887ee87c-3a43-48d7-a4ad-05c0a64ff53a'
        }
    ]

    def __init__(self, inn: str = None, ogrn: str = None):
        load_dotenv()
        super().__init__(
            base_url=os.environ.get('FOCUS_COMPLIANCE_BASE_URL'),
            api_key=os.environ.get('FOCUS_COMPLIANCE_ACCESS_KEY'),
            inn=inn,
            ogrn=ogrn
        )
        self._focus_base_url = f"/banks/{os.environ.get('FOCUS_COMPLIANCE_BANK_ID')}"
    
    def _save_file(self, filename: str, content, file_type: str = 'pdf', path: str = None) -> dict:
        current_datetime = datetime.now().strftime('%d-%m-%Y_%H-%M')
        f_name = f'{filename}_{self.inn}_{current_datetime}.{file_type}'
        
        if not path:
            file_path = os.path.join(self._basedir, f_name)
        else:
            file_path = os.path.join(path, f_name)
        
        try:
            with open(file_path, mode='wb') as file:
                file.write(content)

            return {'success': True, 'filename': f_name, 'path': file_path}
        except Exception as e:
            return {'success': False, 'message': e}
    
    # Компании
    def company_is_foreign_agent(self) -> dict:
        """Вхождение организации и ее руководителей в список иностранных агентов

        :return: Дата формирования реестра, а также признаки присутствия или отсутствия в списках иностранных агентов
        :rtype: dict
        """
        response = self.get(path=f'{self._focus_base_url}/companies/lists')
        foreign_agent_list = response['foreignAgentList']
        company_in_list = []
        persons_in_company_in_list = []
        
        for item in foreign_agent_list['uls']:
            if item['listItemStatus'] == 'NotInList':
                continue
            else:
                company_in_list.append(item)
        
        for person in foreign_agent_list['fls']:
            if person['listItemStatus'] == 'NotInList':
                continue
            else:
                persons_in_company_in_list.append(person)
        
        fal_data = {
            'list_date': str(foreign_agent_list['actualListDate']).split('T')[0],
            'company_in_list': True if company_in_list else False,
            'persons_in_company_in_list': True if persons_in_company_in_list else False
        }
        
        return fal_data
    
    def company_in_sanctions_lists(self) -> dict:
        """Вхождение организации и ее руководителей в санкционные списки с датами вхождения по типам санкций

        :return: Признак присутствия или отсутствия в санкционных списках:\n
                .. code-block:: python\n
                    {'company_in_list': False, \n
                    'persons_in_company_in_list': False, \n
                    'lists_dates': [{'type': 'Sema', 'date': '2025-12-15T00:00:00'}]}
        :rtype: dict
        """
        response = self.get(path=f'{self._focus_base_url}/companies/lists')
        sanctions_list = response['sanctionsList']
        lists_data = response['globalSanctionsList']['listDates']
        company_in_list = []
        persons_in_company_in_list = []
        
        for company in sanctions_list['uls']:
            if company['listItemStatus'] == 'NotInList':
                continue
            else:
                company_in_list.append(company)
        
        for person in sanctions_list['fls']:
            if person['listItemStatus'] == 'NotInList':
                continue
            else:
                persons_in_company_in_list.append(person)
        
        sanctions_lists_data = {
            'company_in_list': True if company_in_list else False,
            'persons_in_company_in_list': True if persons_in_company_in_list else False,
            'lists_data': lists_data
        }
        
        return sanctions_lists_data
    
    def search_global_company_profiles_id(self, company_name: str = None, search_accuracy: str = 'Max') -> list:
        """Поиск сводной информации по санкционным профилям ЮЛ

        :param company_name: Наименование компании
        :type company_name: str
        :param search_accuracy: Точность поиска
        :type search_accuracy: str
        :return: Список идентификаторов профилей
        :rtype: list
        """
        if self.inn:
            query = self.inn
        elif company_name:
            query = company_name
        else:
            return {'success': False, 'result': 'Не указан ИНН или наименование контрагента'}
        
        try:
            response = self.get(f'{self._focus_base_url}/companies/profiles/search', query=query, searchAccuracy=search_accuracy)
            profiles = response['legalEntityProfiles']
            
            if not profiles:
                return {'success': True, 'result': profiles}
            elif len(profiles) > 1:
                return {'success': True, 'result': [profile['id'] for profile in profiles]}
            else:
                return {'success': True, 'result': [profiles[0]['id']]}
        except KeyError:
            return {'success': False, 'result': 'Key Error'}
        except TypeError:
            return {'success': False, 'result': 'Type Error'}
    
    def full_legal_entity_sanctions_profile(self, profile_id_list: list) -> dict:
        """Просмотр полной информации определенного санкционного профиля ЮЛ

        :param profile_id_list: Идентификатор санкционного профиля ЮЛ. Идентификатор возвращается в методе 
                                «Поиск сводной информации по санкционным профилям ЮЛ» - 
                                GET /banks/{bankId}/companies/profiles/search
        :type profile_id_list: list
        :return: Полная информация по профилю ЮЛ
        :rtype: dict
        """
        if not profile_id_list:
            return {'success': False, 'message': 'Не указан список ID профилей'}
        else:
            try:
                profile = profile_id_list[0]
                response = self.get(path=f'{self._focus_base_url}/companies/profiles/{profile}')
                
                return {'success': True, 'result': response}
            except KeyError:
                return {'success': False, 'result': 'Ошибка в ID профиля.'}
    
    def legal_entity_profile_report(self, profile_id_list: list, path: str = None) -> dict:
        """Получение печатного отчета по профилю ЮЛ

        :param profile_id_list: Список идентификаторов санкционных профилей компании 
        :type profile_id_list: list
        :param path: Путь сохранения файла, по-умолчанию файл сохраняется в текущий каталог
        :type path: str, optional
        :return: Отчет о результате сохранения файла
        :rtype: dict
        """
        if not profile_id_list:
            return {'success': False, 'message': 'No profiles is specified'}
        elif len(profile_id_list) > 1:
            files = []
            
            for profile_id in profile_id_list:
                response = self.get(f'{self._focus_base_url}/companies/profiles/{profile_id}/report')
                result = self._save_file(
                    filename=f'Отчет_по_профилю_{profile_id_list[0]}_{profile_id}',
                    content=response.content,
                    file_type='docx',
                    path=path
                )
                files.append(result)
            
            return {'success': True, 'files': files}
        else:
            response = self.get(f'{self._focus_base_url}/companies/profiles/{profile_id_list[0]}/report')
            result = self._save_file(
                filename=f'Отчет_по_профилю_{profile_id_list[0]}',
                content=response.content,
                file_type='docx',
                path=path
            )
            
            return {'success': True, 'files': [result]}
    
    def full_company_report(self, model: str = '115-fz', path: str = None) -> dict:
        """Запрос на полную проверку и построение печатного отчёта по организации

        :param model: Идентификатор модели, по которой пройдет проверка. 
                    Идентификатор возвращается в методе «Получение списка рисковых моделей организации»
                    GET /banks/{bankId}/models, defaults to '115-fz'
        :type model: str, optional
        :param path: Путь сохранения файла, по-умолчанию файл сохраняется в текущий каталог, defaults to None
        :type path: str, optional
        :return: Отчет о результате сохранения файла
        :rtype: dict
        """
        if model == '115-fz':
            model_id = [d['risk_model_id'] for d in self.check_models if d['name'] == model][0]
        else:
            model_id = [d['risk_model_id'] for d in self.check_models if d['name'] == 'corporate'][0]
        
        response = self.get(f'{self._focus_base_url}/models/{model_id}/fullCompanyReport')

        try:
            result = self._save_file(
                    filename='Полный_отчет',
                    content=response.content,
                    file_type='docx',
                    path=path
            )
            if not result['success']:
                return {'success': False, 'result': result['message']}

            return {'success': True, 'file': result}
        except AttributeError:
            return {'success': False, 'result': 'Организация не найдена'}
    
    # Физлица
    def person_is_foreign_agent(self):
        """Вхождение физлица в список иностранных агентов

        :return: True или False
        :rtype: bool
        """
        response = self.get(path=f'{self._focus_base_url}/individuals')
        fa = response[0]['foreignAgents']
        
        return True if fa else False
    
    def search_global_person_profiles_id(self) -> list:
        """Поиск сводной информации по санкционным/ПДЛ профилям ФЛ

        :return: Список идентификаторов профилей
        :rtype: list
        """
        try:
            response = self.get(f'{self._focus_base_url}/individuals/profiles/search', query=self.inn)
            
            return response
        except KeyError:
            return None

    def full_individual_report(self, path: str = None, passport: str = None, fio: str = None) -> dict:
        """Запрос на построение печатного отчёта по физ лицу
           Необходимо обязательно указать либо ИНН, либо ФИО и номер паспорта

        :param path: Путь сохранения файла, по-умолчанию файл сохраняется в текущий каталог, defaults to None
        :type path: str, optional
        :param passport: Номер паспорты, defaults to None
        :type passport: str, optional
        :param fio: ФИО (хотя бы фамилия и имя), defaults to None
        :type fio: str, optional
        :return: Отчет о результате сохранения файла
        :rtype: dict
        """
        if self.inn:
            response = self.get(path=f'{self._focus_base_url}/formFullIndividualReport')
        elif not self.inn and passport and fio:
            response = self.get(path=f'{self._focus_base_url}/formFullIndividualReport', passportNumber=passport, fio=fio)
        else:
            return {'success': False, 'result': 'Необходимо указать: либо ИНН, либо ФИО (хотя бы фамилию и имя) и паспорт'}
        
        try:
            if response.status_code == 200:
                result = self._save_file(
                        filename='Полный_отчет',
                        content=response.content,
                        file_type='docx',
                        path=path
                )
            
                return {'success': True, 'file': result}
            else:
                return {'success': False, 'result': 'Ошибка получения отчета. Проверьте корректность ИНН, ФИО или паспортных данных.'}
        except AttributeError:
            return {'success': False, 'result': 'Ошибка получения отчета. Проверьте корректность ИНН, ФИО или паспортных данных.'}
    
    # Иноагенты
    def get_foreign_agents_list(self, fa_type: str = None) -> list:  # Не работает, если нет подключенной лицензии
        """Получение списка иноагентов

        :param fa_type: Тип иноагента (i - физ. лица, l - юридические лица), если не указано, выгружаются все типы, defaults to None
        :type fa_type: str, optional
        :return: Список данных по иноагентам
        :rtype: list
        """
        response = self.get(path=f'{self._focus_base_url}/foreign-agents')
        result = None
        
        if fa_type == 'i':
            individuals = response['individuals']
            result = individuals
        elif fa_type == 'l':
            legal_entities = response['legalEntities']
            result = legal_entities
        else:
            result = [response]
        
        return result
