from framefox.core.controller.abstract_controller import AbstractController
from framefox.core.routing.decorator.route import Route
from typing import Dict
from src.repository.{{ repository_file_name }} import {{ repository_class_name }}
from src.entity.{{ entity_file_name }} import {{ entity_class_name }}
from framefox.core.orm.entity_manager_interface import EntityManagerInterface


class {{ controller_class_name }}(AbstractController):
    def __init__(self, entityManager: EntityManagerInterface):
        self.entity_manager = entityManager
        self.repository = {{ repository_class_name }}()

    @Route("/{{ entity_name }}s", "{{ entity_file_name }}.index", methods=["GET"])
    async def index(self):
        """GET /{{ entity_name }}s - Retrieve all {{ entity_name }} resources"""
        try:
            items = self.repository.find_all()
            return self.json({
                "{{ entity_name }}s": [item.dict() for item in items],
                "total": len(items),
                "status": "success"
            }, status=200)
        except Exception as e:
            return self.json({
                "error": "Failed to retrieve {{ entity_name }}s",
                "message": str(e),
                "status": "error"
            }, status=500)

    @Route("/{{ entity_name }}s/{id}", "{{ entity_file_name }}.show", methods=["GET"])
    async def show(self, id: int):
        """GET /{{ entity_name }}s/{id} - Retrieve a specific {{ entity_name }} resource"""
        try:
            item = self.repository.find(id)
            if not item:
                return self.json({
                    "error": "{{ entity_class_name }} not found",
                    "status": "not_found"
                }, status=404)

            return self.json({
                "{{ entity_name }}": item.dict(),
                "status": "success"
            }, status=200)
        except Exception as e:
            return self.json({
                "error": "Failed to retrieve {{ entity_name }}",
                "message": str(e),
                "status": "error"
            }, status=500)

    @Route("/{{ entity_name }}s", "{{ entity_file_name }}.create", methods=["POST"])
    async def create(self, data: {{ entity_class_name }}.generate_create_model()):
        """POST /{{ entity_name }}s - Create a new {{ entity_name }} resource"""
        try:
            {{ entity_name }} = self.repository.model(**data.dict())
            self.entity_manager.persist({{ entity_name }})
            self.entity_manager.commit()

            self.entity_manager.refresh({{ entity_name }})

            return self.json({
                "{{ entity_name }}": {{ entity_name }}.dict(),
                "message": "{{ entity_class_name }} created successfully",
                "status": "created"
            }, status=201)
        except Exception as e:
            return self.json({
                "error": "Failed to create {{ entity_name }}",
                "message": str(e),
                "status": "error"
            }, status=400)

    @Route("/{{ entity_name }}s/{id}", "data.update", methods=["PUT"])
    async def update(self, id: int, data: {{ entity_class_name }}.generate_create_model()):
        """PUT /{{ entity_name }}s/{id} - Replace the entire {{ entity_name }} resource"""
        try:
            {{ entity_name }} = self.repository.find(id)
            if not {{ entity_name }}:
                return self.json({
                    "error": "{{ entity_class_name }} not found",
                    "status": "not_found"
                }, status=404)

            # Complete replacement of the resource
            update_data = data.dict()
            for key, value in update_data.items():
                if hasattr({{ entity_name }}, key):
                    setattr({{ entity_name }}, key, value)

            self.entity_manager.persist({{ entity_name }})
            self.entity_manager.commit()

            self.entity_manager.refresh({{ entity_name }})

            return self.json({
                "{{ entity_name }}": {{ entity_name }}.dict(),
                "message": "{{ entity_class_name }} updated successfully",
                "status": "updated"
            }, status=200)
        except Exception as e:
            return self.json({
                "error": "Failed to update {{ entity_name }}",
                "message": str(e),
                "status": "error"
            }, status=400)

    @Route("/{{ entity_name }}s/{id}", "{{ entity_file_name }}.patch", methods=["PATCH"])
    async def patch(self, id: int, data: {{ entity_class_name }}.generate_patch_model()):
        """PATCH /{{ entity_name }}s/{id} - Partially update a {{ entity_name }} resource"""
        try:
            {{ entity_name }} = self.repository.find(id)
            if not {{ entity_name }}:
                return self.json({
                    "error": "{{ entity_class_name }} not found",
                    "status": "not_found"
                }, status=404)

            update_data = data.dict(exclude_unset=True)

            # Partial update - only modify provided fields
            for key, value in update_data.items():
                if hasattr({{ entity_name }}, key):
                    setattr({{ entity_name }}, key, value)

            self.entity_manager.persist({{ entity_name }})
            self.entity_manager.commit()

            self.entity_manager.refresh({{ entity_name }})

            return self.json({
                "{{ entity_name }}": {{ entity_name }}.dict(),
                "message": "{{ entity_class_name }} partially updated successfully",
                "status": "updated"
            }, status=200)
        except Exception as e:
            return self.json({
                "error": "Failed to patch {{ entity_name }}",
                "message": str(e),
                "status": "error"
            }, status=400)

    @Route("/{{ entity_name }}s/{id}", "{{ entity_file_name }}.destroy", methods=["DELETE"])
    async def destroy(self, id: int):
        """DELETE /{{ entity_name }}s/{id} - Delete a {{ entity_name }} resource"""
        try:
            {{ entity_name }} = self.repository.find(id)
            if not {{ entity_name }}:
                return self.json({
                    "error": "{{ entity_class_name }} not found",
                    "status": "not_found"
                }, status=404)

            self.entity_manager.delete({{ entity_name }})
            self.entity_manager.commit()

            return self.json({
                "message": "{{ entity_class_name }} deleted successfully",
                "status": "deleted"
            }, status=204)
        except Exception as e:
            return self.json({
                "error": "Failed to delete {{ entity_name }}",
                "message": str(e),
                "status": "error"
            }, status=500)