import inflection
import sys
import os

def create(name, microservice = None):

    estructura = [
        "application/services",
        "application/use_cases",
        "domain/entities",
        "domain/repositories",
        "domain/value_objects",
        "infrastructure/dto",
        "infrastructure/models",
        "infrastructure/repositories",
        "infrastructure/routers",
        "infrastructure/validations",
    ]

    camel_case_plural = lambda s: inflection.pluralize(s.split('_')[0]) + ''.join(word.capitalize() for word in s.split('_')[1:])
    pascal_case = ''.join(word.capitalize() for word in name.split('_'))
    name_plural = camel_case_plural(name)

    archivos = {
        f"application/services/{name}_service.py":(
            "from typing import List, Optional, Dict, Any\n"
            "\n"
            f"from app.{name}.domain.repositories.{name}_repository import {pascal_case}Repository\n"
            f"from app.{name}.domain.entities.{name} import {pascal_case}\n"
            "\n"
            f"class {pascal_case}Service:\n"
            f"    def __init__(self, repository: {pascal_case}Repository):\n"
            "        self.repository = repository\n"
            "\n"
            "    def list(self,\n"
            "            trashed: int,\n"
            "            paginate: int,\n"
            "            page: int,\n"
            "            rows: int,\n"
            "            filters: Optional[Dict[str, Any]] = None\n"
            f"        ) -> List[{pascal_case}]:\n"
            "        return self.repository.all(trashed, paginate, page, rows, filters)\n"
            "\n"
            f"    def search(self, id: str) -> Optional[{pascal_case}]:\n"
            "        return self.repository.find(id)\n"
            "\n"
            f"    def save(self, {name}: {pascal_case}) -> {pascal_case}:\n"
            f"        return self.repository.create({name})\n"
            "\n"
            f"    def modify(self, id: str, {name}: {pascal_case}) -> Optional[{pascal_case}]:\n"
            f"        return self.repository.update(id, {name})\n"
            "\n"
            f"    def remove(self, id: str) -> Optional[{pascal_case}]:\n"
            "        return self.repository.delete(id)\n"
        ),
        f"application/use_cases/create_{name}.py":(
            f"from app.{name}.application.services.{name}_service import {pascal_case}Service\n"
            f"from app.{name}.domain.entities.{name} import {pascal_case}\n"
            "\n"
            f"class Create{pascal_case}:\n"
            f"    def __init__(self, service: {pascal_case}Service):\n"
            "        self.service = service\n"
            "\n"
            f"    def execute(self, {name}: {pascal_case}) -> {pascal_case}:\n"
            f"        return self.service.save({name})\n"
        ),
        f"application/use_cases/delete_{name}.py":(
            "from typing import Optional\n"
            "\n"
            f"from app.{name}.application.services.{name}_service import {pascal_case}Service\n"
            f"from app.{name}.domain.entities.{name} import {pascal_case}\n"
            "\n"
            f"class Delete{pascal_case}:\n"
            f"    def __init__(self, service: {pascal_case}Service):\n"
            "        self.service = service\n"
            "\n"
            f"    def execute(self, id: str) -> Optional[{pascal_case}]:\n"
            "        return self.service.remove(id)\n"
        ),
        f"application/use_cases/get_{name_plural}.py":(
            "from typing import List, Optional, Dict, Any\n"
            "\n"
            f"from app.{name}.application.services.{name}_service import {pascal_case}Service\n"
            f"from app.{name}.domain.entities.{name} import {pascal_case}\n"
            "\n"
            f"class Get{ name_plural.capitalize()}:\n"
            f"    def __init__(self, service: {pascal_case}Service):\n"
            "        self.service = service\n"
            "\n"
            "    def execute(self,\n"
            "                trashed: int,\n"
            "                paginate: int,\n"
            "                page: int,\n"
            "                rows: int,\n"
            "                filters: Optional[Dict[str, Any]] = None\n"
            f"        ) -> List[{pascal_case}]:\n"
            "        return self.service.list(trashed, paginate, page, rows, filters)\n"
        ),
        f"application/use_cases/get_{name}_by_id.py":(
            "from typing import Optional\n"
            "\n"
            f"from app.{name}.application.services.{name}_service import {pascal_case}Service\n"
            f"from app.{name}.domain.entities.{name} import {pascal_case}\n"
            "\n"
            f"class Get{pascal_case}ById:\n"
            f"    def __init__(self, service: {pascal_case}Service):\n"
            "        self.service = service\n"
            "\n"
            f"    def execute(self, id: str) -> Optional[{pascal_case}]:\n"
            "        return self.service.search(id)\n"
        ),
        f"application/use_cases/update_{name}.py":(
            "from typing import Optional\n"
            "\n"
            f"from app.{name}.application.services.{name}_service import {pascal_case}Service\n"
            f"from app.{name}.domain.entities.{name} import {pascal_case}\n"
            "\n"
            f"class Update{pascal_case}:\n"
            f"    def __init__(self, service: {pascal_case}Service):\n"
            "        self.service = service\n"
            "\n"
            f"    def execute(self, id: str, {name}: {pascal_case}) -> Optional[{pascal_case}]:\n"
            f"        return self.service.modify(id, {name})\n"

        ),
        f"domain/entities/{name}.py":(
            "from pydantic import BaseModel, Field\n"
            "\n"
            "# import value objects\n"
            f"from app.{name}.domain.value_objects.datetime import DateTime\n"
            "\n"
            f"class {pascal_case}(BaseModel):\n"
            f"    id: str = Field(..., description=\"Unique identifier for the {name}\")\n"
            f"    # field: str = Field(..., description=\"field of the {name}\")\n"
            f"    example: str = Field(..., description=\"Example field\")\n"
            f"    created_at: DateTime = Field(..., description=\"Timestamp when the {name} was created\")\n"
            f"    updated_at: DateTime = Field(..., description=\"Timestamp when the {name} was last updated\")\n"
            f"    deleted_at: DateTime = Field(None, description=\"Timestamp when the {name} was deleted\")\n"
        ),
        f"domain/repositories/{name}_repository.py":(
            "from typing import List, Optional, Dict, Any\n"
            "from abc import ABC, abstractmethod\n"
            "\n"
            f"from app.{name}.domain.entities.{name} import {pascal_case}\n"
            "\n"
            f"class {pascal_case}Repository(ABC):\n"
            "    @abstractmethod\n"
            "    def all(self,\n"
            "            trashed: int,\n"
            "            paginate: int,\n"
            "            page: int,\n"
            "            rows: int,\n"
            "            filters: Optional[Dict[str, Any]] = None\n"
            f"        ) -> List[{pascal_case}]:\n"
            "        pass\n"
            "\n"
            "    @abstractmethod\n"
            f"    def find(self, id: str) -> Optional[{pascal_case}]:\n"
            "        pass\n"
            "\n"
            "    @abstractmethod\n"
            f"    def create(self, {name}: {pascal_case}) -> {pascal_case}:\n"
            "        pass\n"
            "\n"
            "    @abstractmethod\n"
            f"    def update(self, id:str, {name}: {pascal_case}) -> Optional[{pascal_case}]:\n"
            "        pass\n"
            "\n"
            "    @abstractmethod\n"
            f"    def delete(self, id: str) -> Optional[{pascal_case}]:\n"
            "        pass\n"
        ),
        f"domain/value_objects/datetime.py":(
            "from pydantic import BaseModel, Field, field_validator\n"
            "from typing import Optional, Any\n"
            "from datetime import datetime as dt\n"
            "\n"
            "class DateTime(BaseModel):\n"
            "    \"\"\"\n"
            "    DateTime represents a date and time value in the system.\n"
            "    It is a value object that encapsulates the date and time information.\n"
            "    \"\"\"\n"
            "\n"
            "    value: Optional[str] = Field(None, description=\"Date and time value\")\n"
            "\n"
            "    @field_validator(\"value\")\n"
            "    def validate_datetime(cls, value: str, context: Optional[Any] = None) -> None:\n"
            "        \"\"\"\n"
            "        Validar que el formato de la feha y hora se Y-m-d H:M:S. o vacio.\n"
            "        \"\"\"\n"
            "        if value is None:\n"
            "            return None\n"
            "\n"
            "        try:\n"
            "            dt.strptime(value, \"%Y-%m-%dT%H:%M:%S.%fZ\")\n"
            "        except ValueError:\n"
            "            raise ValueError(\"El formato de fecha y hora no es válido. Debe ser YYYY-MM-DDTHH:MM:SSZ.\")\n"
            "\n"
            "        return value\n"
            "\n"
            "    @classmethod\n"
            "    def now(cls) -> \"DateTime\":\n"
            "        now_str = dt.now().strftime(\"%Y-%m-%dT%H:%M:%S.%fZ\")\n"
            "        cls.value = now_str\n"
            "        print(f\"Fecha y hora actual: {now_str}\")\n"
            "        return cls(value=now_str)\n"
            "\n"
            "    def to_native(self) -> dt:\n"
            "        print(f\"Convertir a datetime: {self.value}\")\n"
            "        if not self.value:\n"
            "            return None\n"
            "        return dt.strptime(self.value, \"%Y-%m-%dT%H:%M:%S.%fZ\")\n"
            "\n"
            "\n"
            "    def __eq__(self, other: object) -> bool:\n"
            "        return isinstance(other, DateTime) and self.value == other.value\n"
            "\n"
            "    def __str__(self) -> str:\n"
            "        return self.value or \"\"\n"
            "\n"
            "    class Config:\n"
            "        json_schema_extra = {\n"
            "            \"example\": {\n"
            "                \"datetime\": \"2023-10-01 12:00:00\"\n"
            "            }\n"
            "        }\n"
        ),
        f"infrastructure/dto/input_{name}.py":(
            "from pydantic import BaseModel, Field\n"
            "from typing import Optional\n"
            "\n"
            "# import value objects\n"
            "\n"
            f"class Input{pascal_case}(BaseModel):\n"
            "    example: str = Field(..., description=\"Example field\")\n"
            "\n"
            f"class InputUpdate{pascal_case}(BaseModel):\n"
            "    example: str = Field(..., description=\"Example field\")\n"
        ),
        f"infrastructure/dto/output_{name}.py":(
            "from pydantic import BaseModel, Field\n"
            "from typing import Optional\n"
            "\n"
            "# import value objects\n"
            "\n"
            f"class Output{pascal_case}(BaseModel):\n"
            f"    id: str = Field(..., description=\"Unique identifier for the {name}\") \n"
            "    example: str = Field(..., description=\"Example field\")\n"
            f"    deleted_at: Optional[str] = Field(None, description=\"Timestamp when the {name} was deleted\")\n"
        ),
        f"infrastructure/models/{name}_model.py":(
            "from typing import Optional, List\n"
            "import uuid\n"
            "\n"
            "from sqlalchemy import Column, String, DateTime\n"
            "from sqlalchemy.dialects.postgresql import UUID\n"
            "from sqlalchemy.sql import func\n"
            "import uuid\n"
            "\n"
            "from config.database import Base\n"
            "\n"
            f"class {pascal_case}Model(Base):\n"
            f"    __tablename__ = \"{inflection.pluralize(name)}\"\n"
            "\n"
            "    # id es de tipo uuid\n"
            "    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, index=True)\n"
            "    example = Column(String, unique=True, index=True, nullable=False)\n"
            "    created_at = Column(DateTime, server_default=func.now(), nullable=False)\n"
            "    updated_at = Column(DateTime(timezone=True), default=func.now(), onupdate=func.now(), nullable=False)\n"
            "    deleted_at = Column(DateTime, nullable=True)\n"
            "\n"
            "    def to_dict(self, include: Optional[List[str]] = None) -> dict:\n"
            "        data = {\n"
            "            \"id\": str(self.id),\n"
            "            \"example\": self.example,\n"
            "            \"deleted_at\": self.deleted_at.strftime(\"%Y-%m-%dT%H:%M:%S.%fZ\") if self.deleted_at else None\n"
            "        }\n"
            "\n"
            "        if include:\n"
            "            return {k: v for k, v in data.items() if k in include}\n"
            "        return data\n"
        ),f"infrastructure/repositories/{name}_repository_impl.py":(
            "from typing import List, Optional, Dict, Any\n"
            "from datetime import datetime\n"
            "\n"
            f"from app.{name}.domain.value_objects.datetime import DateTime\n"
            "from app.Traits.filters import Filterable\n"
            "\n"
            f"from app.{name}.domain.repositories.{name}_repository import {pascal_case}Repository\n"
            f"from app.{name}.infrastructure.models.{name}_model import {pascal_case}Model\n"
            f"from app.{name}.domain.entities.{name} import {pascal_case}\n"
            "\n"
            f"class {pascal_case}RepositoryImpl({pascal_case}Repository):\n"
            "    def __init__(self, db):\n"
            "        self.db = db\n"
            "        self.filterable = Filterable()\n"
            "\n"
            "    def all(self,\n"
            "            trashed: int,\n"
            "            paginate: int,\n"
            "            page: int,\n"
            "            rows: int,\n"
            "            filters: Optional[Dict[str, Any]] = None\n"
            f"        ) -> List[{pascal_case}]:\n"
            "\n"
            f"        query = self.db.query({pascal_case}Model)\n"
            "\n"
            "        columns_change = {\n"
            f"            'example': {pascal_case}Model.example,\n"
            "        }\n"
            "\n"
            "        if trashed == 0:\n"
            f"            query = query.filter({pascal_case}Model.deleted_at.is_(None))\n"
            "\n"
            "        if filters:\n"
            "            query = self.filterable.apply_filters(query, filters, columns_change)\n"
            "\n"
            "        if paginate == 1:\n"
            "            total = query.count()\n"
            "            offset = (page - 1) * rows\n"
            "            items = query.offset(offset).limit(rows).all()\n"
            "        else:\n"
            "            items = query.all()\n"
            "            total = len(items)\n"
            "\n"
            "        data = [item.to_dict() for item in items]\n"
            "\n"
            "        return {\n"
            "            'total': total,\n"
            "            'data':  data,\n"
            "        }\n"
            "\n"
            f"    def find(self, id: str) -> Optional[{pascal_case}]:\n"
            f"        return self.db.query({pascal_case}Model).filter_by(id=id).first()\n"
            "\n"
            f"    def create(self, {name}: {pascal_case}) -> {pascal_case}:\n"
            "        try:\n"
            f"            {name}_model = {pascal_case}Model(**{name})\n"
            f"            self.db.add({name}_model)\n"
            "            self.db.commit()\n"
            f"            self.db.refresh({name}_model)\n"
            f"            return {name}_model\n"
            "        except Exception as e:\n"
            "            self.db.rollback()\n"
            "            raise e\n"
            "\n"
            f"    def update(self, id: str, {name}: {pascal_case}) -> Optional[{pascal_case}]:\n"
            f"        existing_{name} = self.find(id)\n"
            f"        if existing_{name}:\n"
            f"            for key, value in {name}.items():\n"
            f"                setattr(existing_{name}, key, value)\n"
            "            self.db.commit()\n"
            f"            self.db.refresh(existing_{name})\n"
            f"            return existing_{name}\n"
            "        return None\n"
            "\n"
            f"    def delete(self, id: str) -> Optional[{pascal_case}]:\n"
            f"        {name} = self.find(id)\n"
            f"        if {name} and {name}.deleted_at is None:\n"
            f"            {name}.deleted_at = DateTime.now().to_native()\n"
            "            self.db.commit()\n"
            f"            self.db.refresh({name})\n"
            f"        elif {name} and {name}.deleted_at is not None:\n"
            f"            {name}.deleted_at = None\n"
            "            self.db.commit()\n"
            f"            self.db.refresh({name})\n"
            f"        return {name}\n"
        ),
        f"infrastructure/routers/{name}_router.py":(
            "from fastapi import APIRouter, Depends, Path, HTTPException\n"
            "from sqlalchemy.orm import Session\n"
            "from uuid import UUID\n"
            "\n"
            f"from app.{name}.infrastructure.repositories.{name}_repository_impl import {pascal_case}RepositoryImpl\n"
            f"from app.{name}.application.services.{name}_service import {pascal_case}Service\n"
            "\n"
            f"from app.{name}.application.use_cases.get_{name}_by_id import Get{pascal_case}ById\n"
            f"from app.{name}.application.use_cases.create_{name} import Create{pascal_case}\n"
            f"from app.{name}.application.use_cases.delete_{name} import Delete{pascal_case}\n"
            f"from app.{name}.application.use_cases.update_{name} import Update{pascal_case}\n"
            f"from app.{name}.application.use_cases.get_{name_plural} import Get{name_plural.capitalize()}\n"
            "\n"
            "from app.components.filter.infrastructure.dto.input_filter import InputFilter\n"
            f"from app.{name}.infrastructure.dto.input_{name} import Input{pascal_case}, InputUpdate{pascal_case}\n"
            f"from app.{name}.infrastructure.dto.output_{name} import Output{pascal_case}\n"
            "\n"
            f"from app.{name}.infrastructure.validations.insert import {pascal_case}InsertValidation\n"
            f"from app.{name}.infrastructure.validations.update import {pascal_case}UpdateValidation\n"
            "\n"
            "from config.database import database\n"
            "\n"
            f"class {pascal_case}API:\n"
            "    def __init__(self):\n"
            f"        self.router = APIRouter(prefix=\"/{name}\", tags=[\"{pascal_case}\"])\n"
            "        self._setup_routes()\n"
            "\n"
            "    def _setup_routes(self):\n"
            f"        self.router.get(\"\")(self.get_{name})\n"
            f"        self.router.get(\"/{{id}}\")(self.get_{name}_by_id)\n"
            f"        self.router.post(\"\")(self.create_{name})\n"
            f"        self.router.put(\"/{{id}}\")(self.update_{name})\n"
            f"        self.router.delete(\"/{{id}}\")(self.delete_{name})\n"
            "\n"
            "    @staticmethod\n"
            f"    def _get_{name}_update_validation(\n"
            f"        {name}: InputUpdate{pascal_case},\n"
            "        id: UUID = Path(..., description=\"ID del usuario a actualizar\"),\n"
            "        db: Session = Depends(database.get_db)\n"
            "    ):\n"
            f"        return {pascal_case}UpdateValidation.validate({name}, id, db)\n"
            "\n"
            f"    async def get_{name}(self, payload: InputFilter = Depends(InputFilter.from_request_body), db: Session = Depends(database.get_db)):\n"
            f"        repository = {pascal_case}RepositoryImpl(db)\n"
            f"        service = {pascal_case}Service(repository)\n"
            f"        use_case = Get{name_plural.capitalize()}(service)\n"
            f"        {name_plural} = use_case.execute(**payload.model_dump())\n"
            f"        return {name_plural}\n"
            "\n"
            f"    def get_{name}_by_id(self, id: UUID, db: Session = Depends(database.get_db)):\n"
            f"        repository = {pascal_case}RepositoryImpl(db)\n"
            f"        service = {pascal_case}Service(repository)\n"
            f"        use_case = Get{pascal_case}ById(service)\n"
            f"        {name} = use_case.execute(id)\n"
            f"        if {name} is None:\n"
            "            raise HTTPException(status_code=404, detail=\"No hay resultados\")\n"
            f"        return Output{pascal_case}.model_validate({name}.to_dict())\n"
            "\n"
            f"    def create_{name}(self, {name}: Input{pascal_case} = Depends({pascal_case}InsertValidation.validate), db: Session = Depends(database.get_db)):\n"
            f"        repository = {pascal_case}RepositoryImpl(db)\n"
            f"        service = {pascal_case}Service(repository)\n"
            f"        use_case = Create{pascal_case}(service)\n"
            f"        created_{name} = use_case.execute({name})\n"
            f"        return Output{pascal_case}.model_validate(created_{name}.to_dict())\n"
            "\n"
            f"    def update_{name}(self, id: UUID, {name}: InputUpdate{pascal_case} = Depends(_get_{name}_update_validation), db: Session = Depends(database.get_db)):\n"
            f"        repository = {pascal_case}RepositoryImpl(db)\n"
            f"        service = {pascal_case}Service(repository)\n"
            f"        use_case = Update{pascal_case}(service)\n"
            f"        updated_{name} = use_case.execute(id, {name})\n"
            f"        if updated_{name} is None:\n"
            "            raise HTTPException(status_code=404, detail=\"No hay datos para actualizar\")\n"
            f"        return Output{pascal_case}.model_validate(updated_{name}.to_dict())\n"
            "\n"
            f"    def delete_{name}(self, id: UUID, db: Session = Depends(database.get_db)):\n"
            f"        repository = {pascal_case}RepositoryImpl(db)\n"
            f"        service = {pascal_case}Service(repository)\n"
            f"        use_case = Delete{pascal_case}(service)\n"
            f"        deleted_{name} = use_case.execute(id)\n"
            f"        if deleted_{name} is None:\n"
            "            raise HTTPException(status_code=404, detail=\"No hay datos para eliminar\")\n"
            f"        return Output{pascal_case}.model_validate(deleted_{name}.to_dict())\n"
            "\n"
            f"router = {pascal_case}API().router\n"
        ),
        f"infrastructure/validations/insert.py":(
            "from fastapi import Depends, HTTPException\n"
            "from sqlalchemy.orm import Session\n"
            "import re\n"
            "\n"
            "from config.database import database\n"
            "\n"
            "\n"
            f"from app.{name}.infrastructure.models.{name}_model import {pascal_case}Model\n"
            f"from app.{name}.infrastructure.dto.input_{name} import Input{pascal_case}\n"
            "\n"
            f"class {pascal_case}InsertValidation:\n"
            "    @staticmethod\n"
            f"    def validate({name}: Input{pascal_case}, db: Session = Depends(database.get_db)) -> Input{pascal_case}:\n"
            "        errors = {}\n"
            "\n"
            "        # Check if the example is contained in special characters using regex\n"
            f"        if not re.match(r\"^[a-zA-ZÀ-ÿ\u00f1\u00d1\s0-9]+$\", {name}.example.strip()):\n"
            "            errors.setdefault(\"example\", []).append(\"El example no puede contener caracteres especiales.\")\n"
            "\n"
            f"        existing_example = db.query({pascal_case}Model).filter_by(example={name}.example).first()\n"
            "        if existing_example:\n"
            "            errors.setdefault(\"example\", []).append(\"La example ya se encuentra registrada.\")\n"
            "\n"
            "        if errors:\n"
            "            raise HTTPException(status_code=422, detail=errors)\n"
            "\n"
            "        return {\n"
            f"            \"example\": {name}.example.strip(),\n"
            "        }\n"
        ),
        f"infrastructure/validations/update.py":(
            "from fastapi import Depends, HTTPException\n"
            "from sqlalchemy.orm import Session\n"
            "from uuid import UUID\n"
            "import re\n"
            "\n"
            "from config.database import database\n"
            "\n"
            f"from app.{name}.infrastructure.dto.input_{name} import InputUpdate{pascal_case}\n"
            f"from app.{name}.infrastructure.models.{name}_model import {pascal_case}Model\n"
            "\n"
            f"class {pascal_case}UpdateValidation:\n"
            "    @staticmethod\n"
            f"    def validate({name}: InputUpdate{pascal_case}, id: UUID, db: Session = Depends(database.get_db)) -> InputUpdate{pascal_case}:\n"
            "        errors = {}\n"
            "\n"
            "        # Check if the name is contained in special characters using regex\n"
            f"        if {name}.example is not None and not re.match(r\"^[a-zA-ZÀ-ÿ\u00f1\u00d1\s0-9]+$\", {name}.example.strip()):\n"
            "            errors.setdefault(\"example\", []).append(\"El nombre no puede contener caracteres especiales.\")\n"
            "\n"
            "        # Check if the identification is already in use\n"
            f"        existing_example = db.query({pascal_case}Model).filter({pascal_case}Model.id!=id, {pascal_case}Model.example=={name}.example).first()\n"
            "        if existing_example:\n"
            "            errors.setdefault(\"example\", []).append(\"La example ya se encuentra registrada.\")\n"
            "\n"
            "        if errors:\n"
            "            raise HTTPException(status_code=422, detail=errors)\n"
            "\n"
            "        update_data = {}\n"
            f"        if {name}.example is not None:\n"
            f"            update_data[\"example\"] = {name}.example.strip()\n"
            "\n"
            "        # Additional validation logic can be added here\n"
            "        return update_data\n"
        ),
    }

    if microservice is None and not os.path.isfile(f"{os.getcwd()}/Dockerfile"):
        print("[INFO] No se encuentra en la carpeta de un microservicio.")
        sys.exit()

    if microservice is not None:
        path = f"{microservice}/app/{name}"
    else:
        path = f"app/{name}"

    # Si la entidad ya existe, no la crea
    if os.path.exists(path):
        print(f"[INFO] La entidad {name} ya existe.")
        return

    if microservice is not None:
        os.makedirs(microservice + '/app/' + name, exist_ok=True)
    else:
        os.makedirs(path, exist_ok=True)

    # Crear subdirectorios
    for carpeta in estructura:
        os.makedirs(os.path.join(path, carpeta), exist_ok=True)

    # Crear archivos vacíos
    for archivo, content in archivos.items():
        ruta_archivo = os.path.join(path, archivo)
        with open(ruta_archivo, "w", encoding="utf-8") as f:
            f.write(content)

    print(f"[OK] Entidad {name} creada con éxito.")
