<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Helpers\Response;
use App\Services\LeadService;
use App\Middlewares\AuditMiddleware;

class LeadController extends BaseController
{
    private LeadService $leadService;

    public function __construct($request)
    {
        parent::__construct($request);
        $this->leadService = new LeadService();
    }

    public function publicIndex(): void
    {
        $apiKey = $this->request->header('X-API-Key') ?? $this->request->query('api_key');
        $expectedKey = $_ENV['API_PUBLIC_KEY'] ?? '';

        if (empty($expectedKey) || $apiKey !== $expectedKey) {
            \App\Helpers\Response::error('No autorizado', 401);
            return;
        }

        try {
            $db = \App\Models\Database::connect();
            $stmt = $db->query(
                "SELECT
                    l.id, l.first_name, l.last_name, l.email, l.phone, l.company,
                    l.status, l.classification, l.created_at,
                    u.name as vendedor,
                    e.name as evento
                 FROM leads l
                 LEFT JOIN users u ON l.created_by = u.id
                 LEFT JOIN events e ON l.event_id = e.id
                 ORDER BY l.created_at DESC
                 LIMIT 500"
            );
            $leads = $stmt->fetchAll();
            \App\Helpers\Response::success($leads, 'Leads consultados correctamente');
        } catch (\Throwable $e) {
            \App\Helpers\Response::error($e->getMessage(), 500);
        }
    }

    public function storeManual(): void
    {
        $data = $this->request->body();

        $validation = $this->validate($data, function ($v) {
            $v->required('first_name', 'Nombre');
            $v->required('last_name', 'Apellido');
            if (!empty($data['email'] ?? null)) {
                $v->email('email', 'Correo electrónico');
            }
        });

        if ($validation->fails()) {
            Response::error($validation->firstError(), 422);
        }

        try {
            $lead = $this->leadService->createManual(
                $data,
                $this->getAuthUserId(),
                $this->getAuthUserEventId()
            );
            AuditMiddleware::log($this->getAuthUserId(), 'create', 'lead', isset($lead['id']) ? (int) $lead['id'] : null);
            Response::created($lead, 'Lead registrado correctamente');
        } catch (\RuntimeException $e) {
            Response::error($e->getMessage(), $e->getCode() ?: 400);
        }
    }

    public function storeScanOpenAi(): void
    {
        $file = $this->request->uploadedFile('image');

        try {
            $parsed = $this->leadService->parseFromScanOpenAi($file ?? []);
            Response::success($parsed, 'Imagen procesada con OpenAI');
        } catch (\RuntimeException $e) {
            Response::error($e->getMessage(), $e->getCode() ?: 400);
        }
    }

    public function storeVoiceOpenAi(): void
    {
        $file = $this->request->uploadedFile('audio');

        try {
            $parsed = $this->leadService->parseFromVoiceOpenAi($file ?? []);
            Response::success($parsed, 'Audio procesado con OpenAI');
        } catch (\RuntimeException $e) {
            Response::error($e->getMessage(), $e->getCode() ?: 400);
        }
    }

    public function index(): void
    {
        $filters = [
            'event_id' => $this->getAuthUserEventId(),
            'status' => $this->request->query('status'),
            'classification' => $this->request->query('classification'),
            'client_type' => $this->request->query('client_type'),
            'industry' => $this->request->query('industry'),
            'source' => $this->request->query('source'),
            'search' => $this->request->query('search'),
            'created_by' => $this->request->query('created_by'),
        ];

        $page = (int) ($this->request->query('page', 1));
        $perPage = (int) ($this->request->query('per_page', 15));

        try {
            $result = $this->leadService->getLeads(
                $this->getAuthUserId(),
                $this->getAuthUserRole(),
                $filters,
                $page,
                $perPage
            );
        } catch (\Throwable $e) {
            Response::error($e->getMessage(), 500);
        }

        Response::paginated(
            $result['items'],
            $result['total'],
            $result['page'],
            $result['per_page'],
            'Leads consultados correctamente'
        );
    }

