from typing import Optional
from fastapi import status
from fastapi.responses import JSONResponse

from api_validations.validations_request import (
    DepartmentsPydantic,
    PatchRecord,
    ListOptions,
    BaseModelRegular,
)

from databases import Departments

from api_events.events.abstract_class import MethodToEvent, ActionsSchema
from api_objects.auth.token_objects import EmployeeTokenObject
from ApiServices.api_handlers import AlchemyJsonResponse


class DepartmentListEventMethods(MethodToEvent):

    event_type = "SELECT"
    __event_keys__ = {
        "2cb90331-c1b4-4923-8314-8111326b621a": "department_list",
    }
    __event_validation__ = {"2cb90331-c1b4-4923-8314-8111326b621a": None}

    @classmethod
    def department_list(
        cls,
        list_options: ListOptions,
        token_dict: EmployeeTokenObject,
    ):
        Departments.filter_attr = list_options
        records = Departments.filter_all(
            Departments.company_id == token_dict.selected_company.company_id,
        )
        return AlchemyJsonResponse(
            completed=True,
            message="Departments are listed successfully",
            result=records,
        )


class AdminUserInsertDepartments(BaseModelRegular):
    department_code: str
    department_name: str
    company_uu_id: Optional[str] = None

    department_description: str
    parent_department_uu_id: Optional[int] = None


class DepartmentCreateEventMethods(MethodToEvent):

    event_type = "CREATE"
    __event_keys__ = {
        "d8bd3985-7f3b-4267-a74e-d5017e4ea9f8": "super_user_department_create",
    }
    __event_validation__ = {"d8bd3985-7f3b-4267-a74e-d5017e4ea9f8": DepartmentsPydantic}

    @classmethod
    def super_user_department_create(
        cls,
        data: DepartmentsPydantic,
        token_dict: EmployeeTokenObject,
    ):
        data_dict = data.excluded_dump()
        data_dict["company_id"] = token_dict.selected_company.company_id
        data_dict["company_uu_id"] = token_dict.selected_company.company_uu_id
        created_department = Departments.find_or_create(**data_dict)
        Departments.save()
        return JSONResponse(
            content={
                "completed": False,
                "message": "Company record already exits here is the record",
                "data": created_department.get_dict(),
            },
            status_code=status.HTTP_202_ACCEPTED,
        )


class DepartmentUpdateEventMethods(MethodToEvent):

    event_type = "UPDATE"
    __event_keys__ = {
        "4172706f-06c9-4c38-9ac8-59085a72f80a": "department_update",
    }
    __event_validation__ = {"4172706f-06c9-4c38-9ac8-59085a72f80a": DepartmentsPydantic}

    @classmethod
    def department_update(
        cls,
        company_uu_id: str,
        data: DepartmentsPydantic,
        token_dict: EmployeeTokenObject,
    ):
        find_one_company = Departments.filter_one(Departments.uu_id == company_uu_id)
        access_authorized_company = Departments.select_action(
            duty_id=getattr(token_dict, "duty_id", 5),
            filter_expr=[Departments.id == token_dict.get("")],
        )
        if access_authorized_company.count:
            data_dict = data.excluded_dump()
            updated_company = find_one_company.update(**data_dict)
            Departments.save()
            return JSONResponse(
                content={
                    "completed": True,
                    "message": "Update Company record",
                    "data": updated_company,
                },
                status_code=status.HTTP_200_OK,
            )
        return JSONResponse(
            content={"completed": True, "message": "Update Company record", "data": {}},
            status_code=status.HTTP_200_OK,
        )


class DepartmentPatchEventMethods(MethodToEvent):

    event_type = "PATCH"
    __event_keys__ = {
        "1e272e4f-6c1e-418b-91a7-be8b06c875da": "department_patch",
    }
    __event_validation__ = {"1e272e4f-6c1e-418b-91a7-be8b06c875da": None}

    @classmethod
    def department_patch(
        cls, company_uu_id: str, data: PatchRecord, token_dict: EmployeeTokenObject
    ):
        find_one_company = Departments.find_one_or_abort(uu_id=company_uu_id)
        access_authorized_company = Departments.select_action(
            duty_id=getattr(token_dict, "duty_id", 5),
            filter_expr=[Departments.id == find_one_company.id],
        )
        if access_authorized_company.count:
            action = data.excluded_dump()
            find_one_company.active = bool(
                action.get("active", find_one_company.active)
            )
            find_one_company.is_confirmed = bool(
                action.get("confirm", find_one_company.is_confirmed)
            )
            find_one_company.deleted = bool(
                action.get("delete", find_one_company.deleted)
            )
            find_one_company.save()
            return JSONResponse(
                content={
                    "completed": True,
                    "message": "Patch Company record completed",
                    "data": find_one_company.get_dict(),
                },
                status_code=status.HTTP_200_OK,
            )
        return JSONResponse(
            content={
                "completed": False,
                "message": "Patch Company record failed",
                "data": {},
            },
            status_code=status.HTTP_200_OK,
        )


DepartmentListEventMethod = DepartmentListEventMethods(
    action=ActionsSchema(endpoint="/department/list")
)
DepartmentCreateEventMethod = DepartmentCreateEventMethods(
    action=ActionsSchema(endpoint="/department/create")
)
DepartmentUpdateEventMethod = DepartmentUpdateEventMethods(
    action=ActionsSchema(endpoint="/department/update")
)
DepartmentPatchEventMethod = DepartmentPatchEventMethods(
    action=ActionsSchema(endpoint="/department/patch")
)
