# /user/bin/env python3
# -*- coding: utf-8 -*-
"""Report config class."""

import yaml

import logging
from docx.shared import RGBColor

from lc18report_dev.exceptions import WrongTableContentColumnCountError
from lc18report_dev.exceptions import NoneConfigedTableError, WrongConfigFormatError, WrongTableColumnCountError, WrongTableRowCountError

logger = logging.getLogger(__name__)


class Config:
    """Config class to provide config file parsing and related functions."""

    def __init__(self):
        """Config initialization.
        """
        self.colors: dict = {}
        self.tables = []
        self.data: dict = {}

    def load_config_file(self, config_file: str) -> None:
        with open(config_file, 'rt', encoding='utf-8') as cf:
            self.data = yaml.load(cf, Loader=yaml.FullLoader)
            # self.data['sample_info_file'] = self._try_match_info_file_prefix()

            if 'tables' in self.data.keys():
                for name, content in self.data['tables'].items():
                    table = {}
                    table['title'] = content['title']
                    table['columns'] = content['columns']
                    self.tables.append(table)

            for color, code in self.data['colors'].items():
                # rgbs = [hex(int(c.strip())) for c in code.split(';')]
                rgbs = [int(c.strip()) for c in code.split(';')]
                self.colors[color] = RGBColor(rgbs[0], rgbs[1], rgbs[2])
        self._check_genes()

    # def _try_match_info_file_prefix(self) -> str:
    #     sample_info_dir = os.path.dirname(self.data['sample_info_file'])
    #     sample_info_prefix = os.path.basename(
    #         self.data['sample_info_file'])
    #     if not os.path.isdir(sample_info_dir):
    #         return ''
    #     for file in os.listdir(sample_info_dir):
    #         if file.startswith(sample_info_prefix):
    #             return os.path.join(sample_info_dir, file)

    # def _check_sample_info_file_exist(self):
    #     s_info_file = self.data['sample_info_file']
    #     if not s_info_file.strip():
    #         return
    #     if not os.path.isfile(s_info_file):
    #         logger.error(f'Sample info file cannot be found at: {s_info_file}')
    #         raise InfoFileNotFoundError()

    # def _check_lab_info_file_exist(self):
    #     l_info_file = self.data['lab_info_file']
    #     if not l_info_file.strip():
    #         return
    #     if not os.path.isfile(l_info_file):
    #         logger.error(f'Lab info file cannot be found at: {l_info_file}')
    #         raise InfoFileNotFoundError()

    def get_color(self, color: str) -> RGBColor:
        """Get RGBColor object from color name.

        Args:
            color (str): color name

        Returns:
            RGBColor: RBGColor object of color name
        """
        rgb_color = self.colors[color]
        return rgb_color

    def check_table(self, table):
        """Validate table against report config.

        Args:
            table (Table): python-docx table object needed to be validated.

        Raises:
            WrongTableRowCountError: wrong table row count
            WrongTableColumnCountError: wrong table column count
            NoneConfigedTableError: table not matching any from config

        Returns:
            table_properties (dict): table properties.
        """
        table_title = table.cell(0, 0).text
        for config_table in self.tables:
            if not table_title.startswith(config_table['title']):
                continue
            actual_rows = len(table.rows)
            if actual_rows != 3:
                logger.error(
                    f'Wrong row number found for table: {table_title}\n'
                    f'Expecting 3 and found {actual_rows}')
                raise WrongTableRowCountError()
            expected_cols = len(config_table['columns'])
            actual_cols = len(table.columns)
            if expected_cols != actual_cols:
                logger.error(
                    f'Wrong column number found for table: {table_title}\n'
                    f'Expecting {expected_cols} and found {actual_cols}')
                raise WrongTableColumnCountError()
            properties = self._get_default_table_properties()
            if 'properties' in config_table.keys():
                properties.update(config_table['properties'])
            return config_table['properties']
        logger.error(f'Table \"{table_title}\" can\'t be found in config.')
        raise NoneConfigedTableError()

    def check_table_row_content(self, table, row_content):
        """Validate table row content.

        Args:
            table (Table): python-docx table object
            row_content (list): row content as a list in the order of table col

        Raises:
            WrongTableContentColumnCountError: mismatching content and table
                columns
        """
        table_columns = len(table.columns)
        content_columns = len(row_content)
        if table_columns != content_columns:
            raise WrongTableContentColumnCountError()

    # def has_info_file(self):
    #     try:
    #         self._check_sample_info_file_exist()
    #         self._check_lab_info_file_exist()
    #         return True
    #     except InfoFileNotFoundError:
    #         return False

    # def get_sample_info_file(self):
    #     self._check_sample_info_file_exist()
    #     return self.data['sample_info_file']

    # def get_lab_info_file(self):
    #     self._check_lab_info_file_exist()
    #     return self.data['lab_info_file']

    def _check_genes(self):
        if 'genes' not in self.data.keys():
            logger.error(f'Config file is missing genes part.')
            raise WrongConfigFormatError()

    @property
    def genes(self):
        return self.data['genes']

    @property
    def special_items(self):
        if 'special_items' not in self.data.keys():
            return ['tables', 'multi_tables']
        return self.data['special_items']

    @property
    def namespace(self):
        if 'namespace' not in self.data.keys():
            return r'{http://schemas.openxmlformats.org/wordprocessingml/2006/main}'
        return self.data['namespace']

    @staticmethod
    def _get_default_table_properties():
        table_properties = {
            'title_color': 'FEFFFE',
            'title_fill': '3A8EED',
            'cell_color': '000000',
            'cell_fill': 'DEEAF6',
            'cell_margin': '100',
        }
        return table_properties

    @property
    def multi_tables(self):
        return self.data['multi_tables']

    @property
    def gene_tables(self):
        try:
            return self.data['gene_tables']
        except Exception:
            return {}

    @property
    def med_tables(self):
        try:
            return self.data['med_tables']
        except Exception:
            return {}
