<?php

declare(strict_types=1);

namespace App\Tests\Api\Controller;

use App\Tests\AbstractApiTestCase;
use Symfony\Component\HttpFoundation\File\UploadedFile;

/**
 * @internal
 */
class CommentControllerTest extends AbstractApiTestCase
{
    public function testCreateComment(): void
    {
        $machine = $this->createMachine('Machine A');

        $client = $this->createViewerClient();
        $client->request('POST', '/api/comments', [
            'json' => [
                'content'    => 'Test comment',
                'entityType' => 'machine',
                'entityId'   => $machine->getId(),
                'entityName' => 'Machine A',
            ],
        ]);

        $this->assertResponseStatusCodeSame(201);
        $this->assertJsonContains([
            'content'    => 'Test comment',
            'entityType' => 'machine',
            'status'     => 'open',
        ]);
    }

    public function testCreateCommentUnauthenticated(): void
    {
        $client = $this->createUnauthenticatedClient();
        $client->request('POST', '/api/comments', [
            'json' => [
                'content'    => 'No auth',
                'entityType' => 'machine',
                'entityId'   => 'fake-id',
            ],
        ]);

        $this->assertResponseStatusCodeSame(401);
    }

    public function testCreateCommentEmptyContent(): void
    {
        $client = $this->createViewerClient();
        $client->request('POST', '/api/comments', [
            'json' => [
                'content'    => '',
                'entityType' => 'machine',
                'entityId'   => 'some-id',
            ],
        ]);

        $this->assertResponseStatusCodeSame(400);
        $this->assertJsonContains(['message' => 'Le contenu est requis.']);
    }

    public function testCreateCommentInvalidEntityType(): void
    {
        $client = $this->createViewerClient();
        $client->request('POST', '/api/comments', [
            'json' => [
                'content'    => 'Invalid type',
                'entityType' => 'invalid',
                'entityId'   => 'some-id',
            ],
        ]);

        $this->assertResponseStatusCodeSame(400);
        $this->assertJsonContains(['message' => "Type d'entité invalide."]);
    }

    public function testCreateCommentMissingEntityId(): void
    {
        $client = $this->createViewerClient();
        $client->request('POST', '/api/comments', [
            'json' => [
                'content'    => 'Missing ID',
                'entityType' => 'machine',
                'entityId'   => '',
            ],
        ]);

        $this->assertResponseStatusCodeSame(400);
    }

    public function testResolveComment(): void
    {
        $machine = $this->createMachine('Machine A');

        $viewerClient = $this->createViewerClient();
        $response     = $viewerClient->request('POST', '/api/comments', [
            'json' => [
                'content'    => 'To resolve',
                'entityType' => 'machine',
                'entityId'   => $machine->getId(),
            ],
        ]);

        $data      = $response->toArray();
        $commentId = $data['id'];

        $gestionnaireClient = $this->createGestionnaireClient();
        $gestionnaireClient->request('PATCH', sprintf('/api/comments/%s/resolve', $commentId));

        $this->assertResponseIsSuccessful();
        $this->assertJsonContains(['status' => 'resolved']);
    }

    public function testResolveCommentNotFound(): void
    {
        $client = $this->createGestionnaireClient();
        $client->request('PATCH', '/api/comments/nonexistent-id/resolve');

        $this->assertResponseStatusCodeSame(404);
    }

    public function testUnresolvedCount(): void
    {
        $machine = $this->createMachine('Machine A');

        $client = $this->createViewerClient();
        $client->request('POST', '/api/comments', [
            'json' => [
                'content'    => 'Open 1',
                'entityType' => 'machine',
                'entityId'   => $machine->getId(),
            ],
        ]);
        $client->request('POST', '/api/comments', [
            'json' => [
                'content'    => 'Open 2',
                'entityType' => 'machine',
                'entityId'   => $machine->getId(),
            ],
        ]);

        $client->request('GET', '/api/comments/stats/unresolved-count');

        $this->assertResponseIsSuccessful();
        $this->assertJsonContains(['count' => 2]);
    }

    public function testCreateCommentJsonReturnsDocumentsArray(): void
    {
        $machine = $this->createMachine('Machine A');

        $client   = $this->createViewerClient();
        $response = $client->request('POST', '/api/comments', [
            'json' => [
                'content'    => 'No files',
                'entityType' => 'machine',
                'entityId'   => $machine->getId(),
            ],
        ]);

        $this->assertResponseStatusCodeSame(201);
        $data = $response->toArray();
        $this->assertSame([], $data['documents']);
    }

    public function testCreateCommentWithFile(): void
    {
        $machine = $this->createMachine('Machine A');

        $client = $this->createViewerClient();

        $tmpFile = tempnam(sys_get_temp_dir(), 'test_');
        file_put_contents($tmpFile, 'test file content');

        $uploadedFile = new UploadedFile(
            $tmpFile,
            'test-doc.pdf',
            'application/pdf',
            null,
            true,
        );

        $client->request('POST', '/api/comments', [
            'extra' => [
                'parameters' => [
                    'content'    => 'Comment with file',
                    'entityType' => 'machine',
                    'entityId'   => $machine->getId(),
                    'entityName' => 'Machine A',
                ],
                'files' => [
                    'files' => [$uploadedFile],
                ],
            ],
        ]);

        $this->assertResponseStatusCodeSame(201);
        $data = json_decode($client->getResponse()->getContent(), true);
        $this->assertSame('Comment with file', $data['content']);
        $this->assertCount(1, $data['documents']);
        $this->assertSame('test-doc.pdf', $data['documents'][0]['filename']);
        $this->assertArrayHasKey('fileUrl', $data['documents'][0]);
        $this->assertArrayHasKey('downloadUrl', $data['documents'][0]);

        @unlink($tmpFile);
    }

    public function testCreateCommentWithMultipleFiles(): void
    {
        $machine = $this->createMachine('Machine A');

        $client = $this->createViewerClient();

        $tmpFile1 = tempnam(sys_get_temp_dir(), 'test_');
        file_put_contents($tmpFile1, 'content 1');
        $tmpFile2 = tempnam(sys_get_temp_dir(), 'test_');
        file_put_contents($tmpFile2, 'content 2');

        $file1 = new UploadedFile($tmpFile1, 'doc1.pdf', 'application/pdf', null, true);
        $file2 = new UploadedFile($tmpFile2, 'doc2.png', 'image/png', null, true);

        $client->request('POST', '/api/comments', [
            'extra' => [
                'parameters' => [
                    'content'    => 'Multiple files',
                    'entityType' => 'machine',
                    'entityId'   => $machine->getId(),
                ],
                'files' => [
                    'files' => [$file1, $file2],
                ],
            ],
        ]);

        $this->assertResponseStatusCodeSame(201);
        $data = json_decode($client->getResponse()->getContent(), true);
        $this->assertCount(2, $data['documents']);

        @unlink($tmpFile1);
        @unlink($tmpFile2);
    }
}
