"""
AgencyHub - White-Label Platform for Agencies.
Features: multi-workspace, white-label branding, auto-reports,
RBAC, content approval workflows, client onboarding, SLA monitoring.
"""

import json
import logging
import uuid
from datetime import datetime, timedelta
from collections import Counter, defaultdict

from sqlalchemy.orm import Session
from sqlalchemy import func, desc

from backend.models.video import Video
from backend.models.creator import Creator

logger = logging.getLogger(__name__)

# In-memory storage
_workspaces = {}
_team_members = {}
_approval_queue = {}
_reports = {}
_onboarding = {}

# Default roles
ROLES = {
    "owner": {"permissions": ["all"], "label": "Proprietario"},
    "admin": {"permissions": ["read", "write", "delete", "approve", "invite", "reports"], "label": "Administrador"},
    "manager": {"permissions": ["read", "write", "approve", "reports"], "label": "Gerente"},
    "editor": {"permissions": ["read", "write"], "label": "Editor"},
    "viewer": {"permissions": ["read"], "label": "Visualizador"},
    "client": {"permissions": ["read", "reports"], "label": "Cliente"},
}


# ── Workspace Management ──────────────────────────────────────

def create_workspace(name: str, client_name: str = "", branding: dict = None,
                      plan: str = "pro") -> dict:
    """Create a new workspace for a client/channel."""
    workspace_id = str(uuid.uuid4())[:8]
    _workspaces[workspace_id] = {
        "id": workspace_id,
        "name": name,
        "client_name": client_name,
        "plan": plan,
        "branding": branding or {
            "logo_url": "",
            "primary_color": "#7C3AED",
            "secondary_color": "#06B6D4",
            "company_name": name,
            "footer_text": "",
        },
        "channels": [],
        "team": [],
        "status": "active",
        "created_at": datetime.utcnow().isoformat(),
        "settings": {
            "approval_required": True,
            "auto_reports": True,
            "report_frequency": "weekly",
            "sla_response_hours": 24,
            "timezone": "America/Sao_Paulo",
        },
        "stats": {
            "total_posts": 0,
            "total_views": 0,
            "total_engagement": 0,
        },
    }
    return _workspaces[workspace_id]


def list_workspaces(status: str = "") -> list:
    """List all workspaces."""
    workspaces = list(_workspaces.values())
    if status:
        workspaces = [w for w in workspaces if w["status"] == status]
    workspaces.sort(key=lambda x: x["created_at"], reverse=True)
    return workspaces


def get_workspace(workspace_id: str) -> dict:
    """Get workspace details."""
    return _workspaces.get(workspace_id, {"error": "Workspace nao encontrado"})


def update_workspace(workspace_id: str, **kwargs) -> dict:
    """Update workspace settings."""
    if workspace_id not in _workspaces:
        return {"error": "Workspace nao encontrado"}
    ws = _workspaces[workspace_id]
    for k, v in kwargs.items():
        if k in ws and k not in ("id", "created_at"):
            ws[k] = v
    return ws


def delete_workspace(workspace_id: str) -> bool:
    """Delete a workspace."""
    return _workspaces.pop(workspace_id, None) is not None


def add_channel_to_workspace(workspace_id: str, platform: str, username: str,
                               channel_url: str = "") -> dict:
    """Add a social media channel to a workspace."""
    if workspace_id not in _workspaces:
        return {"error": "Workspace nao encontrado"}
    channel = {
        "id": str(uuid.uuid4())[:8],
        "platform": platform,
        "username": username,
        "url": channel_url,
        "added_at": datetime.utcnow().isoformat(),
        "status": "active",
    }
    _workspaces[workspace_id]["channels"].append(channel)
    return channel


# ── White-Label Branding ──────────────────────────────────────

def update_branding(workspace_id: str, logo_url: str = "", primary_color: str = "",
                     secondary_color: str = "", company_name: str = "",
                     footer_text: str = "") -> dict:
    """Update white-label branding for a workspace."""
    if workspace_id not in _workspaces:
        return {"error": "Workspace nao encontrado"}

    branding = _workspaces[workspace_id]["branding"]
    if logo_url:
        branding["logo_url"] = logo_url
    if primary_color:
        branding["primary_color"] = primary_color
    if secondary_color:
        branding["secondary_color"] = secondary_color
    if company_name:
        branding["company_name"] = company_name
    if footer_text:
        branding["footer_text"] = footer_text

    return branding


def get_branding(workspace_id: str) -> dict:
    """Get workspace branding."""
    ws = _workspaces.get(workspace_id)
    if not ws:
        return {"error": "Workspace nao encontrado"}
    return ws["branding"]


