<?php
namespace Zab\ZabSite\Utility;

use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility;

class ContentOptions
{
    /**
     * Layout options for blocks like Fees Cards
     */
    public function getLayoutOptions(array &$params) {
        $params['items'][] = ['label' => '50% / 50% (Default)', 'value' => 'default'];
        $params['items'][] = ['label' => '70% / 30% (Main and small card)', 'value' => '70-30'];
        $params['items'][] = ['label' => '30% / 70% (Small and main card)', 'value' => '30-70'];
    }

    /**
     * Color options for content
     */
    public function getColors(array &$params) {
        $params['items'][] = ['label' => 'Tea green', 'value' => 'teagreen'];
        $params['items'][] = ['label' => 'Columbia', 'value' => 'columbia'];
        $params['items'][] = ['label' => 'Feldspar', 'value' => 'feldspar'];
        $params['items'][] = ['label' => 'Papaya', 'value' => 'papaya'];
    }

    /**
     * Color options for content
     */
    public function getColorSimple(array &$params) {
        $params['items'][] = ['label' => 'Tea green', 'value' => 'teagreen'];
        $params['items'][] = ['label' => 'Columbia', 'value' => 'columbia'];
    }

    /**
     * Downloads filtered by category, keeping already selected items
     */
    /**
     * Find a field value in $row by suffix, regardless of prefix.
     */
    private function findFieldValue(array $row, string $suffix) {
        foreach ($row as $key => $value) {
            if (str_ends_with($key, '_' . $suffix) || $key === $suffix) {
                return $value;
            }
        }
        return null;
    }

    /**
     * Language of the record currently being edited (sys_language_uid can arrive as array or scalar)
     */
    private function getRowLanguageUid(array $row): int
    {
        $value = $row['sys_language_uid'] ?? 0;
        return is_array($value) ? (int)($value[0] ?? 0) : (int)$value;
    }

    public function getDownloadsByCategory(array &$params) {
        $connection = GeneralUtility::makeInstance(ConnectionPool::class);

        // Clear items loaded by foreign_table to avoid duplicates
        $params['items'] = [];

        // Dynamically find fields by suffix (works with any ContentBlock prefix)
        $row = $params['row'] ?? [];
        $selectedCategory = 0;
        $catValue = $this->findFieldValue($row, 'downloads_category');
        if ($catValue !== null) {
            $selectedCategory = is_array($catValue)
                ? (int)($catValue[0] ?? 0)
                : (int)$catValue;
        }

        // Get already selected download UIDs
        $selectedUids = [];
        $recValue = $this->findFieldValue($row, 'downloads_records');
        if ($recValue !== null && !empty($recValue)) {
            if (is_string($recValue)) {
                $selectedUids = GeneralUtility::intExplode(',', $recValue, true);
            } elseif (is_array($recValue)) {
                foreach ($recValue as $item) {
                    if (is_array($item) && isset($item['uid'])) {
                        $selectedUids[] = (int)$item['uid'];
                    } elseif (is_numeric($item)) {
                        $selectedUids[] = (int)$item;
                    }
                }
            }
        }

        // Fetch downloads: all if category=0, or filtered by category
        $qb = $connection->getQueryBuilderForTable('tx_zab_downloads');
        $qb->select('uid', 'zab_recorddownloads_download_name', 'zab_recorddownloads_download_category')
            ->from('tx_zab_downloads');
        if ($selectedCategory > 0) {
            $qb->where(
                $qb->expr()->eq('zab_recorddownloads_download_category', $qb->createNamedParameter($selectedCategory, \TYPO3\CMS\Core\Database\Connection::PARAM_INT))
            );
        }
        $qb->orderBy('sorting');
        $categoryDownloads = $qb->executeQuery()->fetchAllAssociative();

        $addedUids = [];
        foreach ($categoryDownloads as $download) {
            $params['items'][] = [
                'label' => $download['zab_recorddownloads_download_name'],
                'value' => (int)$download['uid'],
            ];
            $addedUids[] = (int)$download['uid'];
        }

        // Add already selected items that are NOT in the current category
        $missingUids = array_diff($selectedUids, $addedUids);
        if (!empty($missingUids)) {
            $qb = $connection->getQueryBuilderForTable('tx_zab_downloads');
            $qb->select('uid', 'zab_recorddownloads_download_name')
                ->from('tx_zab_downloads')
                ->where(
                    $qb->expr()->in('uid', $missingUids)
                )
                ->orderBy('sorting');
            $extraDownloads = $qb->executeQuery()->fetchAllAssociative();
            foreach ($extraDownloads as $download) {
                $params['items'][] = [
                    'label' => $download['zab_recorddownloads_download_name'],
                    'value' => (int)$download['uid'],
                ];
            }
        }
    }

