/**
 * LLM Controller
 * Handles AI chat assistant endpoints
 */

import { Request, Response, NextFunction } from 'express';
import { llmService } from '../services/llm.service';

// ============================================================================
// Types
// ============================================================================

// Use Request directly - user is already declared globally in auth.middleware.ts
type AuthRequest = Request;

// ============================================================================
// Session Management
// ============================================================================

/**
 * Create a new chat session
 */
export async function createSession(req: AuthRequest, res: Response, next: NextFunction): Promise<void> {
  try {
    const userId = req.user?.id;
    if (!userId) {
      res.status(401).json({
        success: false,
        error: { message: 'Unauthorized', code: 'UNAUTHORIZED' },
      });
      return;
    }

    const { watchlist, preferences, portfolioSummary } = req.body;

    const session = await llmService.createSession(userId, {
      watchlist,
      preferences,
      portfolioSummary,
    });

    res.status(201).json({
      success: true,
      data: {
        sessionId: session.id,
        createdAt: session.createdAt,
      },
    });
  } catch (error) {
    next(error);
  }
}

/**
 * Get user's chat sessions
 */
export async function getSessions(req: AuthRequest, res: Response, next: NextFunction): Promise<void> {
  try {
    const userId = req.user?.id;
    if (!userId) {
      res.status(401).json({
        success: false,
        error: { message: 'Unauthorized', code: 'UNAUTHORIZED' },
      });
      return;
    }

    const sessions = await llmService.getUserSessions(userId);

    res.json({
      success: true,
      data: sessions.map((s) => ({
        id: s.id,
        messagesCount: s.messages.length,
        lastMessage: s.messages[s.messages.length - 1]?.content.substring(0, 100),
        createdAt: s.createdAt,
        updatedAt: s.updatedAt,
      })),
    });
  } catch (error) {
    next(error);
  }
}

/**
 * Get a specific session with messages
 */
export async function getSession(req: AuthRequest, res: Response, next: NextFunction): Promise<void> {
  try {
    const userId = req.user?.id;
    if (!userId) {
      res.status(401).json({
        success: false,
        error: { message: 'Unauthorized', code: 'UNAUTHORIZED' },
      });
      return;
    }

    const { sessionId } = req.params;

    const session = await llmService.getSession(sessionId);
    if (!session) {
      res.status(404).json({
        success: false,
        error: { message: 'Session not found', code: 'NOT_FOUND' },
      });
      return;
    }

    if (session.userId !== userId) {
      res.status(403).json({
        success: false,
        error: { message: 'Forbidden', code: 'FORBIDDEN' },
      });
      return;
    }

    res.json({
      success: true,
      data: session,
    });
  } catch (error) {
    next(error);
  }
}

/**
 * Delete a session
 */
export async function deleteSession(req: AuthRequest, res: Response, next: NextFunction): Promise<void> {
  try {
    const userId = req.user?.id;
    if (!userId) {
      res.status(401).json({
        success: false,
        error: { message: 'Unauthorized', code: 'UNAUTHORIZED' },
      });
      return;
    }

    const { sessionId } = req.params;

    const session = await llmService.getSession(sessionId);
    if (!session) {
      res.status(404).json({
        success: false,
        error: { message: 'Session not found', code: 'NOT_FOUND' },
      });
      return;
    }

    if (session.userId !== userId) {
      res.status(403).json({
        success: false,
        error: { message: 'Forbidden', code: 'FORBIDDEN' },
      });
      return;
    }

    await llmService.deleteSession(sessionId);

    res.json({
      success: true,
      message: 'Session deleted',
    });
  } catch (error) {
    next(error);
  }
}

// ============================================================================
// Chat
// ============================================================================

/**
 * Send a message and get a response
 */
export async function chat(req: AuthRequest, res: Response, next: NextFunction): Promise<void> {
  try {
    const userId = req.user?.id;
    if (!userId) {
      res.status(401).json({
        success: false,
        error: { message: 'Unauthorized', code: 'UNAUTHORIZED' },
      });
      return;
    }

    const { sessionId } = req.params;
    const { message } = req.body;

    if (!message || typeof message !== 'string' || message.trim().length === 0) {
      res.status(400).json({
        success: false,
        error: { message: 'Message is required', code: 'VALIDATION_ERROR' },
      });
      return;
    }

    const session = await llmService.getSession(sessionId);
    if (!session) {
      res.status(404).json({
        success: false,
        error: { message: 'Session not found', code: 'NOT_FOUND' },
      });
      return;
    }

    if (session.userId !== userId) {
      res.status(403).json({
        success: false,
        error: { message: 'Forbidden', code: 'FORBIDDEN' },
      });
      return;
    }

    const response = await llmService.chat(sessionId, message.trim());

    res.json({
      success: true,
      data: response,
    });
  } catch (error) {
    next(error);
  }
}

// ============================================================================
// Quick Actions
// ============================================================================

/**
 * Get quick analysis for a symbol (no session required)
 */
export async function getQuickAnalysis(req: Request, res: Response, next: NextFunction): Promise<void> {
  try {
    const { symbol } = req.params;

    if (!symbol) {
      res.status(400).json({
        success: false,
        error: { message: 'Symbol is required', code: 'VALIDATION_ERROR' },
      });
      return;
    }

    const analysis = await llmService.getQuickAnalysis(symbol.toUpperCase());

    res.json({
      success: true,
      data: {
        symbol: symbol.toUpperCase(),
        analysis,
        timestamp: new Date().toISOString(),
      },
    });
  } catch (error) {
    next(error);
  }
}
