from ..base import BaseView, BaseViewException
from median.models import Magasin, Poste, Espace, Adresse
from median.constant import EcoType
from median.generator import ASTUS_CONFIG
from median.utils import padding_address, get_counter


class GeneratorView(BaseView):

    warehouse_code: str = None
    warehouse: Magasin = None
    poste: Poste = None

    def __init__(self, warehouse: str = None, ecotype: str = None):
        if warehouse is None:
            raise BaseViewException("Warehouse code is required !")
        self.warehouse_code = warehouse
        self.warehouse = Magasin.get_or_none(mag=warehouse)

    def astus_add_xl(self, poste: str, label: str, robot: str = 0, zone: str = 0):
        self._check_prerequisites()
        self.astus_generate_equipment(poste, label, robot, zone, "XL")
        self.astus_generate_address("XL")

    def astus_add_v6(self, poste: str, label: str, robot: str = 0, zone: str = 0):
        self._check_prerequisites()
        self.astus_generate_equipment(poste, label, robot, zone, "V6")
        self.astus_generate_address("V6")

    def astus_add_v7(self, poste: str, label: str, robot: str = 0, zone: str = 0):
        self._check_prerequisites()
        self.astus_generate_equipment(poste, label, robot, zone, "V7")
        self.astus_generate_address("V7")

    def astus_add_v8(self, poste: str, label: str, robot: str = 0, zone: str = 0):
        self._check_prerequisites()
        self.astus_generate_equipment(poste, label, robot, zone, "V8")
        self.astus_generate_address("V8")

    def astus_add_v9(self, poste: str, label: str, robot: str = 0, zone: str = 0):
        self._check_prerequisites()
        self.astus_generate_equipment(poste, label, robot, zone, "V9")
        self.astus_generate_address("V9")

    def astus_add_v10(self, poste: str, label: str, robot: str = 0, zone: str = 0):
        self._check_prerequisites()
        self.astus_generate_equipment(poste, label, robot, zone, "V10")
        self.astus_generate_address("V10")

    def astus_add_v11(self, poste: str, label: str, robot: str = 0, zone: str = 0):
        self._check_prerequisites()
        self.astus_generate_equipment(poste, label, robot, zone, "V11")
        self.astus_generate_address("V11")

    def _check_prerequisites(self):
        if self.warehouse is not None:
            raise BaseViewException(f"Warehouse {self.warehouse.mag} exist !")

    def astus_generate_equipment(self, poste: str, label: str, robot: str = 0, zone: str = 0, config_type: str = ""):
        cfg = ASTUS_CONFIG[config_type]
        Poste.create(
            poste=poste,
            proc_pid=0
        )
        self.warehouse = Magasin.create(
            mag=self.warehouse_code, type_mag=poste,
            eco_type=EcoType.Astus.value, nb_dim=4,
            lib_2="LIGNE", dim_2=cfg["rows"],
            lib_3="COLONNE", dim_3=cfg["cols"],
            lib_4="PROFONDEUR", dim_4=cfg["depths"],
            lib_5="STUPEFIANT", dim_5=0,
            type_machine="ASTUS_V3", libelle=label,
            id_robot=robot, id_zone=zone
        )
        Espace.get_or_create(poste=poste, mag=self.warehouse_code, defaults={
            'alloc': 1,
            'service': 1,
            'gest': 'gest_trad',
            'sub_gest': 'a',
            'pos_aff': 0,
        })

    def astus_generate_address(self, config_type: str):

        cfg = ASTUS_CONFIG[config_type]
        nb_col = cfg["cols"]
        nb_row = cfg["rows"]
        depth = cfg["depths"]
        prefix_tray = cfg["prefix_tray"]

        offset = ord('A')
        if len(cfg['col_types']) != nb_col:
            raise BaseViewException(f"Number of colums: {nb_col} does not match to columns types")  # pragma: no cover
        if len(cfg['row_types']) != nb_row:
            raise BaseViewException(f"Number of rows: {nb_row} does not match to rows types")  # pragma: no cover

        for row in range(nb_row):
            tray_bin = f'{prefix_tray} 1/3 B'
            for column in range(nb_col):
                if column >= 2:
                    tray_bin = f'{prefix_tray} 1/3 H'

                if (row, column) in cfg["blacklist"]:
                    continue

                tray_bin = '%s %s %s' % (prefix_tray, cfg['col_types'][column], cfg['row_types'][row])
                for prof in range(depth):
                    address = '%s.%s.%s.%s' % (
                        self.warehouse_code, str(chr(offset + row)), str(column + 1), str(prof + 1))
                    adr, _ = Adresse.get_or_create(adresse=padding_address(address), defaults={
                        'etat': 'L',
                        'format': tray_bin,
                        'magasin': self.warehouse_code,
                        'contenant': str(get_counter("CONTENANT_PASS")).zfill(8),
                        'emplacement': "",
                        'quantite_posage': 0,
                    })
