"""General-purpose email generator for Prism.

Generates a standalone email service using Resend API for transactional
and business-logic emails, including:
- Email client (Resend wrapper with config)
- Email service (general-purpose send API)
- HTML email templates (base layout + per-template files)
- Template renderer for HTML emails
"""

from __future__ import annotations

from pathlib import Path

from prisme.generators.base import GeneratedFile, GeneratorBase
from prisme.spec.stack import FileStrategy
from prisme.utils.template_engine import TemplateRenderer


class EmailGenerator(GeneratorBase):
    """Generates general-purpose email infrastructure using Resend."""

    REQUIRED_TEMPLATES = [
        "backend/email/email_config.py.jinja2",
        "backend/email/email_client.py.jinja2",
        "backend/email/email_service.py.jinja2",
        "backend/email/email_templates.py.jinja2",
        "backend/email/email_init.py.jinja2",
        "backend/email/base_email.html.jinja2",
    ]

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        email_config = self.email_service_config
        if not email_config.enabled:
            self.skip_generation = True
            return

        self.renderer = TemplateRenderer()
        self.renderer.validate_templates_exist(self.REQUIRED_TEMPLATES)

        backend_base = Path(self.generator_config.backend_output)
        package_name = self.get_package_name()
        package_base = backend_base / package_name

        self.email_path = package_base / "email"
        self.templates_path = package_base / "email" / "templates"

    def _get_context(self) -> dict:
        """Build template context from email service config."""
        config = self.email_service_config
        project_name = self.get_package_name()
        project_title = self.spec.effective_title

        return {
            "project_name": project_name,
            "project_title": project_title,
            "from_address": config.from_address,
            "resend_api_key_env": config.resend_api_key_env,
            "reply_to": config.reply_to,
            "templates": [t.model_dump() for t in config.templates],
            "has_templates": len(config.templates) > 0,
        }

    def generate_files(self) -> list[GeneratedFile]:
        """Generate all email service files."""
        if getattr(self, "skip_generation", False):
            return []

        files = [
            self._generate_email_config(),
            self._generate_email_client(),
            self._generate_email_service(),
            self._generate_email_templates(),
            self._generate_email_init(),
            self._generate_base_html_template(),
        ]

        # Generate per-template HTML files
        for template_spec in self.email_service_config.templates:
            files.append(self._generate_template_html(template_spec))

        return files

    def _generate_email_config(self) -> GeneratedFile:
        """Generate email settings module."""
        content = self.renderer.render_file(
            "backend/email/email_config.py.jinja2",
            context=self._get_context(),
        )
        return GeneratedFile(
            path=self.email_path / "config.py",
            content=content,
            strategy=FileStrategy.ALWAYS_OVERWRITE,
            description="Email configuration settings",
        )

    def _generate_email_client(self) -> GeneratedFile:
        """Generate Resend email client wrapper."""
        content = self.renderer.render_file(
            "backend/email/email_client.py.jinja2",
            context=self._get_context(),
        )
        return GeneratedFile(
            path=self.email_path / "client.py",
            content=content,
            strategy=FileStrategy.ALWAYS_OVERWRITE,
            description="Resend email client",
        )

    def _generate_email_service(self) -> GeneratedFile:
        """Generate general-purpose email service."""
        content = self.renderer.render_file(
            "backend/email/email_service.py.jinja2",
            context=self._get_context(),
        )
        return GeneratedFile(
            path=self.email_path / "service.py",
            content=content,
            strategy=FileStrategy.GENERATE_ONCE,
            description="General-purpose email service",
        )

    def _generate_email_templates(self) -> GeneratedFile:
        """Generate email template renderer."""
        content = self.renderer.render_file(
            "backend/email/email_templates.py.jinja2",
            context=self._get_context(),
        )
        return GeneratedFile(
            path=self.email_path / "templates.py",
            content=content,
            strategy=FileStrategy.ALWAYS_OVERWRITE,
            description="Email template renderer",
        )

    def _generate_email_init(self) -> GeneratedFile:
        """Generate __init__.py for email module."""
        content = self.renderer.render_file(
            "backend/email/email_init.py.jinja2",
            context=self._get_context(),
        )
        return GeneratedFile(
            path=self.email_path / "__init__.py",
            content=content,
            strategy=FileStrategy.ALWAYS_OVERWRITE,
            description="Email module init",
        )

    def _generate_base_html_template(self) -> GeneratedFile:
        """Generate base HTML email template."""
        content = self.renderer.render_file(
            "backend/email/base_email.html.jinja2",
            context=self._get_context(),
        )
        return GeneratedFile(
            path=self.templates_path / "base.html",
            content=content,
            strategy=FileStrategy.GENERATE_ONCE,
            description="Base HTML email template",
        )

    def _generate_template_html(self, template_spec) -> GeneratedFile:
        """Generate an HTML email template for a specific template spec."""
        ctx = self._get_context()
        ctx["template"] = (
            template_spec if isinstance(template_spec, dict) else template_spec.model_dump()
        )

        content = self.renderer.render_file(
            "backend/email/custom_email.html.jinja2",
            context=ctx,
        )
        return GeneratedFile(
            path=self.templates_path / f"{ctx['template']['name']}.html",
            content=content,
            strategy=FileStrategy.GENERATE_ONCE,
            description=f"Email template: {ctx['template']['name']}",
        )
