from typing import List, Optional

from sqlalchemy.orm import Session

from app.core.entities.delivery_accessory import DeliveryAccessoryEntity
from app.infrastructure.database.models.delivery_accessories import DeliveryAccessory
from app.infrastructure.database.repository.delivery_accessory_repository import DeliveryAccessoriesRepository


class DeliveryAccessoriesService:
    def __init__(self, db: Session):
        self.repository = DeliveryAccessoriesRepository(db)

    def get_all_delivery_accessories(self) -> List[DeliveryAccessoryEntity]:
        delivery_accessories = self.repository.get_all()
        return [
            DeliveryAccessoryEntity(
                id=da.id,
                queue=da.queue,
                accessory_id=da.accessory_id,
                delivery_order_id=da.delivery_order_id
            )
            for da in delivery_accessories
        ]

    def get_all_delivery_accessories_by_order(self, delivery_order_id):
        delivery_accessories = self.repository.get_all_by_order_id(delivery_order_id)
        return [
            DeliveryAccessoryEntity(
                id=da.id,
                queue=da.queue,
                accessory_volume=da.accessory.volume,
                accessory_weight=da.accessory.weight,
                accessory_period=da.accessory.period,
                accessory_id=da.accessory_id,
                delivery_order_id=da.delivery_order_id,
                accessory_name=da.accessory.name,
                city_name=da.accessory.city.name,
                city_x=da.accessory.city.x_coordinate,
                city_y=da.accessory.city.y_coordinate,
            )
            for da in delivery_accessories
        ]

    def get_delivery_accessory_by_id(self, delivery_accessory_id: int) -> Optional[DeliveryAccessoryEntity]:
        delivery_accessory = self.repository.get_by_id(delivery_accessory_id)
        if delivery_accessory:
            return DeliveryAccessoryEntity(
                id=delivery_accessory.id,
                queue=delivery_accessory.queue,
                accessory_id=delivery_accessory.accessory_id,
                delivery_order_id=delivery_accessory.delivery_order_id
            )
        return None

    def create_delivery_accessory(self, entity: DeliveryAccessoryEntity) -> DeliveryAccessoryEntity:
        delivery_accessory_model = DeliveryAccessory(
            queue=entity.queue,
            count=entity.count,
            accessory_id=entity.accessory_id,
            delivery_order_id=entity.delivery_order_id
        )
        created_delivery_accessory = self.repository.create(delivery_accessory_model)
        return DeliveryAccessoryEntity(
            id=created_delivery_accessory.id,
            queue=created_delivery_accessory.queue,
            accessory_id=created_delivery_accessory.accessory_id,
            delivery_order_id=created_delivery_accessory.delivery_order_id
        )

    def update_delivery_accessory(self, delivery_accessory_id: int, entity: DeliveryAccessoryEntity) -> Optional[
        DeliveryAccessoryEntity]:
        delivery_accessory_model = self.repository.get_by_id(delivery_accessory_id)
        if delivery_accessory_model:
            delivery_accessory_model.queue = entity.queue
            delivery_accessory_model.count = entity.count
            delivery_accessory_model.accessory_id = entity.accessory_id
            delivery_accessory_model.delivery_order_id = entity.delivery_order_id
            self.repository.update(delivery_accessory_model)
            return DeliveryAccessoryEntity(
                id=delivery_accessory_model.id,
                queue=delivery_accessory_model.queue,
                accessory_id=delivery_accessory_model.accessory_id,
                delivery_order_id=delivery_accessory_model.delivery_order_id
            )
        return None

    def delete_delivery_accessory(self, delivery_accessory_id: int) -> bool:
        return self.repository.delete(delivery_accessory_id) is not None
