<?php

declare(strict_types=1);

namespace FecaMailshots\Tests\Unit;

use FecaMailshots\Application\SourceMetadataProvider;

final class FakeMetadataProvider implements SourceMetadataProvider
{
    /** @var array<string, list<string>> */
    private array $fields;

    /** @param array<string, list<string>> $fields */
    public function __construct(array $fields)
    {
        $this->fields = $fields;
    }

    public function sourceExists(string $source): bool
    {
        return isset($this->fields[$source]);
    }

    public function sourceFields(string $source): array
    {
        return $this->fields[$source] ?? [];
    }

    public function hasEmailField(string $source): bool
    {
        return in_array('Email', $this->fields[$source] ?? [], true) || in_array('email', $this->fields[$source] ?? [], true);
    }

    public function joinPath(string $left, string $right): ?array
    {
        $pairs = [
            'contacts|accounts' => ['left' => 'contacts.Accountid', 'right' => 'accounts.ID'],
            'accounts|contacts' => ['left' => 'accounts.ID', 'right' => 'contacts.Accountid'],
            'renewals|accounts' => ['left' => 'renewals.account_id', 'right' => 'accounts.ID'],
            'accounts|renewals' => ['left' => 'accounts.ID', 'right' => 'renewals.account_id'],
            'renewals|contacts' => ['left' => 'renewals.account_id', 'right' => 'contacts.Accountid'],
            'contacts|renewals' => ['left' => 'contacts.Accountid', 'right' => 'renewals.account_id'],
            'articles|pages' => ['left' => 'articles.PageID', 'right' => 'pages.ID'],
            'pages|articles' => ['left' => 'pages.ID', 'right' => 'articles.PageID'],
            'pages|issues' => ['left' => 'pages.Issue', 'right' => 'issues.ID'],
            'issues|pages' => ['left' => 'issues.ID', 'right' => 'pages.Issue'],
            'ads|pages' => ['left' => 'ads.PageID', 'right' => 'pages.ID'],
            'pages|ads' => ['left' => 'pages.ID', 'right' => 'ads.PageID'],
            'ads|advertisers' => ['left' => 'ads.Advertiser', 'right' => 'advertisers.AdvertiserName'],
            'advertisers|ads' => ['left' => 'advertisers.AdvertiserName', 'right' => 'ads.Advertiser'],
            'invoices|ads' => ['left' => 'invoices.ad_id', 'right' => 'ads.ID'],
            'ads|invoices' => ['left' => 'ads.ID', 'right' => 'invoices.ad_id'],
            'invoices|issues' => ['left' => 'invoices.issue_id', 'right' => 'issues.ID'],
            'issues|invoices' => ['left' => 'issues.ID', 'right' => 'invoices.issue_id'],
            'invoices|pages' => ['left' => 'invoices.issue_id', 'right' => 'pages.Issue'],
            'pages|invoices' => ['left' => 'pages.Issue', 'right' => 'invoices.issue_id'],
        ];
        return $pairs[$left . '|' . $right] ?? null;
    }

    public function allKnownSources(): array
    {
        return array_keys($this->fields);
    }

    public function sourceTable(string $source): ?string
    {
        return $source;
    }

    public function fieldSql(string $source, string $field, string $alias): ?string
    {
        if (!isset($this->fields[$source]) || !in_array($field, $this->fields[$source], true)) {
            return null;
        }
        return $alias . '.`' . str_replace('`', '``', $field) . '`';
    }
}