    public function getFaqsByCategory(array &$params) {
        $connection = GeneralUtility::makeInstance(ConnectionPool::class);

        // Clear items loaded by foreign_table to avoid duplicates
        $params['items'] = [];

        // Dynamically find fields by suffix (works with any ContentBlock prefix)
        $row = $params['row'] ?? [];
        $selectedCategory = 0;
        $catValue = $this->findFieldValue($row, 'faqs_category');
        if ($catValue !== null) {
            $selectedCategory = is_array($catValue)
                ? (int)($catValue[0] ?? 0)
                : (int)$catValue;
        }

        // Get already selected FAQ UIDs
        $selectedUids = [];
        $recValue = $this->findFieldValue($row, 'faqs_records');
        if ($recValue !== null && !empty($recValue)) {
            if (is_string($recValue)) {
                $selectedUids = GeneralUtility::intExplode(',', $recValue, true);
            } elseif (is_array($recValue)) {
                foreach ($recValue as $item) {
                    if (is_array($item) && isset($item['uid'])) {
                        $selectedUids[] = (int)$item['uid'];
                    } elseif (is_numeric($item)) {
                        $selectedUids[] = (int)$item;
                    }
                }
            }
        }

        // Fetch FAQs: all if category=0, or filtered by category; only in the language being edited
        $currentLanguage = $this->getRowLanguageUid($row);
        $qb = $connection->getQueryBuilderForTable('tx_zab_faqs');
        $qb->select('uid', 'zab_recordfaqs_label', 'zab_recordfaqs_categories', 'l10n_source')
            ->from('tx_zab_faqs')
            ->where(
                $qb->expr()->eq('sys_language_uid', $qb->createNamedParameter($currentLanguage, \TYPO3\CMS\Core\Database\Connection::PARAM_INT))
            );
        if ($selectedCategory > 0) {
            $qb->andWhere(
                'FIND_IN_SET(' . $qb->createNamedParameter($selectedCategory, \TYPO3\CMS\Core\Database\Connection::PARAM_INT) . ', zab_recordfaqs_categories)'
            );
        }
        $qb->orderBy('sorting');
        $categoryFaqs = $qb->executeQuery()->fetchAllAssociative();

        $addedUids = [];
        foreach ($categoryFaqs as $faq) {
            $addedUids[] = (int)$faq['uid'];
        }

        // Add already selected items that are NOT in the current category
        $missingUids = array_diff($selectedUids, $addedUids);
        $extraFaqs = [];
        if (!empty($missingUids)) {
            $qb = $connection->getQueryBuilderForTable('tx_zab_faqs');
            $qb->select('uid', 'zab_recordfaqs_label', 'l10n_source')
                ->from('tx_zab_faqs')
                ->where(
                    $qb->expr()->in('uid', $missingUids)
                )
                ->orderBy('sorting');
            $extraFaqs = $qb->executeQuery()->fetchAllAssociative();
        }

        // In non-default languages, show the default-language label as a hint in brackets
        $defaultLabels = $this->getDefaultLanguageLabels($connection, 'tx_zab_faqs', 'zab_recordfaqs_label', array_merge($categoryFaqs, $extraFaqs), $currentLanguage);

        foreach (array_merge($categoryFaqs, $extraFaqs) as $faq) {
            $params['items'][] = [
                'label' => $this->withDefaultLanguageHint($faq['zab_recordfaqs_label'], (int)($faq['l10n_source'] ?? 0), $currentLanguage, $defaultLabels),
                'value' => (int)$faq['uid'],
            ];
        }
    }

    /**
     * FAQ categories filtered by the language being edited, with default-language label as a hint
     */
    public function getFaqsCategoryOptions(array &$params) {
        $connection = GeneralUtility::makeInstance(ConnectionPool::class);

        // Clear items loaded by foreign_table to avoid duplicates
        $params['items'] = [];
        $params['items'][] = ['label' => '[ All ]', 'value' => 0];

        $row = $params['row'] ?? [];
        $currentLanguage = $this->getRowLanguageUid($row);

        $qb = $connection->getQueryBuilderForTable('tx_zab_faqs_category');
        $qb->select('uid', 'zab_recordfaqscategory_faqs_category', 'l10n_source')
            ->from('tx_zab_faqs_category')
            ->where(
                $qb->expr()->eq('sys_language_uid', $qb->createNamedParameter($currentLanguage, \TYPO3\CMS\Core\Database\Connection::PARAM_INT))
            )
            ->orderBy('sorting');
        $categories = $qb->executeQuery()->fetchAllAssociative();

        $defaultLabels = $this->getDefaultLanguageLabels($connection, 'tx_zab_faqs_category', 'zab_recordfaqscategory_faqs_category', $categories, $currentLanguage);

        foreach ($categories as $category) {
            $params['items'][] = [
                'label' => $this->withDefaultLanguageHint($category['zab_recordfaqscategory_faqs_category'], (int)($category['l10n_source'] ?? 0), $currentLanguage, $defaultLabels),
                'value' => (int)$category['uid'],
            ];
        }
    }

