"""
Reminder API Endpoints for Sag Module
CRUD operations, user preferences, snooze/dismiss functionality
"""

import logging
from typing import List, Optional
from datetime import datetime, timedelta
from fastapi import APIRouter, HTTPException, status, Depends, Request
from pydantic import BaseModel, Field

from app.core.database import execute_query, execute_insert
from app.services.reminder_notification_service import reminder_notification_service

logger = logging.getLogger(__name__)

router = APIRouter()


# ============================================================================
# Helper Functions
# ============================================================================

def _get_user_id_from_request(request: Request) -> int:
    """Extract user_id from request query params or raise 401"""
    user_id = getattr(request.state, 'user_id', None)
    if user_id is not None:
        try:
            return int(user_id)
        except ValueError:
            raise HTTPException(status_code=400, detail="Invalid user_id format")

    user_id = request.query_params.get('user_id')
    if user_id:
        try:
            return int(user_id)
        except ValueError:
            raise HTTPException(status_code=400, detail="Invalid user_id format")
    
    raise HTTPException(status_code=401, detail="User not authenticated - provide user_id query parameter")


# ============================================================================
# Pydantic Schemas
# ============================================================================

class UserNotificationPreferences(BaseModel):
    """User notification preferences"""
    notify_mattermost: bool = True
    notify_email: bool = False
    notify_frontend: bool = True
    email_override: Optional[str] = None
    quiet_hours_enabled: bool = False
    quiet_hours_start: Optional[str] = None  # HH:MM format
    quiet_hours_end: Optional[str] = None    # HH:MM format


class ReminderCreate(BaseModel):
    """Create reminder request"""
    title: str = Field(..., min_length=3, max_length=255)
    message: Optional[str] = None
    priority: str = Field(default="normal", pattern="^(low|normal|high|urgent)$")
    event_type: str = Field(default="reminder", pattern="^(reminder|meeting|technician_visit|obs|deadline)$")
    trigger_type: str = Field(pattern="^(status_change|deadline_approaching|time_based)$")
    trigger_config: dict  # JSON config for trigger
    recipient_user_ids: List[int] = []
    recipient_emails: List[str] = []
    notify_mattermost: Optional[bool] = None
    notify_email: Optional[bool] = None
    notify_frontend: Optional[bool] = None
    override_user_preferences: bool = False
    recurrence_type: str = Field(default="once", pattern="^(once|daily|weekly|monthly)$")
    recurrence_day_of_week: Optional[int] = None  # 0-6 for weekly
    recurrence_day_of_month: Optional[int] = None  # 1-31 for monthly
    scheduled_at: Optional[datetime] = None


class ReminderUpdate(BaseModel):
    """Update reminder request"""
    title: Optional[str] = None
    message: Optional[str] = None
    priority: Optional[str] = None
    event_type: Optional[str] = Field(default=None, pattern="^(reminder|meeting|technician_visit|obs|deadline)$")
    notify_mattermost: Optional[bool] = None
    notify_email: Optional[bool] = None
    notify_frontend: Optional[bool] = None
    override_user_preferences: Optional[bool] = None
    is_active: Optional[bool] = None


class ReminderResponse(BaseModel):
    """Reminder response"""
    id: int
    sag_id: int
    title: str
    message: Optional[str]
    priority: str
    event_type: Optional[str]
    trigger_type: str
    recurrence_type: str
    is_active: bool
    next_check_at: Optional[datetime]
    last_sent_at: Optional[datetime]
    created_at: datetime


class ReminderProfileResponse(BaseModel):
    """Reminder response for profile list"""
    id: int
    sag_id: int
    title: str
    message: Optional[str]
    priority: str
    event_type: Optional[str]
    trigger_type: str
    recurrence_type: str
    is_active: bool
    next_check_at: Optional[datetime]
    last_sent_at: Optional[datetime]
    created_at: datetime
    case_title: Optional[str]
    customer_name: Optional[str]


class ReminderLogResponse(BaseModel):
    """Reminder execution log"""
    id: int
    reminder_id: Optional[int]
    sag_id: int
    status: str
    triggered_at: datetime
    channels_used: List[str]


