"""initial_full_schema

Renames legacy tables to *_legacy backup, then creates
all tables with correct UUID PKs, types, and constraints.

Revision ID: 0001
Revises:
Create Date: 2026-02-24
"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa

revision: str = "0001"
down_revision: Union[str, None] = None
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None

# Legacy tables to rename (preserve data)
LEGACY_TABLES = ["users", "clients", "follow_ups", "expenses"]


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

    # Step 1: Rename legacy tables to *_legacy
    for table in LEGACY_TABLES:
        exists = conn.execute(sa.text(
            f"SELECT EXISTS (SELECT 1 FROM information_schema.tables "
            f"WHERE table_schema='public' AND table_name='{table}')"
        )).scalar()
        if exists:
            conn.execute(sa.text(
                f'ALTER TABLE "{table}" RENAME TO "{table}_legacy"'
            ))

    # Step 2: Create new tables with proper schema

    # ---- users ----
    conn.execute(sa.text("""
        CREATE TABLE users (
            id UUID PRIMARY KEY,
            username VARCHAR(50) UNIQUE NOT NULL,
            password_hash VARCHAR(128) NOT NULL,
            role VARCHAR(20) NOT NULL DEFAULT 'viewer',
            permissions JSON DEFAULT '[]',
            is_active BOOLEAN DEFAULT true,
            created_at TIMESTAMP DEFAULT now(),
            updated_at TIMESTAMP DEFAULT now()
        );
    """))

    # ---- clients ----
    conn.execute(sa.text("""
        CREATE TABLE clients (
            id UUID PRIMARY KEY,
            name VARCHAR(200) NOT NULL,
            contact_person VARCHAR(100),
            phone VARCHAR(30),
            address VARCHAR(500),
            notes TEXT,
            created_at TIMESTAMP DEFAULT now(),
            updated_at TIMESTAMP DEFAULT now()
        );
    """))
    conn.execute(sa.text(
        "CREATE INDEX ix_clients_name ON clients (name);"
    ))

    # ---- customer_logs ----
    conn.execute(sa.text("""
        CREATE TABLE customer_logs (
            id UUID PRIMARY KEY,
            customer_id UUID NOT NULL REFERENCES clients(id) ON DELETE CASCADE,
            content TEXT NOT NULL,
            created_at TIMESTAMP DEFAULT now()
        );
    """))
    conn.execute(sa.text(
        "CREATE INDEX ix_customer_logs_cid ON customer_logs (customer_id);"
    ))

    # ---- customer_tags ----
    conn.execute(sa.text("""
        CREATE TABLE customer_tags (
            id UUID PRIMARY KEY,
            customer_id UUID NOT NULL REFERENCES clients(id) ON DELETE CASCADE,
            tag_name VARCHAR(100) NOT NULL,
            created_at TIMESTAMP DEFAULT now()
        );
    """))
    conn.execute(sa.text(
        "CREATE INDEX ix_customer_tags_cid ON customer_tags (customer_id);"
    ))

    # ---- follow_up_todos ----
    conn.execute(sa.text("""
        CREATE TABLE follow_up_todos (
            id UUID PRIMARY KEY,
            customer_id UUID NOT NULL REFERENCES clients(id) ON DELETE CASCADE,
            task_desc TEXT NOT NULL,
            status VARCHAR(20) NOT NULL DEFAULT 'pending',
            created_at TIMESTAMP DEFAULT now()
        );
    """))
    conn.execute(sa.text(
        "CREATE INDEX ix_follow_up_todos_cid ON follow_up_todos (customer_id);"
    ))

    # ---- sales_opportunities ----
    conn.execute(sa.text("""
        CREATE TABLE sales_opportunities (
            id UUID PRIMARY KEY,
            customer_id UUID NOT NULL REFERENCES clients(id) ON DELETE CASCADE,
            amount NUMERIC(12, 2) NOT NULL DEFAULT 0,
            stage VARCHAR(20) NOT NULL DEFAULT 'intent',
            created_at TIMESTAMP DEFAULT now()
        );
    """))
    conn.execute(sa.text(
        "CREATE INDEX ix_sales_opp_cid ON sales_opportunities (customer_id);"
    ))


def downgrade() -> None:
    conn = op.get_bind()

    # Drop new tables
    for t in ["sales_opportunities", "follow_up_todos", "customer_tags",
              "customer_logs", "clients", "users"]:
        conn.execute(sa.text(f'DROP TABLE IF EXISTS "{t}" CASCADE'))

    # Restore legacy tables
    for table in LEGACY_TABLES:
        exists = conn.execute(sa.text(
            f"SELECT EXISTS (SELECT 1 FROM information_schema.tables "
            f"WHERE table_schema='public' AND table_name='{table}_legacy')"
        )).scalar()
        if exists:
            conn.execute(sa.text(
                f'ALTER TABLE "{table}_legacy" RENAME TO "{table}"'
            ))
