"""Tenant management service wrapping POS tenant_manager."""
import os
import sys
import psycopg2
from psycopg2 import sql
from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT

# Add POS to path so we can reuse tenant_manager
POS_DIR = os.environ.get("POS_DIR", "/home/Autopartes/pos")
if POS_DIR not in sys.path:
    sys.path.insert(0, POS_DIR)

from config import MASTER_DB_URL, TENANT_DB_URL_TEMPLATE, DEMO_DEFAULT_DAYS


def get_master_conn():
    return psycopg2.connect(MASTER_DB_URL)


def list_tenants(include_stats=False):
    """List all tenants with optional per-tenant stats."""
    conn = get_master_conn()
    cur = conn.cursor()
    cur.execute("""
        SELECT t.id, t.name, t.db_name, t.subdomain, t.rfc, t.plan, t.is_active,
               t.created_at, COALESCE(s.expires_at, NULL) as expires_at,
               COALESCE(v.version, 'v0.0') as schema_version
        FROM tenants t
        LEFT JOIN subscriptions s ON s.tenant_id = t.id
        LEFT JOIN tenant_schema_version v ON v.tenant_id = t.id
        ORDER BY t.id DESC
    """)
    cols = [desc[0] for desc in cur.description]
    tenants = []
    for row in cur.fetchall():
        tenant = dict(zip(cols, row))
        tenant["created_at"] = str(tenant["created_at"]) if tenant["created_at"] else None
        tenant["expires_at"] = str(tenant["expires_at"]) if tenant["expires_at"] else None
        tenant["is_demo"] = tenant["plan"] in ("demo", "trial")
        tenant["demo_days_left"] = None
        if tenant["expires_at"]:
            from datetime import datetime
            try:
                exp = datetime.fromisoformat(tenant["expires_at"].replace("Z", "+00:00"))
                now = datetime.now(exp.tzinfo) if exp.tzinfo else datetime.now()
                tenant["demo_days_left"] = max(0, (exp - now).days)
            except Exception:
                pass
        tenants.append(tenant)
    cur.close()
    conn.close()

    if include_stats:
        for t in tenants:
            t["stats"] = _get_tenant_quick_stats(t["db_name"])
    return tenants


def get_tenant(tenant_id):
    """Get single tenant details."""
    conn = get_master_conn()
    cur = conn.cursor()
    cur.execute("""
        SELECT t.id, t.name, t.db_name, t.subdomain, t.rfc, t.plan, t.is_active,
               t.created_at, COALESCE(s.expires_at, NULL) as expires_at,
               COALESCE(s.status, 'unknown') as subscription_status,
               COALESCE(v.version, 'v0.0') as schema_version
        FROM tenants t
        LEFT JOIN subscriptions s ON s.tenant_id = t.id
        LEFT JOIN tenant_schema_version v ON v.tenant_id = t.id
        WHERE t.id = %s
    """, (tenant_id,))
    row = cur.fetchone()
    cur.close()
    conn.close()
    if not row:
        return None
    keys = ["id", "name", "db_name", "subdomain", "rfc", "plan", "is_active",
            "created_at", "expires_at", "subscription_status", "schema_version"]
    return {k: str(v) if v is not None else None for k, v in zip(keys, row)}


def _get_tenant_quick_stats(db_name):
    """Quick stats for a tenant DB."""
    dsn = TENANT_DB_URL_TEMPLATE.format(db_name=db_name)
    try:
        conn = psycopg2.connect(dsn, connect_timeout=5)
        cur = conn.cursor()
        cur.execute("""
            SELECT
                (SELECT COUNT(*) FROM employees WHERE is_active = true),
                (SELECT COUNT(*) FROM inventory WHERE is_active = true),
                (SELECT COUNT(*) FROM customers WHERE is_active = true),
                (SELECT COUNT(*) FROM sales WHERE status = 'completed'),
                pg_database_size(current_database())
        """)
        emp, inv, cust, sales, size = cur.fetchone()
        cur.close()
        conn.close()
        return {
            "employees": emp,
            "inventory_items": inv,
            "customers": cust,
            "completed_sales": sales,
            "db_size_mb": round(size / (1024 * 1024), 2)
        }
    except Exception as e:
        return {"error": str(e)}


