<?php

use App\Database\Seeds\DatabaseSeeder;
use CodeIgniter\Shield\Models\UserModel;
use CodeIgniter\Shield\Test\AuthenticationTesting;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\DatabaseTestTrait;
use CodeIgniter\Test\FeatureTestTrait;

/**
 * @internal
 */
final class ReportsFeatureTest extends CIUnitTestCase
{
    use AuthenticationTesting;
    use DatabaseTestTrait;
    use FeatureTestTrait;

    protected $migrate = true;
    protected $refresh = true;
    protected $seed = DatabaseSeeder::class;
    protected $DBGroup = 'tests';
    protected $namespace = ['CodeIgniter\\Shield', 'CodeIgniter\\Settings', 'App'];

    public function testCoachPromotionReportIsScoped(): void
    {
        $coach = $this->findUserByEmail('andrei@academia.local');

        $this->actingAs($coach);

        $report = $this->withSession($_SESSION)->get('/reports?report=ready-for-promotion');

        $report->assertOK();
        $report->assertSee('Luca Marin');
        $report->assertDontSee('Maria Enache');
    }

    public function testAdminCanViewChildProgressReport(): void
    {
        $admin   = $this->findUserByEmail('admin@academia.local');
        $childId = (int) db_connect()->table('children')->select('id')->where('full_name', 'Luca Marin')->get()->getRowArray()['id'];

        $this->actingAs($admin);

        $report = $this->withSession($_SESSION)->get('/reports?report=child-progress&child_id=' . $childId);

        $report->assertOK();
        $report->assertSee('Progres copil: Luca Marin');
        $report->assertSee('Quick Check');
    }

    public function testCoachCanExportScopedCsvReport(): void
    {
        $coach = $this->findUserByEmail('andrei@academia.local');

        $this->actingAs($coach);

        $export = $this->withSession($_SESSION)->get('/reports/export/csv?report=ready-for-promotion');

        $export->assertOK();
        $export->assertHeader('Content-Type', 'text/csv; charset=UTF-8');
        $this->assertStringContainsString('.csv', $export->response()->getHeaderLine('Content-Disposition'));
        $this->assertStringContainsString('Luca Marin', $export->response()->getBody());
        $this->assertStringNotContainsString('Maria Enache', $export->response()->getBody());
    }

    public function testAdminCanExportPdfReport(): void
    {
        $admin = $this->findUserByEmail('admin@academia.local');

        $this->actingAs($admin);

        $export = $this->withSession($_SESSION)->get('/reports/export/pdf?report=children-by-level');

        $export->assertOK();
        $export->assertHeader('Content-Type', 'application/pdf');
        $this->assertStringContainsString('.pdf', $export->response()->getHeaderLine('Content-Disposition'));
        $this->assertStringStartsWith('%PDF-', $export->response()->getBody());
    }

    public function testParentCannotExportReports(): void
    {
        $parent = $this->findUserByEmail('cristina@academia.local');

        $this->actingAs($parent);

        $export = $this->withSession($_SESSION)->get('/reports/export/csv?report=children-by-level');

        $export->assertStatus(403);
    }

    private function findUserByEmail(string $email)
    {
        return model(UserModel::class)->findByCredentials(['email' => $email]);
    }
}
