from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles

from database import get_connection

from routers.tasks import router as tasks_router
from email_routes import router as email_router
from lead import router as lead_router
from calls import router as calls_router
from routers.performance import router as performance_router
from dashboard import router as dashboard
# =========================================================
# SSO / SECURITY IMPORTS
# =========================================================

import os
import time
import hmac
import hashlib
import base64
import secrets


app = FastAPI()


# =========================================================
# ENVIRONMENT
# =========================================================

HRMS_URL = os.getenv(
    "HRMS_URL",
    "https://hrms.kineticcosmos.in"
)

SSO_SECRET = os.getenv(
    "SSO_SECRET",
    "CHANGE_THIS_TO_A_LONG_RANDOM_SECRET"
)


# =========================================================
# CORS
# =========================================================

app.add_middleware(
    CORSMiddleware,

    allow_origins=[
        "http://localhost:5173",
        "http://127.0.0.1:5173",

        # Production CRM frontend
        "https://crm.kineticcosmos.in",
    ],

    allow_credentials=True,

    allow_methods=["*"],

    allow_headers=["*"],
)


# =========================================================
# STATIC RECORDINGS
# =========================================================

app.mount(
    "/recordings",
    StaticFiles(directory="recordings"),
    name="recordings"
)


# =========================================================
# ROUTERS
# =========================================================

app.include_router(
    tasks_router
)

app.include_router(
    email_router
)

app.include_router(
    lead_router
)

app.include_router(
    calls_router
)

app.include_router(
    performance_router
)
app.include_router(
    dashboard
)

# =========================================================
# CRM → HRMS SSO MODEL
# =========================================================

class SwitchHRMSRequest(BaseModel):
    employee_id: str


# =========================================================
# CRM → HRMS SSO
# =========================================================

@app.post("/auth/switch-to-hrms")
def switch_to_hrms(data: SwitchHRMSRequest):

    employee_id = data.employee_id.strip()

    # -----------------------------------------------------
    # Validate Employee ID
    # -----------------------------------------------------

    if not employee_id:

        raise HTTPException(
            status_code=400,
            detail="Employee ID is required"
        )

    conn = None
    cursor = None

    try:

        # -------------------------------------------------
        # Verify employee exists in CRM database
        # -------------------------------------------------

        conn = get_connection()

        cursor = conn.cursor(dictionary=True)

        # IMPORTANT:
        # Agar tumhare employees table ka naam/column
        # different hai to yahan uske according change karna.
        #
        # Common structure:
        # employees.employee_id

        cursor.execute(
            """
            SELECT
                employeeId
            FROM employees
            WHERE employeeId = %s
            LIMIT 1
            """,
            (employee_id,)
        )

        employee = cursor.fetchone()

        if not employee:

            raise HTTPException(
                status_code=404,
                detail="Employee not found"
            )

        # -------------------------------------------------
        # Create short-lived SSO payload
        # -------------------------------------------------

        expires_at = int(time.time()) + 300

        nonce = secrets.token_urlsafe(24)

        payload = (
            f"{employee_id}|"
            f"{expires_at}|"
            f"{nonce}"
        )

        # -------------------------------------------------
        # Create HMAC signature
        # -------------------------------------------------

        signature = hmac.new(
            SSO_SECRET.encode("utf-8"),
            payload.encode("utf-8"),
            hashlib.sha256
        ).hexdigest()

        # -------------------------------------------------
        # Encode payload
        # -------------------------------------------------

        token = base64.urlsafe_b64encode(
            payload.encode("utf-8")
        ).decode("utf-8").rstrip("=")

        # -------------------------------------------------
        # Create HRMS redirect URL
        # -------------------------------------------------

        redirect_url = (
            f"{HRMS_URL}/sso-login"
            f"?token={token}"
            f"&signature={signature}"
        )

        return {
            "success": True,
            "employee_id": employee_id,
            "redirect_url": redirect_url
        }

    except HTTPException:

        raise

    except Exception as e:

        print(
            "CRM → HRMS SSO ERROR:",
            e
        )

        raise HTTPException(
            status_code=500,
            detail="Unable to create HRMS SSO session"
        )

    finally:

        if cursor:
            cursor.close()

        if conn:
            conn.close()