# ── Team Management (RBAC) ───────────────────────────────────

def invite_team_member(workspace_id: str, email: str, name: str = "",
                        role: str = "editor") -> dict:
    """Invite a team member to a workspace."""
    if workspace_id not in _workspaces:
        return {"error": "Workspace nao encontrado"}
    if role not in ROLES:
        return {"error": f"Role invalida. Opcoes: {', '.join(ROLES.keys())}"}

    member_id = str(uuid.uuid4())[:8]
    member = {
        "id": member_id,
        "workspace_id": workspace_id,
        "email": email,
        "name": name,
        "role": role,
        "permissions": ROLES[role]["permissions"],
        "status": "invited",
        "invited_at": datetime.utcnow().isoformat(),
        "last_active": None,
    }
    _team_members[member_id] = member
    _workspaces[workspace_id]["team"].append(member_id)
    return member


def list_team_members(workspace_id: str) -> list:
    """List all team members in a workspace."""
    if workspace_id not in _workspaces:
        return []
    member_ids = _workspaces[workspace_id].get("team", [])
    return [_team_members[mid] for mid in member_ids if mid in _team_members]


def update_member_role(member_id: str, role: str) -> dict:
    """Update a team member's role."""
    if member_id not in _team_members:
        return {"error": "Membro nao encontrado"}
    if role not in ROLES:
        return {"error": f"Role invalida. Opcoes: {', '.join(ROLES.keys())}"}
    _team_members[member_id]["role"] = role
    _team_members[member_id]["permissions"] = ROLES[role]["permissions"]
    return _team_members[member_id]


def remove_team_member(workspace_id: str, member_id: str) -> bool:
    """Remove a team member from workspace."""
    if workspace_id in _workspaces:
        _workspaces[workspace_id]["team"] = [
            m for m in _workspaces[workspace_id]["team"] if m != member_id
        ]
    return _team_members.pop(member_id, None) is not None


def check_permission(member_id: str, action: str) -> bool:
    """Check if a member has permission for an action."""
    member = _team_members.get(member_id)
    if not member:
        return False
    perms = member.get("permissions", [])
    return "all" in perms or action in perms


def get_available_roles() -> dict:
    """Get all available roles and their permissions."""
    return ROLES


# ── Content Approval Workflows ───────────────────────────────

def submit_for_approval(workspace_id: str, content_type: str, content: dict,
                          submitted_by: str = "") -> dict:
    """Submit content for approval."""
    if workspace_id not in _workspaces:
        return {"error": "Workspace nao encontrado"}

    approval_id = str(uuid.uuid4())[:8]
    _approval_queue[approval_id] = {
        "id": approval_id,
        "workspace_id": workspace_id,
        "content_type": content_type,  # post, script, video, report
        "content": content,
        "submitted_by": submitted_by,
        "submitted_at": datetime.utcnow().isoformat(),
        "status": "pending",  # pending, approved, rejected, revision_requested
        "reviewed_by": None,
        "reviewed_at": None,
        "feedback": "",
        "revision_count": 0,
    }
    return _approval_queue[approval_id]


def list_approvals(workspace_id: str = "", status: str = "") -> list:
    """List approval queue items."""
    items = list(_approval_queue.values())
    if workspace_id:
        items = [i for i in items if i["workspace_id"] == workspace_id]
    if status:
        items = [i for i in items if i["status"] == status]
    items.sort(key=lambda x: x["submitted_at"], reverse=True)
    return items


def review_approval(approval_id: str, action: str, reviewer: str = "",
                     feedback: str = "") -> dict:
    """Review an approval item. Actions: approve, reject, revision_requested."""
    if approval_id not in _approval_queue:
        return {"error": "Aprovacao nao encontrada"}
    if action not in ("approved", "rejected", "revision_requested"):
        return {"error": "Acao invalida. Use: approved, rejected, revision_requested"}

    item = _approval_queue[approval_id]
    item["status"] = action
    item["reviewed_by"] = reviewer
    item["reviewed_at"] = datetime.utcnow().isoformat()
    item["feedback"] = feedback
    if action == "revision_requested":
        item["revision_count"] += 1
    return item


# ── Auto-Generated Reports ───────────────────────────────────