def create_demo(name, email, demo_days=None, subdomain=None, pin="0000"):
    """Provision a new demo tenant using POS tenant_manager."""
    from services.tenant_manager import provision_tenant
    from datetime import datetime, timedelta

    days = demo_days or DEMO_DEFAULT_DAYS
    if not subdomain:
        from services.tenant_manager import generate_subdomain
        subdomain = generate_subdomain(name)
        # Ensure uniqueness by appending random suffix if needed
        conn = get_master_conn()
        cur = conn.cursor()
        cur.execute("SELECT 1 FROM tenants WHERE subdomain = %s", (subdomain,))
        if cur.fetchone():
            import secrets
            subdomain = f"{subdomain}-{secrets.token_hex(2)}"
        cur.close()
        conn.close()

    result = provision_tenant(
        name=name,
        rfc=None,
        owner_name="Admin Demo",
        owner_email=email,
        owner_pin=pin,
        subdomain=subdomain
    )

    # Mark as demo plan and set expiration
    tenant_id = result["tenant_id"]
    conn = get_master_conn()
    cur = conn.cursor()
    cur.execute("UPDATE tenants SET plan = 'demo' WHERE id = %s", (tenant_id,))
    cur.execute("""
        INSERT INTO subscriptions (tenant_id, plan, status, expires_at)
        VALUES (%s, 'demo', 'active', %s)
        ON CONFLICT (tenant_id) DO UPDATE SET
            plan = 'demo',
            status = 'active',
            expires_at = EXCLUDED.expires_at
    """, (tenant_id, datetime.now() + timedelta(days=days)))
    conn.commit()
    cur.close()
    conn.close()

    # Auto-provision WhatsApp Bridge
    try:
        import urllib.request
        import json as _json
        from config import POS_INTERNAL_URL, INTERNAL_API_KEY
        bridge_payload = _json.dumps({
            "tenant_id": tenant_id,
            "subdomain": subdomain,
            "db_name": result["db_name"]
        }).encode()
        req = urllib.request.Request(
            f"{POS_INTERNAL_URL}/pos/api/internal/whatsapp-bridge",
            data=bridge_payload,
            headers={
                "Content-Type": "application/json",
                "X-Internal-Key": INTERNAL_API_KEY
            },
            method="POST"
        )
        with urllib.request.urlopen(req, timeout=30) as resp:
            bridge_data = _json.loads(resp.read().decode())
            result["whatsapp_bridge"] = bridge_data
    except Exception as e:
        result["whatsapp_bridge_error"] = str(e)

    result["demo_days"] = days
    result["expires_at"] = str(datetime.now() + timedelta(days=days))
    result["access_url"] = f"https://{subdomain}.nexusautoparts.com.mx/pos/login"
    result["owner_pin"] = pin
    return result


def reset_tenant(tenant_id, keep_config=True):
    """Reset a tenant: truncate business data but keep structure and owner."""
    tenant = get_tenant(tenant_id)
    if not tenant:
        raise ValueError("Tenant not found")
    db_name = tenant["db_name"]
    dsn = TENANT_DB_URL_TEMPLATE.format(db_name=db_name)

    tables_to_truncate = [
        "inventory_operations",
        "inventory",
        "sale_items",
        "sales",
        "customer_payments",
        "cash_register_closings",
        "cash_register_movements",
        "cash_registers",
        "invoices",
        "accounting_entries",
        "journal_entries",
        "service_orders",
        "fleet_vehicles",
        "crm_activities",
        "quotations",
        "quotation_items",
        "savings_transactions",
        "savings_accounts",
        "supplier_orders",
        "supplier_order_items",
        "warranty_claims",
        "notifications",
        "inventory_uploads",
    ]

    conn = psycopg2.connect(dsn)
    cur = conn.cursor()
    try:
        for table in tables_to_truncate:
            try:
                cur.execute(f"TRUNCATE TABLE {table} RESTART IDENTITY CASCADE")
            except Exception:
                pass  # Table may not exist
        conn.commit()
        success = True
    except Exception as e:
        conn.rollback()
        success = False
        raise RuntimeError(f"Reset failed: {e}")
    finally:
        cur.close()
        conn.close()

    return {"success": success, "tenant_id": tenant_id, "tables_reset": len(tables_to_truncate)}


