<?php

namespace AutoAdmin\Bundle\Content\Site;

use AutoAdmin\Bundle\Content\Entity\Domain;
use AutoAdmin\Bundle\Content\Entity\Locale;
use AutoAdmin\Bundle\Content\Entity\Site;
use AutoAdmin\Bundle\Content\Model\SiteConfig;
use Doctrine\Persistence\ManagerRegistry;
use RuntimeException;

class SiteConfigBuilderHelper
{
    public function __construct(
        protected ManagerRegistry $doctrine,
    ) {
    }

    public function getSiteConfigByLocale(Site $site, Locale $locale): ?SiteConfig
    {
        $configs = $this->buildSiteConfigs($site);

        foreach ($configs as $config) {
            if ($config->getLocale() === $locale) {
                return $config;
            }
        }

        return null;
    }

    /**
     * @param Site $site
     * @return SiteConfig[]
     */
    public function buildSiteConfigs(Site $site): array
    {
        $encounteredLocales = [];
        $encounteredDomains = [];

        $siteConfigs = [];

        $siteSlug = $site->getSlug();

        foreach ($site->getDomains() as $domain) {
            if (in_array($dom = $domain->getDomain(), $encounteredDomains)) {
                $error = "Invalid sites-config, multiple times domain: $dom";
                throw new RuntimeException($error);
            }
            $encounteredDomains[] = $dom;

            foreach ($domain->getLocales() as $locale) {
                if (in_array($code = $locale->getCode(), $encounteredLocales)) {
                    $error = "Invalid sites-config, same locale ($code) on different domains (on site: $siteSlug).";
                    throw new RuntimeException($error);
                }
                $encounteredLocales[] = $code;

                $siteConfigs[] = new SiteConfig($site, $domain, $locale);
            }
        }

        return $siteConfigs;
    }

    /**
     * @return SiteConfig[]
     */
    public function buildAllSitesConfigs(): array
    {
        $configs = [];

        $sites = $this->doctrine->getManager()->getRepository(Site::class)->findAll();
        foreach ($sites as $site) {
            $configs = [...$configs, ...$this->buildSiteConfigs($site)];
        }

        return $configs;
    }

    public function getDomain(Site $site, Locale $locale): Domain|null
    {
        $configs = $this->buildSiteConfigs($site);
        foreach ($configs as $config) {
            if ($config->getLocale() === $locale) {
                return $config->getDomain();
            }
        }

        return null;
    }

    /**
     * Mainly used for debugging
     *
     * @param SiteConfig[] $siteConfigs
     * @return array
     */
    public function convertToStringMatrix(array $siteConfigs): array
    {
        $m = [];

        foreach ($siteConfigs as $siteConfig) {
            $k = sprintf(
                "%s:%s",
                $siteConfig->getDomain()->getDomain(),
                $siteConfig->getLocale()->getCode(),
            );
            $v = $siteConfig->getSite()->getSlug();
            if (!array_key_exists($v, $m)) {
                $m[$k] = $v;
            }
        }

        return $m;
    }
}
