"""This module holds the style export of the ``import_export`` app."""

import os

from django.conf import settings

from openpyxl.cell import get_column_letter
from openpyxl.styles import Alignment, Border, Font, PatternFill, Protection, Side, Style

from mtp.apps.themes.models import Theme


class StyleXlsx:

    PASSWORD_PROTECT = 'magency'
    CELL_LOGO = 'P5'
    DEFAULT_LOGO = os.path.join(settings.STATIC_ROOT, 'trainings/images/logo.png')

    CELL_TITLE = 'B2'
    CELL_SUBTITLE = 'B4'
    CELL_INFO = 'P2'

    COLUMN_MAX_WIDTH = 40
    ESCAPE_RATIO = 1.25
    WIDTH_MARGIN = 5

    TOP_OFFSET = 4
    RIGHT_OFFSET = 50
    BOTTOM_OFFSET = 50
    LEFT_OFFSET = 1

    PRIMARY_COLOR = '8f0682'
    SECONDARY_COLOR = '650075'
    TERTIARY_COLOR = '9058a5'
    QUATERNARY_COLOR = 'cba4cf'
    BACKGROUND_COLOR = 'd8d9d1'

    BORDER_COLOR = 'a6a6a6'

    BLACK = '3f4036'
    WHITE = 'FFFFFF'
    RED = 'DA4453'
    GREEN = '8CC152'

    MEDIUM = 'medium'
    SOLID = 'solid'
    HAIR = 'hair'

    SIZE = 13

    RED_FONT = Font(size=SIZE, color=RED)
    GREEN_FONT = Font(size=SIZE, color=GREEN)

    STYLES = {}

    def __init__(self):
        try:
            current_theme = Theme.objects.get(default=True)
        except Theme.MultipleObjectsReturned:
            current_theme = Theme.objects.filter(default=True).first()
        except Theme.DoesNotExist:
            current_theme = Theme.objects.first()  # Return None if no theme exists

        if current_theme:
            self.PRIMARY_COLOR = current_theme.main[1:]
            self.BACKGROUND_COLOR = current_theme.gray_lighter[1:]

        self.STYLES = {
            'HEADER_LINE': Style(
                fill=PatternFill(fill_type=self.SOLID, start_color=self.PRIMARY_COLOR)
            ),
            'HEADER_TITLE': Style(
                fill=PatternFill(fill_type=self.SOLID, start_color=self.BLACK),
                font=Font(size=22, color=self.WHITE),
                alignment=Alignment(vertical='center')
            ),
            'DEFAULT': Style(
                font=Font(size=self.SIZE, color=self.BLACK),
                fill=PatternFill(fill_type=self.SOLID, start_color=self.BACKGROUND_COLOR),
                alignment=Alignment(horizontal='left', vertical='top', wrap_text=True),
            ),
            'DEFAULT_NO_PROTECTED': Style(
                font=Font(size=self.SIZE, color=self.BLACK),
                fill=PatternFill(fill_type=self.SOLID, start_color=self.BACKGROUND_COLOR),
                alignment=Alignment(horizontal='left', vertical='top', wrap_text=True),
                protection=Protection(locked=False)
            ),
            'HEADER_INFO': Style(
                font=Font(size=self.SIZE, bold=True),
                fill=PatternFill(fill_type=self.SOLID, start_color=self.BACKGROUND_COLOR),
                alignment=Alignment(wrap_text=True, horizontal='right')
            ),
            'HEADER_TABLE': Style(
                font=Font(size=self.SIZE, color=self.PRIMARY_COLOR),
                fill=PatternFill(fill_type=self.SOLID, start_color=self.BACKGROUND_COLOR),
                border=Border(
                    bottom=Side(border_style='thin', color=self.BORDER_COLOR),
                ),
                alignment=Alignment(horizontal='left')
            ),
            'DEFAULT_TABLE': Style(
                font=Font(size=self.SIZE, color=self.BLACK),
                fill=PatternFill(fill_type=self.SOLID, start_color=self.BACKGROUND_COLOR),
                border=Border(
                    bottom=Side(border_style='thin', color=self.BORDER_COLOR),
                ),
                alignment=Alignment(horizontal='left', vertical='top', wrap_text=True),
                protection=Protection(locked=False)
            ),
            'EDITABLE_DEFAULT_TABLE': Style(
                font=Font(size=self.SIZE, color=self.BLACK),
                fill=PatternFill(fill_type=self.SOLID, start_color=self.WHITE),
                border=Border(
                    bottom=Side(border_style='thin', color=self.BORDER_COLOR),
                ),
                alignment=Alignment(horizontal='left', vertical='top', wrap_text=True),
                protection=Protection(locked=False)
            ),
            'PROTECTED_DEFAULT_TABLE': Style(
                font=Font(size=self.SIZE, color=self.BLACK),
                fill=PatternFill(fill_type=self.SOLID, start_color=self.BACKGROUND_COLOR),
                border=Border(
                    bottom=Side(border_style='thin', color=self.BORDER_COLOR),
                ),
                alignment=Alignment(horizontal='left', vertical='top', wrap_text=True)
            ),
            'GREEN_PROTECTED_DEFAULT_TABLE': Style(
                font=Font(size=self.SIZE, color=self.BLACK),
                fill=PatternFill(fill_type=self.SOLID, start_color=self.GREEN),
                border=Border(
                    bottom=Side(border_style='thin', color=self.BORDER_COLOR),
                ),
                alignment=Alignment(horizontal='left', vertical='top', wrap_text=True)
            ),
            'DETAIL': Style(
                font=Font(size=18, color=self.BLACK),
                fill=PatternFill(fill_type=self.SOLID, start_color=self.BACKGROUND_COLOR),
                alignment=Alignment(horizontal='left'),
                protection=Protection(locked=False)
            )
        }

    def apply_style(self, sheet):
        """ Apply style on sheet.
        We apply style on cell with values more 50 lines of margin.

        Parameters
        ----------
        sheet : openpyxl.Worksheet
            Sheet will be stylized.
        """
        row_nb_max = sheet.max_row + self.BOTTOM_OFFSET
        column_nb_max = sheet.max_column + self.RIGHT_OFFSET

        for row_nb in range(1, row_nb_max):
            for column_nb in range(1, column_nb_max):
                if row_nb == 1:
                    sheet.cell(row=1, column=column_nb).style = self.STYLES['HEADER_LINE']
                elif row_nb == 2:
                    sheet.cell(row=2, column=column_nb).style = self.STYLES['HEADER_TITLE']
                elif row_nb >= sheet.max_row:
                    cell = sheet.cell(row=row_nb, column=column_nb)
                    cell.style = self.STYLES['DEFAULT_NO_PROTECTED']
                else:
                    cell = sheet.cell(row=row_nb, column=column_nb)
                    if not cell.value:
                        cell.style = self.STYLES['DEFAULT']

    def dimension_sheet(self, sheet):
        """ Set row dimension in sheet.

        Parameters
        ----------
        sheet : openpyxl.Worksheet
            Sheet will be modified.
        """
        sheet.column_dimensions[get_column_letter(1)].width = 5  # Margin-Left
        sheet.row_dimensions[1].height = 5  # HEADER_LINE
        sheet.row_dimensions[2].height = 40  # HEADER_TITLE

    def protect_sheet(self, sheet):
        """ Protect a sheet.
        We protect locked cells so that they are impossible to change. Like headers and title.

        Parameters
        ----------
        sheet : openpyxl.Worksheet
            Sheet will be protected.
        """
        sheet.protection.formatColumns = False
        sheet.protection.formatRows = False
        sheet.protection.formatCells = False
        sheet.protection.set_password(self.PASSWORD_PROTECT)
        sheet.protection.enable()

    def hide_columns(self, sheet, index_list):
        """ Hide some columns in sheet.
        We use index of column to hide them.

        Parameters
        ----------
        sheet : openpyxl.Worksheet
            Sheet will be stylized.
        index_list : list, tuple
            List of column index to hide.
        """
        for index in index_list:
            index += self.LEFT_OFFSET
            sheet.column_dimensions[get_column_letter(index)].hidden = True