def delete_tenant(tenant_id):
    """Permanently delete a tenant and its database."""
    tenant = get_tenant(tenant_id)
    if not tenant:
        raise ValueError("Tenant not found")
    db_name = tenant["db_name"]
    subdomain = tenant.get("subdomain") or f"tenant-{tenant_id}"

    # Destroy WhatsApp Bridge container
    try:
        import urllib.request
        import json as _json
        from config import POS_INTERNAL_URL, INTERNAL_API_KEY
        bridge_payload = _json.dumps({"subdomain": subdomain}).encode()
        req = urllib.request.Request(
            f"{POS_INTERNAL_URL}/pos/api/internal/whatsapp-bridge",
            data=bridge_payload,
            headers={
                "Content-Type": "application/json",
                "X-Internal-Key": INTERNAL_API_KEY
            },
            method="DELETE"
        )
        urllib.request.urlopen(req, timeout=15)
    except Exception:
        pass  # Bridge may not exist

    conn = get_master_conn()
    cur = conn.cursor()

    # Drop database
    try:
        master_conn = psycopg2.connect(MASTER_DB_URL)
        master_conn.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)
        master_cur = master_conn.cursor()
        master_cur.execute(
            sql.SQL('DROP DATABASE IF EXISTS {}').format(sql.Identifier(db_name))
        )
        master_cur.close()
        master_conn.close()
    except Exception as e:
        pass

    # Clean master records
    cur.execute("DELETE FROM tenant_schema_version WHERE tenant_id = %s", (tenant_id,))
    cur.execute("DELETE FROM subscriptions WHERE tenant_id = %s", (tenant_id,))
    cur.execute("DELETE FROM tenants WHERE id = %s", (tenant_id,))
    conn.commit()
    cur.close()
    conn.close()
    return {"success": True, "tenant_id": tenant_id, "db_name": db_name}


def toggle_tenant(tenant_id, active):
    """Activate or deactivate a tenant."""
    conn = get_master_conn()
    cur = conn.cursor()
    cur.execute("UPDATE tenants SET is_active = %s WHERE id = %s", (active, tenant_id))
    conn.commit()
    rowcount = cur.rowcount
    cur.close()
    conn.close()
    return {"success": rowcount > 0, "tenant_id": tenant_id, "is_active": active}


def get_tenant_login_url(subdomain):
    """Generate login URL for a tenant."""
    domain = os.environ.get("NEXUS_DOMAIN", "nexusautoparts.com.mx")
    return f"https://{subdomain}.{domain}/pos/login"


def get_tenant_modules(tenant_id):
    """Get enabled modules for a tenant from tenant_config."""
    tenant = get_tenant(tenant_id)
    if not tenant:
        raise ValueError("Tenant not found")
    db_name = tenant["db_name"]
    dsn = TENANT_DB_URL_TEMPLATE.format(db_name=db_name)
    conn = psycopg2.connect(dsn)
    cur = conn.cursor()
    try:
        modules = {}
        for key in ["module_whatsapp", "module_marketplace", "module_meli", "module_catalog"]:
            cur.execute("SELECT value FROM tenant_config WHERE key = %s", (key,))
            row = cur.fetchone()
            modules[key.replace("module_", "")] = (row[0] or "").lower() == "true" if row else True
        return modules
    finally:
        cur.close()
        conn.close()


def update_tenant_modules(tenant_id, modules):
    """Update enabled modules for a tenant in tenant_config."""
    tenant = get_tenant(tenant_id)
    if not tenant:
        raise ValueError("Tenant not found")
    db_name = tenant["db_name"]
    dsn = TENANT_DB_URL_TEMPLATE.format(db_name=db_name)
    conn = psycopg2.connect(dsn)
    cur = conn.cursor()
    try:
        key_map = {
            "whatsapp": "module_whatsapp",
            "marketplace": "module_marketplace",
            "meli": "module_meli",
            "catalog": "module_catalog",
        }
        for field, key in key_map.items():
            value = "true" if modules.get(field) else "false"
            cur.execute("""
                INSERT INTO tenant_config (key, value) VALUES (%s, %s)
                ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value
            """, (key, value))
        conn.commit()
        return {"success": True, "tenant_id": tenant_id, "modules": modules}
    finally:
        cur.close()
        conn.close()


def get_dashboard_stats():
    """Global stats for the manager dashboard."""
    conn = get_master_conn()
    cur = conn.cursor()

    cur.execute("SELECT COUNT(*) FROM tenants")
    total = cur.fetchone()[0]

    cur.execute("SELECT COUNT(*) FROM tenants WHERE is_active = true")
    active = cur.fetchone()[0]

    cur.execute("SELECT COUNT(*) FROM tenants WHERE plan = 'demo'")
    demos = cur.fetchone()[0]

    cur.execute("""
        SELECT COUNT(*) FROM subscriptions
        WHERE status = 'active' AND expires_at < NOW() + INTERVAL '7 days'
    """)
    expiring_soon = cur.fetchone()[0]

    cur.close()
    conn.close()

    # Get system health summary
    from services.health_service import check_disk_space, check_memory
    disk = check_disk_space()
    mem = check_memory()

    return {
        "tenants": {"total": total, "active": active, "demos": demos, "expiring_soon": expiring_soon},
        "system": {
            "disk_percent": disk.get("percent_used"),
            "memory_percent": mem.get("percent_used"),
            "disk_free_gb": disk.get("free_gb"),
            "memory_available_gb": mem.get("available_gb")
        }
    }