    /**
     * Info-Hub categories filtered by the language being edited, with default-language label as a hint
     */
    public function getInfoHubCategoryOptions(array &$params) {
        $connection = GeneralUtility::makeInstance(ConnectionPool::class);

        // Clear items loaded by foreign_table to avoid duplicates
        $params['items'] = [];

        $row = $params['row'] ?? [];
        $currentLanguage = $this->getRowLanguageUid($row);

        $qb = $connection->getQueryBuilderForTable('tx_zab_info_hub_category');
        $qb->select('uid', 'zab_recordinfohubcategory_info-hub_category', 'l10n_source')
            ->from('tx_zab_info_hub_category')
            ->where(
                $qb->expr()->eq('sys_language_uid', $qb->createNamedParameter($currentLanguage, \TYPO3\CMS\Core\Database\Connection::PARAM_INT))
            )
            ->orderBy('sorting');
        $categories = $qb->executeQuery()->fetchAllAssociative();

        $defaultLabels = $this->getDefaultLanguageLabels($connection, 'tx_zab_info_hub_category', 'zab_recordinfohubcategory_info-hub_category', $categories, $currentLanguage);

        foreach ($categories as $category) {
            $params['items'][] = [
                'label' => $this->withDefaultLanguageHint($category['zab_recordinfohubcategory_info-hub_category'], (int)($category['l10n_source'] ?? 0), $currentLanguage, $defaultLabels),
                'value' => (int)$category['uid'],
            ];
        }
    }

    /**
     * Record title (label_userFunc) for tx_zab_faqs_category: appends the default-language
     * label in brackets when the row being rendered (e.g. in a category tree) is a translation
     */
    public function getFaqsCategoryLabel(array &$params): void
    {
        $row = $params['row'] ?? [];
        $label = (string)($row['zab_recordfaqscategory_faqs_category'] ?? '');
        $currentLanguage = $this->getRowLanguageUid($row);
        $sourceUid = (int)($row['l10n_source'] ?? 0);

        if ($currentLanguage > 0 && $sourceUid > 0) {
            $connection = GeneralUtility::makeInstance(ConnectionPool::class);
            $defaultLabels = $this->getDefaultLanguageLabels($connection, 'tx_zab_faqs_category', 'zab_recordfaqscategory_faqs_category', [$row], $currentLanguage);
            $label = $this->withDefaultLanguageHint($label, $sourceUid, $currentLanguage, $defaultLabels);
        }

        $params['title'] = $label;
    }

    /**
     * Fetch default-language labels for a set of translated rows, keyed by their l10n_source uid
     */
    private function getDefaultLanguageLabels(ConnectionPool $connection, string $table, string $labelField, array $rows, int $currentLanguage): array
    {
        if ($currentLanguage <= 0) {
            return [];
        }
        $sourceUids = array_filter(array_unique(array_map(static fn(array $row) => (int)($row['l10n_source'] ?? 0), $rows)));
        if (empty($sourceUids)) {
            return [];
        }
        $qb = $connection->getQueryBuilderForTable($table);
        $rows = $qb->select('uid', $labelField)
            ->from($table)
            ->where($qb->expr()->in('uid', $sourceUids))
            ->executeQuery()->fetchAllAssociative();
        $labels = [];
        foreach ($rows as $row) {
            $labels[(int)$row['uid']] = $row[$labelField];
        }
        return $labels;
    }

    /**
     * Append the default-language label in brackets when editing a translation
     */
    private function withDefaultLanguageHint(string $label, int $sourceUid, int $currentLanguage, array $defaultLabels): string
    {
        if ($currentLanguage > 0 && $sourceUid > 0 && isset($defaultLabels[$sourceUid])) {
            $label .= ' [' . $defaultLabels[$sourceUid] . ']';
        }
        return $label;
    }

    /**
     * Slug prefix: display /download/ as non-editable prefix
     */
    public function getDownloadSlugPrefix(array $parameters): string
    {
        $site = $parameters['site'] ?? null;
        $base = $site ? rtrim((string)$site->getBase(), '/') : '';
        return $base . '/download';
    }

    /**
     * Slug prefix: display /info-hub/ as non-editable prefix
     */
    public function getInfohubSlugPrefix(array $parameters): string
    {
        $site = $parameters['site'] ?? null;
        $base = $site ? rtrim((string)$site->getBase(), '/') : '';
        return $base . '/info-hub';
    }
}
