<?php

namespace Internetgalerie\IgDatapoolFe\DataHandling;

use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\SysLog\Error as SystemLogErrorClassification;
use TYPO3\CMS\Core\Utility\GeneralUtility;

class DataHandler
{
    /**
     * Localizes a record to another system language
     *
     * @param string $table Table name
     * @param int $uid Record uid (to be localized)
     * @param int $language Language ID (from sys_language table)
     * @return int|bool The uid (int) of the new translated record or FALSE (bool) if something went wrong
     */
    public function localize($table, $uid, $language)
    {
        $newId = false;
        $uid = (int)$uid;


        if (!$GLOBALS['TCA'][$table]['ctrl']['languageField'] || !$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']) {
            $this->newlog('Localization failed; "languageField" and "transOrigPointerField" must be defined for the table ' . $table, SystemLogErrorClassification::USER_ERROR);
            return false;
        }
        // fetch record to translate
        $langRec = $this->getRecord($table, $uid);
        if (!$langRec) {
            $this->newlog('Sys language UID "' . $language . '" not found valid!', SystemLogErrorClassification::USER_ERROR);
            return false;
        }

        // Make sure that records which are translated from another language than the default language have a correct
        // localization source set themselves, before translating them to another language.
        /*
        if ((int)$langRec[$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']] !== 0
            && $langRec[$GLOBALS['TCA'][$table]['ctrl']['languageField']] > 0) {
            $localizationParentRecord = BackendUtility::getRecord(
                $table,
                $langRec[$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']]
            );
            if ((int)$localizationParentRecord[$GLOBALS['TCA'][$table]['ctrl']['languageField']] !== 0) {
                $this->newlog('Localization failed; Source record ' . $table . ':' . $localizationParentRecord['uid'] . ' contained a reference to an original record that is not a default record (which is strange)!', SystemLogErrorClassification::USER_ERROR);
                return false;
            }
        }
        */

        // Default language records must never have a localization parent as they are the origin of any translation.
        if ((int)$langRec[$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']] !== 0
            && (int)$langRec[$GLOBALS['TCA'][$table]['ctrl']['languageField']] === 0) {
            $this->newlog('Localization failed; Source record ' . $table . ':' . $langRec['uid'] . ' contained a reference to an original default record but is a default record itself (which is strange)!', SystemLogErrorClassification::USER_ERROR);
            return false;
        }
        // localization exists
        $recordLocalizations = $this->getRecord($table, $uid, $language, (int)$langRec['pid']);

        if (!empty($recordLocalizations)) {
            return false;
        }

        // @todo ugly - make it more general
        $origUid = $langRec['uid'];
        unset($langRec['uid']);
        $langRec['tstamp'] = time();
        $langRec['crdate'] = time();
        $langRec['sys_language_uid'] = $language;
        $langRec['l10n_parent'] = $origUid ;

        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
        $affectedRows = $queryBuilder->insert($table)->values($langRec)->executeStatement();
        $conn = $queryBuilder->getConnection();
        $lastInsertId = $conn->lastInsertId();
        return  $lastInsertId;
    }

    protected function getRecord($table, $uid, $language = null, $pid = null)
    {
        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
        $constraints = [
                $queryBuilder->expr()->eq(
                    'uid',
                    $queryBuilder->createNamedParameter($uid, Connection::PARAM_INT)
                )
        ];
        if ($language !== null) {
            $constraints[] = $queryBuilder->expr()->eq(
                'sys_language_uid',
                $queryBuilder->createNamedParameter($language, Connection::PARAM_INT)
            );
        }
        $result = $queryBuilder->select('*')->from($table)->where(
            $queryBuilder->expr()->and(...$constraints)
        )->executeQuery();
        return $result->fetchAssociative();
    }
}
