<?php

declare(strict_types=1);

namespace App\Services;

use App\Models\Note;

class NoteService
{
    private Note $noteModel;

    public function __construct()
    {
        $this->noteModel = new Note();
    }

    public function createTextNote(int $leadId, string $content, int $userId): array
    {
        return $this->createNote($leadId, 'texto', $content, null, $userId);
    }

    public function createVoiceNote(int $leadId, array $fileData, int $userId): array
    {
        $filePath = $this->storeAudioFile($fileData);

        return $this->createNote($leadId, 'audio', null, $filePath, $userId);
    }

    public function getNotesByLead(int $leadId): array
    {
        return $this->noteModel->getByLeadId($leadId);
    }

    public function updateNote(int $id, string $content): array
    {
        $note = $this->noteModel->findById($id);
        if (!$note) {
            throw new \RuntimeException('Nota no encontrada', 404);
        }
        if ($note['type'] !== 'texto') {
            throw new \RuntimeException('Solo se pueden editar notas de texto', 422);
        }
        if (empty(trim($content))) {
            throw new \RuntimeException('El contenido de la nota es obligatorio', 422);
        }
        $this->noteModel->update($id, ['content' => $content]);
        $note = $this->noteModel->findById($id);
        $note['created_by_name'] = $note['created_by'] ?? 'Usuario';
        return $note;
    }

    public function getAudioFilePath(int $id): string
    {
        $note = $this->noteModel->findById($id);
        if (!$note) {
            throw new \RuntimeException('Nota no encontrada', 404);
        }
        if ($note['type'] !== 'audio' || empty($note['audio_file_path'])) {
            throw new \RuntimeException('La nota no tiene audio', 404);
        }
        if (!file_exists($note['audio_file_path'])) {
            throw new \RuntimeException('Archivo de audio no encontrado', 404);
        }
        return $note['audio_file_path'];
    }

    public function deleteNote(int $id): void
    {
        $note = $this->noteModel->findById($id);
        if (!$note) {
            throw new \RuntimeException('Nota no encontrada', 404);
        }

        if ($note['type'] === 'audio' && !empty($note['audio_file_path'])) {
            if (file_exists($note['audio_file_path'])) {
                @unlink($note['audio_file_path']);
            }
        }

        $this->noteModel->delete($id);
    }

    private function createNote(int $leadId, string $type, ?string $content, ?string $audioPath, int $userId): array
    {
        $data = [
            'lead_id' => $leadId,
            'type' => $type,
            'created_by' => $userId,
        ];

        if ($type === 'texto') {
            if (empty(trim($content ?? ''))) {
                throw new \RuntimeException('El contenido de la nota es obligatorio', 422);
            }
            $data['content'] = $content;
        } elseif ($type === 'audio') {
            $data['audio_file_path'] = $audioPath;
        }

        $id = $this->noteModel->createNote($data);

        $note = $this->noteModel->findById($id);
        $note['created_by_name'] = $note['created_by'] ?? 'Usuario';

        return $note;
    }

    private function storeAudioFile(array $fileData): string
    {
        if (empty($fileData) || !isset($fileData['tmp_name']) || $fileData['error'] !== UPLOAD_ERR_OK) {
            throw new \RuntimeException('Archivo de audio no proporcionado', 422);
        }

        // finfo fallback if client MIME is unreliable
        $detectedMime = @(new \finfo(FILEINFO_MIME_TYPE))->file($fileData['tmp_name']);
        $originalMime = $fileData['type'] ?? '';
        $mimeType = $detectedMime ?: $originalMime;

        $allowedMimes = ['audio/webm', 'video/webm', 'audio/mp4', 'audio/mpeg', 'audio/wav', 'audio/ogg'];
        $valid = false;
        foreach ($allowedMimes as $m) {
            if (str_starts_with($mimeType, $m) || $mimeType === $m) {
                $valid = true;
                break;
            }
        }
        if (!$valid) {
            throw new \RuntimeException('Formato de audio no permitido', 422);
        }

        $maxSize = 30 * 1024 * 1024;
        if ($fileData['size'] > $maxSize) {
            throw new \RuntimeException('El archivo excede los 30MB', 422);
        }

        $subDir = STORAGE_PATH . '/uploads/audio/';
        if (!is_dir($subDir)) {
            mkdir($subDir, 0755, true);
        }

        $filename = uniqid('voice_note_') . '.webm';
        $destPath = $subDir . $filename;

        if (!move_uploaded_file($fileData['tmp_name'], $destPath)) {
            throw new \RuntimeException('Error al guardar el audio', 500);
        }

        return $destPath;
    }
}
