import json
import requests
import traceback
import logging
import time
from django.conf import settings
from django.db.models import Count, Q
from django.utils import timezone
from companies.models import Company
from subscriptions.models import SaasMarketingLog
from core.email_utils import _render_email_html, _make_email, _send_in_background

logger = logging.getLogger(__name__)

SUPERADMIN_AI_TOOLS = [
    {
        "type": "function",
        "function": {
            "name": "get_companies_by_segment",
            "description": "Get details of companies matching a specific platform segment: 'inactive' (registered but 0 completed sales), 'expired_trial' (trial expired, did not subscribe to paid plan), 'active_paid' (paid subscription), or 'all' (all registered companies).",
            "parameters": {
                "type": "object",
                "properties": {
                    "segment": {
                        "type": "string",
                        "enum": ["inactive", "expired_trial", "active_paid", "all"],
                        "description": "The segment type to retrieve"
                    }
                },
                "required": ["segment"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "send_group_emails",
            "description": "Send a targeted campaign email to a list of company slugs. Pass the list of slugs, subject line, and the email body text formatted in clean HTML.",
            "parameters": {
                "type": "object",
                "properties": {
                    "company_slugs": {
                        "type": "array",
                        "items": {"type": "string"},
                        "description": "List of company slugs to target"
                    },
                    "subject": {
                        "type": "string",
                        "description": "Subject line of the email"
                    },
                    "html_body": {
                        "type": "string",
                        "description": "Email content in clean, light-themed HTML formatting (no dark backgrounds, simple formatting)."
                    }
                },
                "required": ["company_slugs", "subject", "html_body"]
            }
        }
    }
]


def get_companies_by_segment(segment):
    """Query companies belonging to a targeted segment."""
    today = timezone.now().date()
    
    if segment == 'inactive':
        # Created, but has 0 completed POS orders
        companies = Company.objects.annotate(
            order_count=Count('orders', filter=Q(orders__status='completed'))
        ).filter(order_count=0)
    elif segment == 'expired_trial':
        # Trial expired
        companies = Company.objects.filter(
            plan__name__icontains='trial'
        ).filter(
            Q(is_active=False) | Q(expiry_date__lt=today)
        )
    elif segment == 'active_paid':
        # Active paid plans
        companies = Company.objects.filter(
            is_active=True
        ).exclude(plan__name__icontains='trial')
    else:
        companies = Company.objects.all()

    results = []
    for c in companies.select_related('plan').order_by('-created_at')[:80]:
        admin_user = c.users.filter(role='admin').first()
        admin_email = None
        if admin_user:
            admin_email = admin_user.email
        if not admin_email:
            admin_email = c.email
        
        # Calculate total orders
        orders_count = c.orders.filter(status='completed').count()
        
        results.append({
            'name': c.name,
            'slug': c.slug,
            'email': admin_email or 'No email found',
            'plan': c.plan.name if c.plan else 'None',
            'created_at': c.created_at.strftime('%Y-%m-%d') if c.created_at else 'N/A',
            'is_active': c.is_active,
            'expiry_date': str(c.expiry_date) if c.expiry_date else 'N/A',
            'orders_count': orders_count
        })
    return json.dumps(results)


def send_group_emails(company_slugs, subject, html_body):
    """Send target emails in the background and log inside SaasMarketingLog."""
    # Ensure company_slugs is parsed correctly
    if isinstance(company_slugs, str):
        clean_slugs = company_slugs.strip("[]'\" ")
        if ',' in clean_slugs:
            company_slugs = [s.strip(" '\"") for s in clean_slugs.split(',')]
        else:
            company_slugs = [clean_slugs] if clean_slugs else []
    
    if not isinstance(company_slugs, (list, tuple)):
        company_slugs = [company_slugs] if company_slugs else []

    cleaned_slugs = []
    for s in company_slugs:
        if s:
            cleaned_slugs.append(str(s).strip(" '\"[]"))
    company_slugs = cleaned_slugs

    sent_to = []
    campaign_key = f"superadmin_campaign_{int(time.time())}"
    
    for slug in company_slugs:
        try:
            # Robust company resolution (matching direct slug, case-insensitive, name, or slugify)
            c = None
            try:
                c = Company.objects.get(slug=slug)
            except Company.DoesNotExist:
                try:
                    c = Company.objects.get(slug__iexact=slug)
                except Company.DoesNotExist:
                    try:
                        c = Company.objects.get(name__iexact=slug)
                    except Company.DoesNotExist:
                        try:
                            c = Company.objects.get(name__iexact=slug.replace('-', ' '))
                        except Company.DoesNotExist:
                            # Try slugifying existing names to find a match
                            from django.utils.text import slugify
                            for comp in Company.objects.all():
                                if slugify(comp.name) == slugify(slug):
                                    c = comp
                                    break
            
            if not c:
                raise Company.DoesNotExist(f"Company matching slug/name '{slug}' not found.")

            admin_user = c.users.filter(role='admin').first()
            recipient = None
            if admin_user:
                recipient = admin_user.email
            if not recipient:
                recipient = c.email
            
            if not recipient:
                logger.warning(f"No recipient email found for company '{c.name}'")
                continue

            # Render HTML body inside light brand template
            rendered_html = _render_email_html(
                company_name=c.name,
                title=subject,
                body_html=html_body,
            )

            # Plain text version for fallback clients
            from django.utils.html import strip_tags
            text_body = strip_tags(html_body)

            # Build MIME email and trigger background dispatch
            msg = _make_email(subject, text_body, rendered_html, [recipient])
            _send_in_background(msg.send, fail_silently=False)

            # Log this action
            SaasMarketingLog.objects.create(
                company=c,
                email_key=campaign_key,
                subject=subject
            )
            sent_to.append({
                "slug": c.slug,
                "name": c.name,
                "email": recipient
            })
        except Exception as ex:
            logger.error(f"Error sending campaign email to company '{slug}': {ex}")

    return json.dumps({
        "status": "ok",
        "sent_count": len(sent_to),
        "recipients": sent_to,
        "campaign_key": campaign_key
    })


def call_superadmin_llm(user_prompt, history):
    """
    Superadmin AI endpoint to draft and dispatch emails.
    Returns a tuple of (content, updated_history)
    """
    base_url = getattr(settings, 'AI_API_URL', 'https://openrouter.ai/api/v1').rstrip('/')
    url = f"{base_url}/chat/completions"
    api_key = getattr(settings, 'AI_API_KEY', '')
    model = getattr(settings, 'AI_API_MODEL', 'minimax/minimax-m2.5:free')

    if not api_key:
        return "AI API Key is not configured in settings.", history

    current_time = timezone.now()

    # System prompt specifically tailored for platform operations
    system_prompt = (
        "You are the SwiftPOS Platform Superadmin Marketing Assistant.\n"
        "Your task is to help the platform superadmin segment tenant companies and send emails/onboarding follow-ups.\n\n"
        "STRICT DESIGN & BRADING RULES:\n"
        "- All email bodies you draft must follow a clean, premium light-themed brand design. No dark mode layouts ('no dark shit').\n"
        "- Format HTML cleanly using simple tags: paragraphs (<p>), bold (<strong>), line breaks (<br>), lists (<ul>/<li>), or custom buttons.\n"
        "- Use clean, encouraging tone suitable for Nigerian business owners.\n\n"
        "STRICT SPAM PREVENTION RULES FOR SUBJECT AND BODY:\n"
        "- The email subject and body must NOT contain spam-trigger words that cause mail servers to discard them (SMTP 550 spam errors).\n"
        "- NEVER use spammy words in the subject line. Avoid: 'Urgent', 'Congratulations', 'Guaranteed', 'Winner', '100% Free', 'Offer', 'Upgrade Now', 'Special Discount', 'Promo', 'Buy Now', 'Cash', 'Earn', 'Deal', 'Risk-free', or similar buzzwords.\n"
        "- Avoid exclamation marks and all-caps words in subject lines.\n"
        "- Subject lines must sound natural, professional, and transactional (e.g., 'SwiftPOS: Welcome to your new workspace', 'Quick question about your SwiftPOS retail store', 'Setting up your point-of-sale terminal').\n"
        "- The email body must be helpful, informative, conversational, and direct. Avoid sounding like a pushy sales pitch.\n\n"
        "HOW TO PERFORM OUTREACH:\n"
        "1. The superadmin will describe a group (e.g. 'find companies with no sales' or 'find expired trials').\n"
        "2. Call `get_companies_by_segment` to fetch their details first.\n"
        "3. Draft a professional email content. Present the draft content to the superadmin along with the list of targeted companies.\n"
        "4. Ask for confirmation before sending. Do NOT call `send_group_emails` until the admin explicitly says to send it or confirms the draft.\n"
        "5. Once confirmed, invoke `send_group_emails` with the list of company slugs, subject, and clean HTML body.\n"
        "6. In your final confirmation message to the superadmin, ALWAYS clearly write out the company name, slug, and the exact email address of every company to which the email was successfully sent (e.g., 'Sent to: Company Name (slug) - email@domain.com'). Do not omit any email addresses, so the superadmin can verify them.\n\n"
        f"CURRENT DATE AND TIME: {current_time.strftime('%A, %B %d, %Y %I:%M %p')}\n"
    )

    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json",
        "HTTP-Referer": "https://app.swiftpos.ng",
        "X-Title": "SwiftPOS Superadmin"
    }

    # Reconstruct conversation history
    messages = [{"role": "system", "content": system_prompt}]
    for msg in history:
        messages.append(msg)
    
    # Add new user prompt
    messages.append({"role": "user", "content": user_prompt})

    def _call_api(msgs):
        payload = {
            "model": model,
            "messages": msgs,
            "tools": SUPERADMIN_AI_TOOLS,
            "tool_choice": "auto"
        }
        res = requests.post(url, headers=headers, json=payload, timeout=30)
        res.raise_for_status()
        return res.json()

    try:
        data = _call_api(messages)
        message_obj = data["choices"][0]["message"]

        # Process tool calls
        if message_obj.get("tool_calls"):
            messages.append(message_obj)
            for tool_call in message_obj["tool_calls"]:
                func_name = tool_call["function"]["name"]
                args = json.loads(tool_call["function"]["arguments"])

                result = {"error": "Function not found"}
                try:
                    if func_name == "get_companies_by_segment":
                        result = get_companies_by_segment(args.get("segment"))
                    elif func_name == "send_group_emails":
                        result = send_group_emails(
                            args.get("company_slugs"),
                            args.get("subject"),
                            args.get("html_body")
                        )
                except Exception as ex:
                    logger.error(f"Superadmin Tool call error: {traceback.format_exc()}")
                    result = json.dumps({"error": str(ex)})

                messages.append({
                    "role": "tool",
                    "tool_call_id": tool_call["id"],
                    "name": func_name,
                    "content": str(result)
                })

            # Call API with tool results
            data2 = _call_api(messages)
            final_message_obj = data2["choices"][0]["message"]
            messages.append(final_message_obj)
            content = final_message_obj.get("content") or ""
            return content.strip(), messages[1:]

        else:
            messages.append(message_obj)
            content = message_obj.get("content") or ""
            return content.strip(), messages[1:]

    except requests.exceptions.RequestException as e:
        return f"Unable to reach the AI server. (Error: {str(e)})", history
    except Exception as e:
        logger.error(f"Superadmin AI Error: {traceback.format_exc()}")
        return f"An internal error occurred: {str(e)}", history
