from __future__ import annotations

from alembic import op
import sqlalchemy as sa

revision = "20260608_phase_7s1_email_notifications"
down_revision = "20260607_phase_7r6a_cashfree"
branch_labels = None
depends_on = None


def _has_table(bind, table_name: str) -> bool:
    return sa.inspect(bind).has_table(table_name)


def upgrade() -> None:
    bind = op.get_bind()

    if not _has_table(bind, "email_settings"):
        op.create_table(
            "email_settings",
            sa.Column("id", sa.Integer(), primary_key=True, autoincrement=True),
            sa.Column("tenant_id", sa.Integer(), sa.ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False),
            sa.Column("branch_id", sa.Integer(), sa.ForeignKey("branches.id", ondelete="SET NULL"), nullable=True),
            sa.Column("smtp_host", sa.String(length=255), nullable=True),
            sa.Column("smtp_port", sa.Integer(), nullable=True),
            sa.Column("smtp_username", sa.String(length=255), nullable=True),
            sa.Column("smtp_password", sa.String(length=500), nullable=True),
            sa.Column("smtp_security", sa.String(length=20), nullable=False, server_default="SSL"),
            sa.Column("smtp_timeout_seconds", sa.Integer(), nullable=False, server_default="20"),
            sa.Column("from_email", sa.String(length=255), nullable=True),
            sa.Column("from_name", sa.String(length=255), nullable=True),
            sa.Column("reply_to_email", sa.String(length=255), nullable=True),
            sa.Column("imap_host", sa.String(length=255), nullable=True),
            sa.Column("imap_port", sa.Integer(), nullable=True),
            sa.Column("imap_username", sa.String(length=255), nullable=True),
            sa.Column("imap_password", sa.String(length=500), nullable=True),
            sa.Column("imap_security", sa.String(length=20), nullable=False, server_default="SSL"),
            sa.Column("send_auth_emails", sa.Boolean(), nullable=False, server_default=sa.true()),
            sa.Column("send_alert_emails", sa.Boolean(), nullable=False, server_default=sa.false()),
            sa.Column("send_billing_emails", sa.Boolean(), nullable=False, server_default=sa.true()),
            sa.Column("send_task_emails", sa.Boolean(), nullable=False, server_default=sa.true()),
            sa.Column("is_active", sa.Boolean(), nullable=False, server_default=sa.true()),
            sa.Column("created_by_user_id", sa.Integer(), sa.ForeignKey("users.id", ondelete="SET NULL"), nullable=True),
            sa.Column("updated_by_user_id", sa.Integer(), sa.ForeignKey("users.id", ondelete="SET NULL"), nullable=True),
            sa.Column("created_at_utc", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()),
            sa.Column("updated_at_utc", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()),
            sa.UniqueConstraint("tenant_id", "branch_id", name="uq_email_settings_tenant_branch"),
        )
        op.create_index("ix_email_settings_tenant_id", "email_settings", ["tenant_id"])
        op.create_index("ix_email_settings_branch_id", "email_settings", ["branch_id"])
        op.create_index("ix_email_settings_is_active", "email_settings", ["is_active"])

    if not _has_table(bind, "email_templates"):
        op.create_table(
            "email_templates",
            sa.Column("id", sa.Integer(), primary_key=True, autoincrement=True),
            sa.Column("tenant_id", sa.Integer(), sa.ForeignKey("tenants.id", ondelete="CASCADE"), nullable=True),
            sa.Column("branch_id", sa.Integer(), sa.ForeignKey("branches.id", ondelete="SET NULL"), nullable=True),
            sa.Column("template_code", sa.String(length=80), nullable=False),
            sa.Column("template_name", sa.String(length=160), nullable=False),
            sa.Column("subject_template", sa.String(length=500), nullable=False),
            sa.Column("body_template", sa.Text(), nullable=False),
            sa.Column("is_html", sa.Boolean(), nullable=False, server_default=sa.false()),
            sa.Column("is_active", sa.Boolean(), nullable=False, server_default=sa.true()),
            sa.Column("created_at_utc", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()),
            sa.Column("updated_at_utc", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()),
            sa.UniqueConstraint("tenant_id", "branch_id", "template_code", name="uq_email_templates_scope_code"),
        )
        op.create_index("ix_email_templates_tenant_id", "email_templates", ["tenant_id"])
        op.create_index("ix_email_templates_branch_id", "email_templates", ["branch_id"])
        op.create_index("ix_email_templates_template_code", "email_templates", ["template_code"])
        op.create_index("ix_email_templates_is_active", "email_templates", ["is_active"])

    if not _has_table(bind, "email_logs"):
        op.create_table(
            "email_logs",
            sa.Column("id", sa.Integer(), primary_key=True, autoincrement=True),
            sa.Column("tenant_id", sa.Integer(), sa.ForeignKey("tenants.id", ondelete="CASCADE"), nullable=True),
            sa.Column("branch_id", sa.Integer(), sa.ForeignKey("branches.id", ondelete="SET NULL"), nullable=True),
            sa.Column("recipient_email", sa.String(length=255), nullable=False),
            sa.Column("subject", sa.String(length=500), nullable=False),
            sa.Column("body", sa.Text(), nullable=True),
            sa.Column("status", sa.String(length=30), nullable=False, server_default="PENDING"),
            sa.Column("error_message", sa.Text(), nullable=True),
            sa.Column("sent_at", sa.DateTime(timezone=True), nullable=True),
            sa.Column("related_module", sa.String(length=80), nullable=True),
            sa.Column("related_id", sa.Integer(), nullable=True),
            sa.Column("template_code", sa.String(length=80), nullable=True),
            sa.Column("provider_message_id", sa.String(length=255), nullable=True),
            sa.Column("created_at_utc", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()),
        )
        op.create_index("ix_email_logs_tenant_id", "email_logs", ["tenant_id"])
        op.create_index("ix_email_logs_branch_id", "email_logs", ["branch_id"])
        op.create_index("ix_email_logs_recipient_email", "email_logs", ["recipient_email"])
        op.create_index("ix_email_logs_status", "email_logs", ["status"])
        op.create_index("ix_email_logs_sent_at", "email_logs", ["sent_at"])
        op.create_index("ix_email_logs_related_module", "email_logs", ["related_module"])
        op.create_index("ix_email_logs_related_id", "email_logs", ["related_id"])
        op.create_index("ix_email_logs_template_code", "email_logs", ["template_code"])
        op.create_index("ix_email_logs_created_at_utc", "email_logs", ["created_at_utc"])


def downgrade() -> None:
    bind = op.get_bind()
    if _has_table(bind, "email_logs"):
        op.drop_table("email_logs")
    if _has_table(bind, "email_templates"):
        op.drop_table("email_templates")
    if _has_table(bind, "email_settings"):
        op.drop_table("email_settings")