class SnoozeRequest(BaseModel):
    """Snooze reminder request"""
    duration_minutes: int = Field(..., ge=15, le=1440)  # 15 min to 24 hours


class DismissRequest(BaseModel):
    """Dismiss reminder request"""
    reason: Optional[str] = None


# ============================================================================
# User Preferences Endpoints
# ============================================================================

@router.get("/api/v1/users/me/notification-preferences", response_model=UserNotificationPreferences)
async def get_user_notification_preferences(request: Request):
    """Get current user's notification preferences"""
    user_id = _get_user_id_from_request(request)
    
    query = """
        SELECT 
            notify_mattermost, notify_email, notify_frontend,
            email_override, quiet_hours_enabled, quiet_hours_start, quiet_hours_end
        FROM user_notification_preferences
        WHERE user_id = %s
    """
    
    result = execute_query(query, (user_id,))
    
    if result:
        r = result[0]
        return UserNotificationPreferences(
            notify_mattermost=r.get('notify_mattermost', True),
            notify_email=r.get('notify_email', False),
            notify_frontend=r.get('notify_frontend', True),
            email_override=r.get('email_override'),
            quiet_hours_enabled=r.get('quiet_hours_enabled', False),
            quiet_hours_start=r.get('quiet_hours_start'),
            quiet_hours_end=r.get('quiet_hours_end')
        )
    
    # Return defaults
    return UserNotificationPreferences()


@router.patch("/api/v1/users/me/notification-preferences")
async def update_user_notification_preferences(
    request: Request,
    preferences: UserNotificationPreferences
):
    """Update user notification preferences"""
    user_id = _get_user_id_from_request(request)
    
    # Check if preferences exist
    check_query = "SELECT id FROM user_notification_preferences WHERE user_id = %s"
    exists = execute_query(check_query, (user_id,))
    
    try:
        if exists:
            # Update existing
            query = """
                UPDATE user_notification_preferences
                SET notify_mattermost = %s,
                    notify_email = %s,
                    notify_frontend = %s,
                    email_override = %s,
                    quiet_hours_enabled = %s,
                    quiet_hours_start = %s,
                    quiet_hours_end = %s,
                    updated_at = CURRENT_TIMESTAMP
                WHERE user_id = %s
                RETURNING id
            """
            
            execute_insert(query, (
                preferences.notify_mattermost,
                preferences.notify_email,
                preferences.notify_frontend,
                preferences.email_override,
                preferences.quiet_hours_enabled,
                preferences.quiet_hours_start,
                preferences.quiet_hours_end,
                user_id
            ))
        else:
            # Create new
            query = """
                INSERT INTO user_notification_preferences (
                    user_id, notify_mattermost, notify_email, notify_frontend,
                    email_override, quiet_hours_enabled, quiet_hours_start, quiet_hours_end
                )
                VALUES (%s, %s, %s, %s, %s, %s, %s, %s)
                RETURNING id
            """
            
            execute_insert(query, (
                user_id,
                preferences.notify_mattermost,
                preferences.notify_email,
                preferences.notify_frontend,
                preferences.email_override,
                preferences.quiet_hours_enabled,
                preferences.quiet_hours_start,
                preferences.quiet_hours_end
            ))
        
        logger.info(f"✅ Updated notification preferences for user {user_id}")
        return {"success": True, "message": "Preferences updated"}
    
    except Exception as e:
        logger.error(f"❌ Error updating preferences: {e}")
        raise HTTPException(status_code=500, detail=str(e))


# ============================================================================
# Reminder CRUD Endpoints
# ============================================================================