# =========================================================
# ROOT
# =========================================================

@app.get("/")
def root():

    return {
        "status": "success",
        "message": "Kinetic CRM API running"
    }


# =========================================================
# TEST INTERNET
# =========================================================

@app.get("/test-internet")
def test_internet():

    import requests

    try:

        r = requests.get(
            "https://httpbin.org/get",
            timeout=10
        )

        return {
            "success": True,
            "status_code": r.status_code,
            "message": "External API connection working"
        }

    except Exception as e:

        return {
            "success": False,
            "error": str(e)
        }


# =========================================================
# CRM NOTIFICATIONS
# =========================================================

@app.get(
    "/crm-notifications/{employee_id}/unread-count"
)
def get_crm_unread_count(employee_id: str):

    conn = None
    cursor = None

    try:

        conn = get_connection()

        cursor = conn.cursor(
            dictionary=True
        )

        cursor.execute(
            """
            SELECT COUNT(*) AS count
            FROM crm_notifications
            WHERE employee_id = %s
            AND is_read = 0
            """,
            (employee_id,)
        )

        result = cursor.fetchone()

        return {
            "count": (
                result["count"]
                if result
                else 0
            )
        }

    except Exception as e:

        print(
            "CRM NOTIFICATION COUNT ERROR:",
            e
        )

        raise HTTPException(
            status_code=500,
            detail=str(e)
        )

    finally:

        if cursor:
            cursor.close()

        if conn:
            conn.close()


# =========================================================
# GET CRM NOTIFICATIONS
# =========================================================

@app.get(
    "/crm-notifications/{employee_id}"
)
def get_crm_notifications(employee_id: str):

    conn = None
    cursor = None

    try:

        conn = get_connection()

        cursor = conn.cursor(
            dictionary=True
        )

        cursor.execute(
            """
            SELECT
                id,
                employee_id,
                title,
                message,
                type,
                is_read,
                created_at
            FROM crm_notifications
            WHERE employee_id = %s
            AND is_read = 0
            ORDER BY created_at DESC
            """,
            (employee_id,)
        )

        notifications = cursor.fetchall()

        return notifications

    except Exception as e:

        print(
            "CRM NOTIFICATIONS ERROR:",
            e
        )

        raise HTTPException(
            status_code=500,
            detail=str(e)
        )

    finally:

        if cursor:
            cursor.close()

        if conn:
            conn.close()


# =========================================================
# MARK ONE CRM NOTIFICATION AS READ
# =========================================================

@app.put(
    "/crm-notifications/{notification_id}/read"
)
def mark_crm_notification_read(
    notification_id: int
):

    conn = None
    cursor = None

    try:

        conn = get_connection()

        cursor = conn.cursor()

        cursor.execute(
            """
            UPDATE crm_notifications
            SET is_read = 1
            WHERE id = %s
            """,
            (notification_id,)
        )

        conn.commit()

        return {
            "success": True
        }

    except Exception as e:

        if conn:
            conn.rollback()

        print(
            "CRM NOTIFICATION READ ERROR:",
            e
        )

        raise HTTPException(
            status_code=500,
            detail=str(e)
        )

    finally:

        if cursor:
            cursor.close()

        if conn:
            conn.close()


# =========================================================
# MARK ALL CRM NOTIFICATIONS AS READ
# =========================================================

@app.put(
    "/crm-notifications/{employee_id}/read-all"
)
def mark_all_crm_notifications_read(
    employee_id: str
):

    conn = None
    cursor = None

    try:

        conn = get_connection()

        cursor = conn.cursor()

        cursor.execute(
            """
            UPDATE crm_notifications
            SET is_read = 1
            WHERE employee_id = %s
            AND is_read = 0
            """,
            (employee_id,)
        )

        conn.commit()

        return {
            "success": True
        }

    except Exception as e:

        if conn:
            conn.rollback()

        print(
            "CRM NOTIFICATIONS READ ALL ERROR:",
            e
        )

        raise HTTPException(
            status_code=500,
            detail=str(e)
        )

    finally:

        if cursor:
            cursor.close()

        if conn:
            conn.close()