<?php

declare(strict_types=1);

namespace Tests\Unit\Services;

use App\Services\MaterialService;
use App\Services\TemplateService;
use Tests\TestCase;

class MaterialTemplateServiceTest extends TestCase
{
    private MaterialService $materialService;
    private TemplateService $templateService;
    private int $adminId;

    protected function setUp(): void
    {
        parent::setUp();
        $this->materialService = new MaterialService();
        $this->templateService = new TemplateService();
        $this->adminId = $this->createTestUser('admin@test.com', 'super_admin', 'active');
    }

    public function testCreateMaterial(): void
    {
        $material = $this->materialService->uploadMaterial([
            'title' => 'Guía de Nutrición Bovina',
            'description' => 'Manual completo',
            'type' => 'pdf',
            'external_url' => 'https://ejemplo.com/guia.pdf',
        ], [], $this->adminId);

        $this->assertEquals('Guía de Nutrición Bovina', $material['title']);
        $this->assertEquals('pdf', $material['type']);
        $this->assertEquals('active', $material['status']);
    }

    public function testCreateMaterialWithoutTitle(): void
    {
        $this->expectException(\RuntimeException::class);
        $this->materialService->uploadMaterial([
            'title' => '',
            'type' => 'pdf',
        ], [], $this->adminId);
    }

    public function testGetMaterials(): void
    {
        $this->materialService->uploadMaterial(['title' => 'M1', 'type' => 'pdf'], [], $this->adminId);
        $this->materialService->uploadMaterial(['title' => 'M2', 'type' => 'video', 'external_url' => 'https://a.com/v.mp4'], [], $this->adminId);

        $result = $this->materialService->getMaterials();
        $this->assertGreaterThanOrEqual(2, $result['total']);
    }

    public function testGetMaterialsWithFilter(): void
    {
        $this->materialService->uploadMaterial(['title' => 'PDF Doc', 'type' => 'pdf'], [], $this->adminId);
        $this->materialService->uploadMaterial(['title' => 'Video Tut', 'type' => 'video', 'external_url' => 'https://a.com/v.mp4'], [], $this->adminId);

        $result = $this->materialService->getMaterials(['type' => 'pdf']);
        $this->assertEquals(1, $result['total']);
    }

    public function testGetMaterial(): void
    {
        $created = $this->materialService->uploadMaterial(['title' => 'Detalle', 'type' => 'pdf'], [], $this->adminId);
        $material = $this->materialService->getMaterial($created['id']);
        $this->assertEquals('Detalle', $material['title']);
    }

    public function testUpdateMaterial(): void
    {
        $created = $this->materialService->uploadMaterial(['title' => 'Original', 'type' => 'pdf'], [], $this->adminId);

        $updated = $this->materialService->updateMaterial($created['id'], [
            'title' => 'Actualizado',
            'description' => 'Nueva descripción',
        ]);

        $this->assertEquals('Actualizado', $updated['title']);
        $this->assertEquals('Nueva descripción', $updated['description']);
    }

    public function testDeleteMaterial(): void
    {
        $created = $this->materialService->uploadMaterial(['title' => 'Eliminar', 'type' => 'pdf'], [], $this->adminId);
        $this->materialService->deleteMaterial($created['id']);

        $this->expectException(\RuntimeException::class);
        $this->materialService->getMaterial($created['id']);
    }

    public function testCreateTemplate(): void
    {
        $template = $this->templateService->createTemplate([
            'name' => 'Saludo Inicial',
            'content' => 'Hola {nombre}, soy {empresa}. ¿Cómo estás?',
        ], $this->adminId);

        $this->assertEquals('Saludo Inicial', $template['name']);
        $this->assertEquals('active', $template['status']);
        $this->assertContains('nombre', $template['variables']);
        $this->assertContains('empresa', $template['variables']);
    }

    public function testCreateTemplateWithoutContent(): void
    {
        $this->expectException(\RuntimeException::class);
        $this->templateService->createTemplate(['name' => 'Test', 'content' => ''], $this->adminId);
    }

    public function testGetTemplates(): void
    {
        $this->templateService->createTemplate(['name' => 'T1', 'content' => 'Hola {nombre}'], $this->adminId);
        $this->templateService->createTemplate(['name' => 'T2', 'content' => 'Adiós {nombre}'], $this->adminId);

        $result = $this->templateService->getTemplates();
        $this->assertGreaterThanOrEqual(2, $result['total']);
    }

    public function testGetTemplate(): void
    {
        $created = $this->templateService->createTemplate(['name' => 'Detalle T', 'content' => 'Saludos {nombre}'], $this->adminId);
        $template = $this->templateService->getTemplate($created['id']);
        $this->assertEquals('Detalle T', $template['name']);
    }

    public function testUpdateTemplate(): void
    {
        $created = $this->templateService->createTemplate(['name' => 'T Original', 'content' => '{nombre}'], $this->adminId);

        $updated = $this->templateService->updateTemplate($created['id'], [
            'name' => 'T Editada',
            'content' => 'Hola {nombre}, empresa {empresa}',
        ]);

        $this->assertEquals('T Editada', $updated['name']);
        $this->assertCount(2, $updated['variables']);
    }

    public function testDeleteTemplate(): void
    {
        $created = $this->templateService->createTemplate(['name' => 'Borrar', 'content' => 'Test'], $this->adminId);
        $this->templateService->deleteTemplate($created['id']);

        $this->expectException(\RuntimeException::class);
        $this->templateService->getTemplate($created['id']);
    }

    public function testValidateVariables(): void
    {
        $result = $this->templateService->validateVariables('Hola {nombre}, de {empresa}. Producto: {producto}');
        $this->assertTrue($result['valid']);
        $this->assertCount(3, $result['variables']);
        $this->assertContains('nombre', $result['variables']);
        $this->assertContains('empresa', $result['variables']);
        $this->assertContains('producto', $result['variables']);
    }

    public function testValidateVariablesNone(): void
    {
        $result = $this->templateService->validateVariables('Hola, sin variables');
        $this->assertTrue($result['valid']);
        $this->assertCount(0, $result['variables']);
    }

    public function testTemplateVariableExtraction(): void
    {
        $template = $this->templateService->createTemplate([
            'name' => 'Multi Variable',
            'content' => '{nombre} {apellido} trabaja en {empresa} como {cargo}',
        ], $this->adminId);

        $this->assertCount(4, $template['variables']);
    }
}
