from typing import List, Optional from backend.infra.template_message_handler import TemplateMessageHandler from backend.models.models import MessageTemplateDoc from common.log.module_logger import ModuleLogger from datetime import datetime from common.constants.region import UserRegion class TemplateMessageService: def __init__(self): self.template_message_handler = TemplateMessageHandler() self.module_logger = ModuleLogger(sender_id="TemplateMessageService") async def verify_tenant_access(self, template_id: str, tenant_id: str, region: int): """verify tenant access""" try: result = await self.template_message_handler.verify_tenant_access(template_id, tenant_id, region) await self.module_logger.log_info( info="Tenant access verified", properties={ "template_id": template_id, "tenant_id": tenant_id, "region": region } ) return result except Exception as e: await self.module_logger.log_error( error="Failed to verify tenant access", properties={ "template_id": template_id, "tenant_id": tenant_id, "region": region, "error": str(e) } ) raise # ==================== global templates ==================== async def create_global_template(self, template: MessageTemplateDoc): """create global template""" try: result = await self.template_message_handler.create_global_template(template) await self.module_logger.log_info( info="Global template created", properties={ "template_id": template.template_id, "region": template.region } ) return result except Exception as e: await self.module_logger.log_error( error="Failed to create global template", properties={ "template_id": template.template_id, "error": str(e) } ) raise async def update_global_template(self, template_id: str, data: dict, region: int): """update global template""" try: # check if template exists template = await self.template_message_handler.find_global_template(template_id, region) if not template: raise ValueError(f"Global template not found for template_id: {template_id}, region: {region}") result = await self.template_message_handler.update_global_template(template_id, data, region) await self.module_logger.log_info( info="Global template updated", properties={ "template_id": template_id, "region": region, "updated_fields": list(data.keys()) } ) return result except Exception as e: await self.module_logger.log_error( error="Failed to update global template", properties={ "template_id": template_id, "region": region, "error": str(e) } ) raise async def delete_global_template(self, template_id: str): """delete global template""" try: result = await self.template_message_handler.delete_global_template(template_id) await self.module_logger.log_info( info="Global template deleted", properties={ "template_id": template_id } ) return result except Exception as e: await self.module_logger.log_error( error="Failed to delete global template", properties={ "template_id": template_id, "error": str(e) } ) raise async def list_global_templates(self, region: int): """list global templates""" try: result = await self.template_message_handler.list_global_templates(region) await self.module_logger.log_info( info="Global templates listed", properties={ "region": region, "count": len(result) if result else 0 } ) return result except Exception as e: await self.module_logger.log_error( error="Failed to list global templates", properties={ "region": region, "error": str(e) } ) raise # ==================== TENANT templates ==================== async def list_tenant_templates(self, tenant_id: str, region: int): """list tenant templates""" try: result = await self.template_message_handler.list_tenant_templates(tenant_id, region) await self.module_logger.log_info( info="Tenant templates listed", properties={ "tenant_id": tenant_id, "region": region, "count": len(result) if result else 0 } ) return result except Exception as e: await self.module_logger.log_error( error="Failed to list tenant templates", properties={ "tenant_id": tenant_id, "region": region, "error": str(e) } ) raise async def assign_template_to_tenant(self, tenant_id: str, template_ids: List[str], region: int): """assign templates to tenant""" try: results = [] for template_id in template_ids: try: global_template = await self.template_message_handler.find_global_template(template_id, region) if not global_template: results.append({ "template_id": template_id, "success": False, "msg": "Global template not found" }) continue # check if tenant already has this template existing = await self.template_message_handler.find_tenant_template(tenant_id, template_id, region) if existing: results.append({ "template_id": template_id, "success": False, "msg": "Template already assigned to tenant" }) continue # copy template to tenant, use unique template_id tenant_template_id = f"{global_template.template_id}_tenant_{tenant_id}" new_template = MessageTemplateDoc( template_id=tenant_template_id, tenant_id=tenant_id, region=global_template.region, subject=global_template.subject, body=global_template.body, is_active=global_template.is_active, created_at=datetime.utcnow() ) await self.template_message_handler.create_tenant_template(tenant_id, new_template) results.append({ "template_id": template_id, "success": True, "template_db_id": str(new_template.id) }) except Exception as e: results.append({ "template_id": template_id, "success": False, "msg": f"Error: {str(e)}" }) success_count = sum(1 for r in results if r.get("success")) await self.module_logger.log_info( info="Templates assigned to tenant", properties={ "tenant_id": tenant_id, "region": region, "total_requested": len(template_ids), "success_count": success_count } ) return results except Exception as e: await self.module_logger.log_error( error="Failed to assign templates to tenant", properties={ "tenant_id": tenant_id, "region": region, "error": str(e) } ) raise async def create_tenant_template(self, tenant_id: str, template: MessageTemplateDoc): """create tenant template""" try: template.tenant_id = tenant_id result = await self.template_message_handler.create_tenant_template(tenant_id, template) await self.module_logger.log_info( info="Tenant template created", properties={ "tenant_id": tenant_id, "template_id": template.template_id, "region": template.region } ) return result except Exception as e: await self.module_logger.log_error( error="Failed to create tenant template", properties={ "tenant_id": tenant_id, "template_id": template.template_id, "error": str(e) } ) raise async def update_tenant_template(self, tenant_id: str, template_id: str, data: dict, region: int): """update tenant template""" try: template = await self.template_message_handler.find_tenant_template(tenant_id, template_id, region) if not template: raise ValueError("Template not found") result = await self.template_message_handler.update_tenant_template(tenant_id, template_id, data, region) await self.module_logger.log_info( info="Tenant template updated", properties={ "tenant_id": tenant_id, "template_id": template_id, "region": region, "updated_fields": list(data.keys()) } ) return result except Exception as e: await self.module_logger.log_error( error="Failed to update tenant template", properties={ "tenant_id": tenant_id, "template_id": template_id, "region": region, "error": str(e) } ) raise async def delete_tenant_template(self, tenant_id: str, template_id: str, region: int): """delete tenant template""" try: template = await self.template_message_handler.find_tenant_template(tenant_id, template_id, region) if not template: raise ValueError("Template not found") result = await self.template_message_handler.delete_tenant_template(tenant_id, template_id, region) await self.module_logger.log_info( info="Tenant template deleted", properties={ "tenant_id": tenant_id, "template_id": template_id } ) return result except Exception as e: await self.module_logger.log_error( error="Failed to delete tenant template", properties={ "tenant_id": tenant_id, "template_id": template_id, "error": str(e) } ) raise async def render_template(self, tenant_id: str, template_id: str, properties: dict, region: int): """render template""" try: template = await self.template_message_handler.find_tenant_template(tenant_id, template_id, region) if not template: raise ValueError("Template not found") result = await self.template_message_handler.render_template(template, properties) await self.module_logger.log_info( info="Template rendered successfully", properties={ "tenant_id": tenant_id, "template_id": template_id, "region": region, "properties_count": len(properties) } ) return result except Exception as e: await self.module_logger.log_error( error="Failed to render template", properties={ "tenant_id": tenant_id, "template_id": template_id, "region": region, "error": str(e) } ) raise async def get_template(self, tenant_id: str, template_id: str, region: int): """get template""" try: template = await self.template_message_handler.find_tenant_template(tenant_id, template_id, region) if template: await self.module_logger.log_info( "Tenant template found", properties={ "tenant_id": tenant_id, "template_id": template_id, "region": region } ) return template raise ValueError(f"Template not found") except Exception as e: await self.module_logger.log_error( error="Failed to get tenant template", properties={ "tenant_id": tenant_id, "template_id": template_id, "region": region, "error": str(e) } ) raise