<?php
/**
 * ZLO Platform - Lead Controller
 */

declare(strict_types=1);

require_once __DIR__ . '/../models/Lead.php';
require_once __DIR__ . '/../core/Router.php';

class LeadController
{
    private Lead $leadModel;
    
    public function __construct()
    {
        $this->leadModel = new Lead();
    }
    
    /**
     * Get all leads (admin only)
     */
    public function index(array $params): array
    {
        AuthController::requirePermission('leads.view');
        
        $query = Router::getQuery();
        
        $options = [
            'status' => $query['status'] ?? null,
            'assigned_to' => $query['assigned_to'] ?? null,
            'limit' => (int) ($query['limit'] ?? 20),
            'page' => (int) ($query['page'] ?? 1)
        ];
        
        $where = [];
        $whereParams = [];
        
        if ($options['status']) {
            $where[] = "status = ?";
            $whereParams[] = $options['status'];
        }
        
        if ($options['assigned_to']) {
            $where[] = "assigned_to = ?";
            $whereParams[] = $options['assigned_to'];
        }
        
        $whereClause = !empty($where) ? "WHERE " . implode(" AND ", $where) : "";
        
        // Get leads with solution info
        $sql = "SELECT l.*, s.title as solution_title, s.slug as solution_slug, u.name as assigned_name 
                FROM leads l 
                LEFT JOIN solutions s ON l.interest_solution_id = s.id 
                LEFT JOIN users u ON l.assigned_to = u.id 
                {$whereClause} 
                ORDER BY l.created_at DESC 
                LIMIT ? OFFSET ?";
        
        $params = array_merge($whereParams, [
            $options['limit'],
            ($options['page'] - 1) * $options['limit']
        ]);
        
        $leads = $this->leadModel->raw($sql, $params);
        
        // Count total
        $countSql = "SELECT COUNT(*) as total FROM leads {$whereClause}";
        $totalResult = $this->leadModel->raw($countSql, $whereParams);
        $total = (int) ($totalResult[0]['total'] ?? 0);
        
        return [
            'leads' => $leads,
            'pagination' => [
                'current_page' => $options['page'],
                'per_page' => $options['limit'],
                'total' => $total,
                'last_page' => (int) ceil($total / $options['limit']),
                'from' => (($options['page'] - 1) * $options['limit']) + 1,
                'to' => min($options['page'] * $options['limit'], $total)
            ]
        ];
    }
    
    /**
     * Get single lead (admin only)
     */
    public function show(array $params): ?array
    {
        AuthController::requirePermission('leads.view');
        
        $id = (int) ($params['id'] ?? 0);
        
        if (!$id) {
            http_response_code(400);
            return ['error' => 'Lead ID is required'];
        }
        
        $lead = $this->leadModel->getWithDetails($id);
        
        if (!$lead) {
            http_response_code(404);
            return ['error' => 'Lead not found'];
        }
        
        return $lead;
    }
    
    /**
     * Create lead (public)
     */
    public function create(array $params): array
    {
        $body = Router::getBody();
        $security = new Security();
        
        // Validate required fields
        $required = ['first_name', 'last_name', 'email'];
        foreach ($required as $field) {
            if (empty($body[$field])) {
                http_response_code(400);
                return ['error' => "Field {$field} is required"];
            }
        }
        
        // Validate email
        if (!$security->validateEmail($body['email'])) {
            http_response_code(400);
            return ['error' => 'Invalid email address'];
        }
        
        try {
            $id = $this->leadModel->create($body);
            
            // Calculate lead score
            $this->leadModel->calculateScore($id);
            
            // Send notification email (if mailer is configured)
            $this->sendLeadNotification($body);
            
            http_response_code(201);
            return [
                'message' => 'Lead created successfully',
                'lead_id' => $id
            ];
        } catch (Exception $e) {
            http_response_code(500);
            return ['error' => 'Failed to create lead'];
        }
    }
    
    /**
     * Update lead (admin only)
     */
    public function update(array $params): ?array
    {
        AuthController::requirePermission('leads.edit');
        
        $id = (int) ($params['id'] ?? 0);
        
        if (!$id) {
            http_response_code(400);
            return ['error' => 'Lead ID is required'];
        }
        
        $body = Router::getBody();
        
        try {
            $this->leadModel->update($id, $body);
            
            // Recalculate score if relevant fields changed
            if (isset($body['company_size']) || isset($body['message'])) {
                $this->leadModel->calculateScore($id);
            }
            
            return $this->leadModel->getWithDetails($id);
        } catch (Exception $e) {
            http_response_code(500);
            return ['error' => 'Failed to update lead'];
        }
    }
    
    /**
     * Delete lead (admin only)
     */
    public function delete(array $params): array
    {
        AuthController::requirePermission('leads.delete');
        
        $id = (int) ($params['id'] ?? 0);
        
        if (!$id) {
            http_response_code(400);
            return ['error' => 'Lead ID is required'];
        }
        
        try {
            $this->leadModel->delete($id);
            return ['message' => 'Lead deleted successfully'];
        } catch (Exception $e) {
            http_response_code(500);
            return ['error' => 'Failed to delete lead'];
        }
    }
    
    /**
     * Assign lead to user (admin only)
     */
    public function assign(array $params): array
    {
        AuthController::requirePermission('leads.edit');
        
        $id = (int) ($params['id'] ?? 0);
        $body = Router::getBody();
        $userId = (int) ($body['user_id'] ?? 0);
        
        if (!$id || !$userId) {
            http_response_code(400);
            return ['error' => 'Lead ID and User ID are required'];
        }
        
        try {
            $this->leadModel->assign($id, $userId);
            return ['message' => 'Lead assigned successfully'];
        } catch (Exception $e) {
            http_response_code(500);
            return ['error' => 'Failed to assign lead'];
        }
    }
    
    /**
     * Update lead status (admin only)
     */
    public function updateStatus(array $params): array
    {
        AuthController::requirePermission('leads.edit');
        
        $id = (int) ($params['id'] ?? 0);
        $body = Router::getBody();
        $status = $body['status'] ?? '';
        
        $validStatuses = ['new', 'contacted', 'qualified', 'proposal', 'negotiation', 'won', 'lost', 'nurturing'];
        
        if (!$id || !in_array($status, $validStatuses)) {
            http_response_code(400);
            return ['error' => 'Invalid lead ID or status'];
        }
        
        try {
            $this->leadModel->updateStatus($id, $status);
            return ['message' => 'Status updated successfully'];
        } catch (Exception $e) {
            http_response_code(500);
            return ['error' => 'Failed to update status'];
        }
    }
    
    /**
     * Get lead stats (admin only)
     */
    public function stats(array $params): array
    {
        AuthController::requirePermission('leads.view');
        
        return $this->leadModel->getStats();
    }
    
    /**
     * Search leads (admin only)
     */
    public function search(array $params): array
       {
        AuthController::requirePermission('leads.view');
        
        $query = Router::getQuery();
        $search = $query['q'] ?? '';
        
        if (!$search) {
            http_response_code(400);
            return ['error' => 'Search query is required'];
        }
        
        $results = $this->leadModel->search($search, [
            'limit' => (int) ($query['limit'] ?? 20)
        ]);
        
        return ['leads' => $results];
    }
    
    /**
     * Send lead notification email
     */
    private function sendLeadNotification(array $leadData): void
    {
        // This will be implemented when Mailer is configured
        // For now, just log the lead creation
        $security = new Security();
        $security->logEvent('lead_created', [
            'email' => $leadData['email'],
            'company' => $leadData['company'] ?? null
        ]);
    }
}