    public function show(): void
    {
        $id = (int) $this->getRouteParam('id');

        try {
            $lead = $this->leadService->getLeadDetail($id);
            Response::success($lead, 'Lead consultado correctamente');
        } catch (\RuntimeException $e) {
            Response::error($e->getMessage(), $e->getCode() ?: 400);
        }
    }

    public function update(): void
    {
        $id = (int) $this->getRouteParam('id');
        $data = $this->request->body();

        if (isset($data['email']) && !empty($data['email'])) {
            $validation = $this->validate($data, function ($v) {
                $v->email('email', 'Correo electrónico');
            });
            if ($validation->fails()) {
                Response::error($validation->firstError(), 422);
            }
        }

        try {
            $oldLead = $this->leadService->getLead($id);
            $lead = $this->leadService->updateLead($id, $data, $this->getAuthUserId());
            AuditMiddleware::log($this->getAuthUserId(), 'update', 'lead', $id, $oldLead, $lead);
            Response::success($lead, 'Lead actualizado correctamente');
        } catch (\RuntimeException $e) {
            Response::error($e->getMessage(), $e->getCode() ?: 400);
        }
    }

    public function changeStatus(): void
    {
        $id = (int) $this->getRouteParam('id');
        $data = $this->request->body();

        $validation = $this->validate($data, function ($v) {
            $v->required('status', 'Estado')
              ->inValues('status', ['nuevo', 'contactado', 'calificado', 'propuesta', 'negociacion', 'ganado', 'perdido'], 'Estado');
        });

        if ($validation->fails()) {
            Response::error($validation->firstError(), 422);
        }

        try {
            $lead = $this->leadService->changeStatus(
                $id,
                $data['status'],
                $data['loss_reason_id'] ?? null,
                $data['notes'] ?? null,
                $this->getAuthUserId()
            );
            AuditMiddleware::log($this->getAuthUserId(), 'update', 'lead', $id, null, ['status' => $data['status']]);
            Response::success($lead, 'Estado actualizado correctamente');
        } catch (\RuntimeException $e) {
            Response::error($e->getMessage(), $e->getCode() ?: 400);
        }
    }

    public function assign(): void
    {
        $id = (int) $this->getRouteParam('id');
        $data = $this->request->body();
        $role = $this->getAuthUserRole();

        if ($role !== 'super_admin') {
            Response::error('Solo el administrador puede asignar leads', 403);
            return;
        }

        $validation = $this->validate($data, function ($v) {
            $v->required('seller_id', 'Vendedor');
        });

        if ($validation->fails()) {
            Response::error($validation->firstError(), 422);
            return;
        }

        try {
            $lead = $this->leadService->assignToSeller($id, (int) $data['seller_id'], $this->getAuthUserId());
            Response::success($lead, 'Lead asignado correctamente');
        } catch (\RuntimeException $e) {
            Response::error($e->getMessage(), $e->getCode() ?: 400);
        }
    }

    public function lossReasons(): void
    {
        $reasons = $this->leadService->getLossReasons();
        Response::success($reasons, 'Motivos de pérdida consultados correctamente');
    }

    public function destroy(): void
    {
        $id = (int) $this->getRouteParam('id');

        try {
            $this->leadService->deleteLead($id, $this->getAuthUserId(), $this->getAuthUserRole());
            AuditMiddleware::log($this->getAuthUserId(), 'delete', 'lead', $id);
            Response::success([], 'Lead eliminado correctamente');
        } catch (\RuntimeException $e) {
            Response::error($e->getMessage(), $e->getCode() ?: 400);
        }
    }

    public function checkDuplicates(): void
    {
        $email = $this->request->query('email');
        $phone = $this->request->query('phone');

        if (empty($email) && empty($phone)) {
            Response::success([], 'Sin criterios de búsqueda');
        }

        $duplicates = $this->leadService->checkDuplicates($email, $phone);
        Response::success($duplicates, count($duplicates) > 0 ? 'Posibles duplicados encontrados' : 'Sin duplicados');
    }

    public function references(): void
    {
        $references = $this->leadService->getReferences(
            $this->getAuthUserId(),
            $this->getAuthUserRole(),
            $this->getAuthUserEventId() ?? 0
        );
        Response::success($references, 'Referencias consultadas correctamente');
    }
}