async def generate_workspace_report(workspace_id: str, db: Session,
                                      period: str = "weekly") -> dict:
    """Generate an auto report for a workspace."""
    from backend.services.local_ai import llm_chat

    ws = _workspaces.get(workspace_id)
    if not ws:
        return {"error": "Workspace nao encontrado"}

    days = {"daily": 1, "weekly": 7, "monthly": 30}.get(period, 7)
    since = datetime.utcnow() - timedelta(days=days)

    # Get videos for workspace channels
    usernames = [ch["username"] for ch in ws.get("channels", [])]
    videos = []
    if usernames:
        videos = (
            db.query(Video)
            .filter(Video.collected_at >= since,
                    Video.creator_username.in_(usernames))
            .order_by(desc(Video.views))
            .limit(100)
            .all()
        )

    total_views = sum(v.views or 0 for v in videos)
    total_likes = sum(v.likes or 0 for v in videos)
    total_comments = sum(v.comments or 0 for v in videos)
    total_shares = sum(v.shares or 0 for v in videos)

    top_videos = [
        {"title": v.title[:50], "views": v.views, "likes": v.likes, "platform": v.platform}
        for v in videos[:5]
    ]

    # Platform breakdown
    platform_stats = defaultdict(lambda: {"videos": 0, "views": 0, "likes": 0})
    for v in videos:
        p = v.platform or "other"
        platform_stats[p]["videos"] += 1
        platform_stats[p]["views"] += v.views or 0
        platform_stats[p]["likes"] += v.likes or 0

    # AI narrative
    ai_narrative = ""
    try:
        system = "Voce e um social media manager profissional. Escreva um relatorio executivo em portugues, maximo 200 palavras."
        prompt = f"""Relatorio {period} do workspace '{ws['name']}':
- Videos: {len(videos)}
- Views: {total_views:,}
- Likes: {total_likes:,}
- Comentarios: {total_comments:,}
- Shares: {total_shares:,}
- Top video: {top_videos[0]['title'] if top_videos else 'N/A'} ({top_videos[0]['views']:,} views)

Escreva um resumo executivo com destaques e recomendacoes."""
        ai_narrative = await llm_chat(prompt, system=system, temperature=0.3, max_tokens=600)
    except Exception as e:
        logger.error(f"Report AI narrative error: {e}")

    report = {
        "id": str(uuid.uuid4())[:8],
        "workspace_id": workspace_id,
        "workspace_name": ws["name"],
        "period": period,
        "days": days,
        "generated_at": datetime.utcnow().isoformat(),
        "metrics": {
            "total_videos": len(videos),
            "total_views": total_views,
            "total_likes": total_likes,
            "total_comments": total_comments,
            "total_shares": total_shares,
            "engagement_rate": round(
                (total_likes + total_comments) / max(total_views, 1) * 100, 2
            ),
        },
        "top_videos": top_videos,
        "platform_breakdown": dict(platform_stats),
        "ai_narrative": ai_narrative or "Narrativa indisponivel.",
        "branding": ws.get("branding", {}),
    }

    _reports[report["id"]] = report
    return report


def list_reports(workspace_id: str = "", limit: int = 20) -> list:
    """List generated reports."""
    reports = list(_reports.values())
    if workspace_id:
        reports = [r for r in reports if r["workspace_id"] == workspace_id]
    reports.sort(key=lambda x: x["generated_at"], reverse=True)
    return reports[:limit]


def get_report(report_id: str) -> dict:
    """Get a specific report."""
    return _reports.get(report_id, {"error": "Relatorio nao encontrado"})


# ── Client Onboarding ────────────────────────────────────────

def start_onboarding(workspace_id: str, client_name: str, client_email: str = "",
                      channels: list = None, goals: list = None) -> dict:
    """Start a client onboarding process."""
    if workspace_id not in _workspaces:
        return {"error": "Workspace nao encontrado"}

    onboarding_id = str(uuid.uuid4())[:8]
    steps = [
        {"step": 1, "name": "Criar workspace", "status": "completed"},
        {"step": 2, "name": "Configurar branding", "status": "pending"},
        {"step": 3, "name": "Conectar canais sociais", "status": "pending"},
        {"step": 4, "name": "Convidar equipe", "status": "pending"},
        {"step": 5, "name": "Definir metas e KPIs", "status": "pending"},
        {"step": 6, "name": "Configurar relatorios automaticos", "status": "pending"},
        {"step": 7, "name": "Primeiro relatorio gerado", "status": "pending"},
    ]

    if channels:
        for ch in channels:
            add_channel_to_workspace(workspace_id, ch.get("platform", ""), ch.get("username", ""))
        steps[2]["status"] = "completed"

    _onboarding[onboarding_id] = {
        "id": onboarding_id,
        "workspace_id": workspace_id,
        "client_name": client_name,
        "client_email": client_email,
        "goals": goals or [],
        "steps": steps,
        "progress": sum(1 for s in steps if s["status"] == "completed") / len(steps) * 100,
        "started_at": datetime.utcnow().isoformat(),
        "completed_at": None,
    }
    return _onboarding[onboarding_id]