@router.get("/api/v1/sag/{sag_id}/reminders", response_model=List[ReminderResponse])
async def list_sag_reminders(sag_id: int):
    """List all reminders for a case"""
    
    query = """
        SELECT id, sag_id, title, message, priority, event_type, trigger_type, 
               recurrence_type, is_active, next_check_at, last_sent_at, created_at
        FROM sag_reminders
        WHERE sag_id = %s AND deleted_at IS NULL
        ORDER BY created_at DESC
    """
    
    results = execute_query(query, (sag_id,))
    
    return [
        ReminderResponse(
            id=r['id'],
            sag_id=r['sag_id'],
            title=r['title'],
            message=r['message'],
            priority=r['priority'],
            event_type=r.get('event_type'),
            trigger_type=r['trigger_type'],
            recurrence_type=r['recurrence_type'],
            is_active=r['is_active'],
            next_check_at=r['next_check_at'],
            last_sent_at=r['last_sent_at'],
            created_at=r['created_at']
        )
        for r in results
    ]


@router.get("/api/v1/reminders/my", response_model=List[ReminderProfileResponse])
async def list_my_reminders(request: Request):
    """List reminders for the authenticated user"""
    user_id = _get_user_id_from_request(request)

    query = """
        SELECT r.id, r.sag_id, r.title, r.message, r.priority, r.event_type, r.trigger_type,
               r.recurrence_type, r.is_active, r.next_check_at, r.last_sent_at, r.created_at,
               s.titel as case_title, c.name as customer_name
        FROM sag_reminders r
        LEFT JOIN sag_sager s ON s.id = r.sag_id
        LEFT JOIN customers c ON c.id = s.customer_id
        WHERE r.deleted_at IS NULL
          AND %s = ANY(r.recipient_user_ids)
        ORDER BY r.created_at DESC
    """

    results = execute_query(query, (user_id,))

    return [
        ReminderProfileResponse(
            id=r['id'],
            sag_id=r['sag_id'],
            title=r['title'],
            message=r['message'],
            priority=r['priority'],
            event_type=r.get('event_type'),
            trigger_type=r['trigger_type'],
            recurrence_type=r['recurrence_type'],
            is_active=r['is_active'],
            next_check_at=r['next_check_at'],
            last_sent_at=r['last_sent_at'],
            created_at=r['created_at'],
            case_title=r.get('case_title'),
            customer_name=r.get('customer_name')
        )
        for r in results
    ]


