<?php

declare(strict_types=1);

use Builder\Seo\Settings\SeoSettings;
use Builder\Seo\Support\SchemaOrgBuilder;
use Spatie\SchemaOrg\LocalBusiness;
use Spatie\SchemaOrg\Organization;
use Spatie\SchemaOrg\Person;
use Spatie\SchemaOrg\WebSite;

function makeSettings(array $overrides = []): SeoSettings
{
    /** @var SeoSettings $settings */
    $settings = app(SeoSettings::class);

    foreach ($overrides as $key => $value) {
        $settings->{$key} = $value;
    }

    return $settings;
}

it('build with schema_type Organization returns Organization schema', function (): void {
    $schema = (new SchemaOrgBuilder)->build(makeSettings(['schema_type' => 'Organization']));

    expect($schema)->toBeInstanceOf(Organization::class);
});

it('build with schema_type Person returns Person schema', function (): void {
    $schema = (new SchemaOrgBuilder)->build(makeSettings(['schema_type' => 'Person']));

    expect($schema)->toBeInstanceOf(Person::class);
});

it('build with schema_type LocalBusiness returns LocalBusiness schema', function (): void {
    $schema = (new SchemaOrgBuilder)->build(makeSettings(['schema_type' => 'LocalBusiness']));

    expect($schema)->toBeInstanceOf(LocalBusiness::class);
});

it('build with schema_type WebSite returns WebSite schema', function (): void {
    $schema = (new SchemaOrgBuilder)->build(makeSettings(['schema_type' => 'WebSite']));

    expect($schema)->toBeInstanceOf(WebSite::class);
});

it('build with unknown schema_type falls back to Organization', function (): void {
    $schema = (new SchemaOrgBuilder)->build(makeSettings(['schema_type' => 'Unknown']));

    expect($schema)->toBeInstanceOf(Organization::class);
});

it('toScript returns a string containing application/ld+json', function (): void {
    $output = (new SchemaOrgBuilder)->toScript(makeSettings());

    expect($output)->toContain('application/ld+json');
});

it('toScript includes the configured schema_name', function (): void {
    $settings = makeSettings([
        'schema_type' => 'Organization',
        'schema_name' => 'Acme Corp',
    ]);

    $output = (new SchemaOrgBuilder)->toScript($settings);

    expect($output)->toContain('Acme Corp');
});

it('build falls back to site_name when schema_name is empty', function (): void {
    $settings = makeSettings([
        'schema_type' => 'Organization',
        'schema_name' => '',
        'site_name' => 'My Website',
    ]);

    $output = (new SchemaOrgBuilder)->toScript($settings);

    expect($output)->toContain('My Website');
});

it('build Organization includes url, logo and description when set', function (): void {
    $settings = makeSettings([
        'schema_type' => 'Organization',
        'schema_name' => 'Acme',
        'schema_url' => 'https://acme.example',
        'schema_logo_url' => 'https://acme.example/logo.png',
        'schema_description' => 'We make things.',
    ]);

    $output = (new SchemaOrgBuilder)->toScript($settings);

    expect($output)
        ->toContain('acme.example')
        ->toContain('logo.png')
        ->toContain('We make things');
});

it('build Person includes url and description when set', function (): void {
    $settings = makeSettings([
        'schema_type' => 'Person',
        'schema_name' => 'Jane Doe',
        'schema_url' => 'https://janedoe.example',
        'schema_description' => 'Developer.',
    ]);

    $output = (new SchemaOrgBuilder)->toScript($settings);

    expect($output)
        ->toContain('janedoe.example')
        ->toContain('Developer');
});

it('build LocalBusiness includes url, logo and description when set', function (): void {
    $settings = makeSettings([
        'schema_type' => 'LocalBusiness',
        'schema_name' => 'Corner Store',
        'schema_url' => 'https://corner.example',
        'schema_logo_url' => 'https://corner.example/logo.png',
        'schema_description' => 'Local shop.',
    ]);

    $output = (new SchemaOrgBuilder)->toScript($settings);

    expect($output)
        ->toContain('corner.example')
        ->toContain('Local shop');
});

it('build WebSite includes url and description when set', function (): void {
    $settings = makeSettings([
        'schema_type' => 'WebSite',
        'schema_name' => 'My Site',
        'schema_url' => 'https://mysite.example',
        'schema_description' => 'A great site.',
    ]);

    $output = (new SchemaOrgBuilder)->toScript($settings);

    expect($output)
        ->toContain('mysite.example')
        ->toContain('A great site');
});