def update_onboarding_step(onboarding_id: str, step_number: int,
                             status: str = "completed") -> dict:
    """Update an onboarding step status."""
    if onboarding_id not in _onboarding:
        return {"error": "Onboarding nao encontrado"}
    ob = _onboarding[onboarding_id]
    for step in ob["steps"]:
        if step["step"] == step_number:
            step["status"] = status
            break
    ob["progress"] = round(
        sum(1 for s in ob["steps"] if s["status"] == "completed") / len(ob["steps"]) * 100, 1
    )
    if ob["progress"] >= 100:
        ob["completed_at"] = datetime.utcnow().isoformat()
    return ob


def get_onboarding(onboarding_id: str) -> dict:
    """Get onboarding status."""
    return _onboarding.get(onboarding_id, {"error": "Onboarding nao encontrado"})


def list_onboardings(workspace_id: str = "") -> list:
    """List onboarding processes."""
    items = list(_onboarding.values())
    if workspace_id:
        items = [i for i in items if i["workspace_id"] == workspace_id]
    return items


# ── SLA Monitoring ────────────────────────────────────────────

def check_sla_compliance(workspace_id: str) -> dict:
    """Check SLA compliance for a workspace."""
    ws = _workspaces.get(workspace_id)
    if not ws:
        return {"error": "Workspace nao encontrado"}

    settings = ws.get("settings", {})
    sla_hours = settings.get("sla_response_hours", 24)

    # Check approval queue response times
    approvals = [a for a in _approval_queue.values() if a["workspace_id"] == workspace_id]
    pending = [a for a in approvals if a["status"] == "pending"]

    now = datetime.utcnow()
    overdue = []
    for a in pending:
        submitted = datetime.fromisoformat(a["submitted_at"])
        hours_waiting = (now - submitted).total_seconds() / 3600
        if hours_waiting > sla_hours:
            overdue.append({
                "approval_id": a["id"],
                "content_type": a["content_type"],
                "hours_overdue": round(hours_waiting - sla_hours, 1),
                "submitted_by": a["submitted_by"],
            })

    # Calculate compliance rate
    reviewed = [a for a in approvals if a["status"] != "pending"]
    compliant = 0
    for a in reviewed:
        if a["reviewed_at"] and a["submitted_at"]:
            submitted = datetime.fromisoformat(a["submitted_at"])
            reviewed_at = datetime.fromisoformat(a["reviewed_at"])
            hours = (reviewed_at - submitted).total_seconds() / 3600
            if hours <= sla_hours:
                compliant += 1

    compliance_rate = (compliant / max(len(reviewed), 1)) * 100

    return {
        "workspace_id": workspace_id,
        "sla_hours": sla_hours,
        "compliance_rate": round(compliance_rate, 1),
        "pending_approvals": len(pending),
        "overdue_items": overdue,
        "overdue_count": len(overdue),
        "total_reviewed": len(reviewed),
        "label": "Conforme" if compliance_rate >= 90 else "Atencao" if compliance_rate >= 70 else "Critico",
    }


# ── Agency Stats ──────────────────────────────────────────────

def get_agency_stats() -> dict:
    """Get overall agency statistics."""
    workspaces = list(_workspaces.values())
    active = [w for w in workspaces if w["status"] == "active"]
    members = list(_team_members.values())
    approvals = list(_approval_queue.values())
    reports = list(_reports.values())

    return {
        "workspaces": {
            "total": len(workspaces),
            "active": len(active),
            "total_channels": sum(len(w.get("channels", [])) for w in workspaces),
        },
        "team": {
            "total_members": len(members),
            "by_role": dict(Counter(m["role"] for m in members)),
        },
        "approvals": {
            "total": len(approvals),
            "pending": sum(1 for a in approvals if a["status"] == "pending"),
            "approved": sum(1 for a in approvals if a["status"] == "approved"),
            "rejected": sum(1 for a in approvals if a["status"] == "rejected"),
        },
        "reports": {
            "total_generated": len(reports),
        },
        "onboardings": {
            "total": len(_onboarding),
            "completed": sum(1 for o in _onboarding.values() if o.get("completed_at")),
            "in_progress": sum(1 for o in _onboarding.values() if not o.get("completed_at")),
        },
    }
