"""
Project:    PARTS Website
Author:     Edward Middleton-Smith
            Precision And Research Technology Systems Limited

Technology: Business Objects
Feature:    SQL Error Business Object

Description:
Business object for SQL errors returned by Get Many Stored Procedures
"""

# internal
from business_objects.base import Base
from business_objects.db_base import SQLAlchemy_ABC, Get_Many_Parameters_Base
from extensions import db
from helpers.helper_app import Helper_App
import lib.argument_validation as av
from lib import data_types
# external
from enum import Enum
from datetime import datetime, timedelta
import locale
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import Uuid
from typing import ClassVar

# db = SQLAlchemy()


class SQL_Error(SQLAlchemy_ABC, Base):
    ATTR_ERROR_ID: ClassVar[str] = 'error_id'
    FLAG_IS_BREAKING_ERROR: ClassVar[str] = 'is_breaking_error'

    __tablename__ = 'error'
    __table_args__ = { 'extend_existing': True }

    error_id = db.Column(db.Integer, primary_key=True)
    guid = db.Column(Uuid)
    id_type = db.Column(db.Integer)
    code_type = db.Column(db.Text)
    name_type = db.Column(db.Text)
    msg = db.Column(db.Text)
    display_order = db.Column(db.Integer)
    active = db.Column(db.Boolean)

    
    def __init__(self):
        self.error_id = 0
        super().__init__()
        
    @classmethod
    def from_db_error(cls, record):
        _m = f'{cls.__qualname__}.from_db_error'
        # Helper_App.console_log(_m)
        # Helper_App.console_log(f'record: {record}')
        error = cls()
        error.error_id = record[0]
        error.guid = record[1]
        error.id_type = record[2]
        error.code_type = record[3]
        error.name_type = record[4]
        error.msg = record[5]
        error.display_order = record[6]
        error.active = av.input_bool(record[7], "active", _m)
        return error

    @classmethod
    def from_exception(cls, exception: Exception, is_breaking: bool = True):
        _m = f'{cls.__qualname__}.from_exception'
        # Helper_App.console_log(_m)
        error = cls()
        error.error_id = -1
        error.id_type = -1
        error.code_type = type(exception).__name__
        error.name_type = type(exception).__name__
        error.msg = str(exception)
        # Helper_App.console_log(f'Error: {error}')
        return error

    @classmethod
    def from_json(cls, json):
        _m = f'{cls.__qualname__}.from_json'
        error = cls()
        if json is None: return error
        """
        # Helper_App.console_log(f'{_m}\njson: {json}')
        error.error_id = json.get(cls.ATTR_ERROR_ID, -1)
        error.id_type = json.get()
        error.name = json[cls.FLAG_NAME]
        error.code = json.get(cls.FLAG_CODE, error.name.upper().replace(" ", "_"))
        error.active = av.input_bool(json[cls.FLAG_ACTIVE], cls.FLAG_ACTIVE, _m)
        # Helper_App.console_log(f'Error: {error}')
        return error
        """
    
    def to_json(self):
        return {
              self.ATTR_ERROR_ID: self.error_id
            , Base.FLAG_GUID: self.guid
            , Base.ATTR_ID_MSG_ERROR_TYPE: self.id_type
            , Base.FLAG_CODE: self.code_type
            , Base.FLAG_NAME: self.name_type
            , Base.FLAG_MESSAGE: self.msg
            , Base.FLAG_DISPLAY_ORDER: self.display_order
            , Base.FLAG_ACTIVE: self.active
        }

    def __repr__(self):
        # Helper_App.console_log(f'{cls.__qualname__}.__repr__')
        return f'''
{self.__class__.__name__}(
    {self.ATTR_ERROR_ID}: {self.error_id}
    {Base.ATTR_ID_MSG_ERROR_TYPE}: {self.id_type}
    {Base.FLAG_CODE}: {self.code_type}
    {Base.FLAG_NAME}: {self.name_type}
    {Base.FLAG_MESSAGE}: {self.msg}
    {Base.FLAG_DISPLAY_ORDER}: {self.display_order}
    {Base.FLAG_ACTIVE}: {self.active}
)
            '''
    
class Parameters_SQL_Error(Get_Many_Parameters_Base):
    guid: str  # UUID stored as string for Pydantic compatibility

    @classmethod
    def get_default(cls, guid):
        return cls(
            guid = guid
        )

    @classmethod
    def from_json(cls, json):
        return cls(
            guid = json.get('a_guid', None)
        )

    def to_json(self):
        return {
            'a_guid': self.guid
        }

    @staticmethod
    def get_type_hints():
        return {
            'a_guid': Uuid
        }