<?php

declare(strict_types=1);

namespace Ig\IgReservations\Upgrades;

use Doctrine\DBAL\ArrayParameterType;
use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Install\Attribute\UpgradeWizard;
use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite;
use TYPO3\CMS\Install\Updates\UpgradeWizardInterface;

#[UpgradeWizard('igReservationsPluginToCType')]
final class PluginToCTypeUpgradeWizard implements UpgradeWizardInterface
{
    private const PLUGIN_MAPPING = [
        'igreservations_calendarlist' => 'igreservations_calendarlist',
        'igreservations_publiccalendar' => 'igreservations_publiccalendar',
        'igreservations_ajax' => 'igreservations_ajax',
        'igreservations_eventtodo' => 'igreservations_eventtodo',
        'igreservations_overview' => 'igreservations_overview',
        'igreservations_eventlist' => 'igreservations_eventlist',
        'igreservations_feusermanagement' => 'igreservations_feusermanagement',
        'igreservations_locationmanagement' => 'igreservations_locationmanagement',
        'igreservations_locationlist' => 'igreservations_locationlist',
        'igreservations_alarm' => 'igreservations_alarm',
        'igreservations_myreservations' => 'igreservations_myreservations',
        'igreservations_statistics' => 'igreservations_statistics',
    ];

    public function getIdentifier(): string
    {
        return 'igReservationsPluginToCType';
    }

    public function getTitle(): string
    {
        return 'Migrate ig_reservations plugins from list_type to CType';
    }

    public function getDescription(): string
    {
        return 'Migrates all ig_reservations content elements from using list_type to the new TYPO3 14 CType approach.';
    }

    public function getPrerequisites(): array
    {
        return [
            DatabaseUpdatedPrerequisite::class,
        ];
    }

    public function updateNecessary(): bool
    {
        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
            ->getQueryBuilderForTable('tt_content');

        $count = $queryBuilder
            ->count('uid')
            ->from('tt_content')
            ->where(
                $queryBuilder->expr()->eq(
                    'CType',
                    $queryBuilder->createNamedParameter('list')
                ),
                $queryBuilder->expr()->in(
                    'list_type',
                    $queryBuilder->createNamedParameter(
                        array_keys(self::PLUGIN_MAPPING),
                        ArrayParameterType::STRING
                    )
                )
            )
            ->executeQuery()
            ->fetchOne();

        return $count > 0;
    }

    public function executeUpdate(): bool
    {
        $connection = GeneralUtility::makeInstance(ConnectionPool::class)
            ->getConnectionForTable('tt_content');

        foreach (self::PLUGIN_MAPPING as $oldListType => $newCType) {
            $queryBuilder = $connection->createQueryBuilder();
            $queryBuilder
                ->update('tt_content')
                ->set('CType', $newCType)
                ->set('list_type', '')
                ->where(
                    $queryBuilder->expr()->eq(
                        'CType',
                        $queryBuilder->createNamedParameter('list')
                    ),
                    $queryBuilder->expr()->eq(
                        'list_type',
                        $queryBuilder->createNamedParameter($oldListType)
                    )
                )
                ->executeStatement();
        }

        return true;
    }
}