@router.post("/api/v1/sag/{sag_id}/reminders", response_model=ReminderResponse)
async def create_sag_reminder(sag_id: int, request: Request, reminder: ReminderCreate):
    """Create a new reminder for a case"""
    user_id = _get_user_id_from_request(request)
    
    # Verify case exists
    case_query = "SELECT id FROM sag_sager WHERE id = %s"
    case = execute_query(case_query, (sag_id,))
    if not case:
        raise HTTPException(status_code=404, detail=f"Case #{sag_id} not found")
    
    # Calculate next_check_at based on trigger type
    next_check_at = None
    if reminder.trigger_type == 'time_based' and reminder.scheduled_at:
        next_check_at = reminder.scheduled_at
    elif reminder.trigger_type == 'deadline_approaching':
        next_check_at = datetime.now() + timedelta(days=1)  # Check daily
    
    try:
        import json
        query = """
            INSERT INTO sag_reminders (
                sag_id, title, message, priority, event_type, trigger_type, trigger_config,
                recipient_user_ids, recipient_emails,
                notify_mattermost, notify_email, notify_frontend,
                override_user_preferences,
                recurrence_type, recurrence_day_of_week, recurrence_day_of_month,
                scheduled_at, next_check_at,
                is_active, created_by_user_id
            )
            VALUES (
                %s, %s, %s, %s, %s, %s, %s,
                %s, %s,
                %s, %s, %s,
                %s,
                %s, %s, %s,
                %s, %s,
                true, %s
            )
            RETURNING id, sag_id, title, message, priority, event_type, trigger_type,
                      recurrence_type, is_active, next_check_at, last_sent_at, created_at
        """
        
        result = execute_insert(query, (
            sag_id, reminder.title, reminder.message, reminder.priority, reminder.event_type,
            reminder.trigger_type, json.dumps(reminder.trigger_config),
            reminder.recipient_user_ids, reminder.recipient_emails,
            reminder.notify_mattermost, reminder.notify_email, reminder.notify_frontend,
            reminder.override_user_preferences,
            reminder.recurrence_type, reminder.recurrence_day_of_week, reminder.recurrence_day_of_month,
            reminder.scheduled_at, next_check_at,
            user_id
        ))
        
        if not result:
            raise HTTPException(status_code=500, detail="Failed to create reminder")
        
        raw_row = result[0] if isinstance(result, list) else result
        if isinstance(raw_row, dict):
            r = raw_row
        else:
            reminder_id = int(raw_row)
            fetch_query = """
                SELECT id, sag_id, title, message, priority, event_type, trigger_type,
                       recurrence_type, is_active, next_check_at, last_sent_at, created_at
                FROM sag_reminders
                WHERE id = %s
            """
            fetched = execute_query(fetch_query, (reminder_id,))
            if not fetched:
                raise HTTPException(status_code=500, detail="Failed to fetch reminder after creation")
            r = fetched[0]

        logger.info(f"✅ Reminder created for case #{sag_id} by user {user_id}")

        return ReminderResponse(
            id=r['id'],
            sag_id=r['sag_id'],
            title=r['title'],
            message=r['message'],
            priority=r['priority'],
            event_type=r.get('event_type'),
            trigger_type=r['trigger_type'],
            recurrence_type=r['recurrence_type'],
            is_active=r['is_active'],
            next_check_at=r['next_check_at'],
            last_sent_at=r['last_sent_at'],
            created_at=r['created_at']
        )
    
    except Exception as e:
        logger.error(f"❌ Error creating reminder: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.patch("/api/v1/sag/reminders/{reminder_id}")
async def update_sag_reminder(reminder_id: int, update: ReminderUpdate):
    """Update a reminder"""
    
    # Build update query dynamically
    updates = []
    params = []
    
    if update.title is not None:
        updates.append("title = %s")
        params.append(update.title)
    
    if update.message is not None:
        updates.append("message = %s")
        params.append(update.message)
    
    if update.priority is not None:
        updates.append("priority = %s")
        params.append(update.priority)

    if update.event_type is not None:
        updates.append("event_type = %s")
        params.append(update.event_type)
    
    if update.notify_mattermost is not None:
        updates.append("notify_mattermost = %s")
        params.append(update.notify_mattermost)
    
    if update.notify_email is not None:
        updates.append("notify_email = %s")
        params.append(update.notify_email)
    
    if update.notify_frontend is not None:
        updates.append("notify_frontend = %s")
        params.append(update.notify_frontend)
    
    if update.override_user_preferences is not None:
        updates.append("override_user_preferences = %s")
        params.append(update.override_user_preferences)
    
    if update.is_active is not None:
        updates.append("is_active = %s")
        params.append(update.is_active)
    
    if not updates:
        raise HTTPException(status_code=400, detail="No fields to update")
    
    updates.append("updated_at = CURRENT_TIMESTAMP")
    params.append(reminder_id)
    
    try:
        query = f"""
            UPDATE sag_reminders
            SET {', '.join(updates)}
            WHERE id = %s
            RETURNING id
        """
        
        result = execute_insert(query, tuple(params))
        if not result:
            raise HTTPException(status_code=404, detail="Reminder not found")
        
        logger.info(f"✅ Reminder {reminder_id} updated")
        return {"success": True, "message": "Reminder updated"}
    
    except Exception as e:
        logger.error(f"❌ Error updating reminder: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.delete("/api/v1/sag/reminders/{reminder_id}")
async def delete_sag_reminder(reminder_id: int):
    """Soft-delete a reminder"""
    
    try:
        query = """
            UPDATE sag_reminders
            SET deleted_at = CURRENT_TIMESTAMP, is_active = false
            WHERE id = %s
            RETURNING id
        """
        
        result = execute_insert(query, (reminder_id,))
        if not result:
            raise HTTPException(status_code=404, detail="Reminder not found")
        
        logger.info(f"✅ Reminder {reminder_id} deleted")
        return {"success": True, "message": "Reminder deleted"}
    
    except Exception as e:
        logger.error(f"❌ Error deleting reminder: {e}")
        raise HTTPException(status_code=500, detail=str(e))


# ============================================================================
# Reminder Interaction Endpoints
# ============================================================================

@router.post("/api/v1/sag/reminders/{reminder_id}/snooze")
async def snooze_reminder(reminder_id: int, request: Request, snooze_request: SnoozeRequest):
    """Snooze a reminder for specified minutes"""
    user_id = _get_user_id_from_request(request)
    
    snooze_until = datetime.now() + timedelta(minutes=snooze_request.duration_minutes)
    
    try:
        query = """
            INSERT INTO sag_reminder_logs (
                reminder_id, sag_id, user_id, status, snoozed_until, snoozed_by_user_id, triggered_at
            )
            SELECT id, sag_id, %s, 'snoozed', %s, %s, CURRENT_TIMESTAMP
            FROM sag_reminders
            WHERE id = %s
            RETURNING id
        """
        
        result = execute_insert(query, (user_id, snooze_until, user_id, reminder_id))
        if not result:
            raise HTTPException(status_code=404, detail="Reminder not found")
        
        logger.info(f"✅ Reminder {reminder_id} snoozed until {snooze_until}")
        return {
            "success": True,
            "message": f"Reminder snoozed for {snooze_request.duration_minutes} minutes",
            "snoozed_until": snooze_until
        }
    
    except Exception as e:
        logger.error(f"❌ Error snoozing reminder: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/api/v1/sag/reminders/{reminder_id}/dismiss")
async def dismiss_reminder(reminder_id: int, request: Request, dismiss_request: DismissRequest):
    """Dismiss a reminder"""
    user_id = _get_user_id_from_request(request)
    
    try:
        query = """
            INSERT INTO sag_reminder_logs (
                reminder_id, sag_id, user_id, status, dismissed_at, dismissed_by_user_id, triggered_at
            )
            SELECT id, sag_id, %s, 'dismissed', CURRENT_TIMESTAMP, %s, CURRENT_TIMESTAMP
            FROM sag_reminders
            WHERE id = %s
            RETURNING id
        """
        
        result = execute_insert(query, (user_id, user_id, reminder_id))
        if not result:
            raise HTTPException(status_code=404, detail="Reminder not found")
        
        logger.info(f"✅ Reminder {reminder_id} dismissed by user {user_id}")
        return {"success": True, "message": "Reminder dismissed"}
    
    except Exception as e:
        logger.error(f"❌ Error dismissing reminder: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/api/v1/reminders/pending/me")
async def get_pending_reminders(request: Request):
    """Get pending reminders for current user (for frontend polling)"""
    user_id = _get_user_id_from_request(request)
    
    query = """
        SELECT 
            r.id, r.sag_id, r.title, r.message, r.priority,
            s.titel as case_title, c.name as customer_name,
            l.id as log_id, l.snoozed_until, l.status as log_status
        FROM sag_reminders r
        JOIN sag_sager s ON r.sag_id = s.id
        JOIN customers c ON s.customer_id = c.id
        LEFT JOIN LATERAL (
            SELECT id, snoozed_until, status, triggered_at
            FROM sag_reminder_logs
            WHERE reminder_id = r.id AND user_id = %s
            ORDER BY triggered_at DESC
            LIMIT 1
        ) l ON true
        WHERE r.is_active = true
            AND r.deleted_at IS NULL
            AND r.next_check_at <= CURRENT_TIMESTAMP
            AND %s = ANY(r.recipient_user_ids)
            AND (l.snoozed_until IS NULL OR l.snoozed_until < CURRENT_TIMESTAMP)
            AND (l.status IS NULL OR l.status != 'dismissed')
        ORDER BY r.priority DESC, r.next_check_at ASC
        LIMIT 5
    """
    
    try:
        results = execute_query(query, (user_id, user_id))
        return [{
            'id': r['id'],
            'sag_id': r['sag_id'],
            'title': r['title'],
            'message': r['message'],
            'priority': r['priority'],
            'case_title': r['case_title'],
            'customer_name': r['customer_name']
        } for r in results]
    
    except Exception as e:
        logger.error(f"❌ Error fetching pending reminders: {e}")
        raise HTTPException(status_code=500, detail=str(e))
