<?php

/**
 * @file
 * Contains the definition of the custom module's primary functions and hooks.
 */

declare(strict_types=1);

use Drupal\Core\Database\Database;
use Drupal\languagewire_translation_provider\Adapter\TMGMT\TmgmtJobItem;
use Drupal\languagewire_translation_provider\Database\TablesInterface;
use Drupal\languagewire_translation_provider\Domain\DocumentStatus;
use Drupal\languagewire_translation_provider\Domain\ProjectStatus;

/**
 * Create the necessary tables for the module.
 */
function languagewire_translation_provider_schema(): array {
  return [
    TablesInterface::CONFIGURATION_ITEM => [
      'description' => t('Stores a collection of user selected LanguageWire business configuration items.'),
      'fields' => [
        'item_id' => [
          'description' => t('Item ID in the platform.'),
          'type' => 'int',
          'not null' => TRUE,
        ],
        'name' => [
          'description' => t('Item name in the platform.'),
          'type' => 'varchar',
          'length' => 190,
          'not null' => TRUE,
          'default' => '',
        ],
        'type' => [
          'description' => t('Item type.'),
          'type' => 'varchar',
          'length' => 20,
          'not null' => TRUE,
        ],
        'translator_id' => [
          'description' => t('TMGMT Translator ID'),
          'type' => 'varchar',
          'length' => 190,
          'not null' => TRUE,
        ]
      ],
      'primary key' => ['item_id', 'name', 'type', 'translator_id'],
      'unique keys' => [
        'item_id_name_type_translator_id' => ['item_id', 'name', 'type', 'translator_id']
      ],
    ],
    TablesInterface::PROJECTS => [
      'description' => t('Information about LanguageWire projects.'),
      'fields' => [
        'pid' => [
          'description' => t('Internal project ID'),
          'type' => 'serial', //Evaluates to INT auto_increment in MySQL
          'not null' => TRUE,
          'unsigned' => TRUE,
        ],
        'correlation_id' => [
          'description' => t('Project\'s correlation ID'),
          'type' => 'varchar',
          'length' => 50,
          'not null' => TRUE,
        ],
        'tmgmt_job_id' => [
          'description' => t('TMGMT Job ID'),
          'type' => 'int',
          'not null' => TRUE,
          'unsigned' => TRUE,
        ],
        'platform_id' => [
          'description' => t('Project ID in the LanguageWire platform'),
          'type' => 'int',
          'not null' => TRUE,
          'unsigned' => TRUE,
          'default' => 0,
        ],
        'platform_url' => [
          'description' => t('Project URL in the LanguageWire platform'),
          'type' => 'varchar',
          'length' => 255,
          'not null' => FALSE,
        ],
        'bundle_id' => [
          'description' => t('Bundle ID'),
          'type' => 'varchar',
          'length' => 255,
          'not null' => false,
         ],
        'status' => [
          'description' => t('Project status'),
          'type' => 'varchar',
          'length' => 100,
          'not null' => TRUE,
          'default' => DocumentStatus::UPLOADING_CONTENT
        ],
      ],
      'primary key' => ['pid'],
    ],
    TablesInterface::DOCUMENTS => [
      'description' => t('Information about project\'s documents.'),
      'fields' => [
          'did' => [
            'description' => t('Internal document ID'),
            'type' => 'serial', //Evaluates to INT auto_increment in MySQL
            'not null' => TRUE,
            'unsigned' => TRUE,
          ],
          'project_id' => [
            'description' => t('Internal project ID'),
            'type' => 'int',
            'not null' => TRUE,
            'unsigned' => TRUE,
          ],
          'tmgmt_item_id' => [
            'description' => t('TMGMT Job Item ID'),
            'type' => 'int',
            'not null' => TRUE,
            'unsigned' => TRUE,
          ],
          'platform_id' => [
            'description' => t('Document ID in the LanguageWire platform'),
            'type' => 'varchar',
            'length' => 255,
            'not null' => FALSE,
          ],
          'status' => [
            'description' => t('Document status'),
            'type' => 'varchar',
            'length' => 100,
            'not null' => TRUE,
            'default' => ProjectStatus::UPLOADING
          ],
          'errors' => [
            'description' => t('Document related errors'),
            'type' => 'text',
            'not null' => FALSE,
          ]
      ],
      'primary key' => ['did'],

      // From Drupal's official documentation (https://api.drupal.org/api/drupal/core!lib!Drupal!Core!Database!database.api.php/group/schemaapi/8.9.x):
      // This key is for documentation purposes only; foreign keys are not created in the database, nor are they enforced by Drupal.
      'foreign keys' => [
        'fk_documents_project_id_projects_pid' => [
          'table' => TablesInterface::PROJECTS,
          'columns' => [
            'project_id' => 'pid',
          ],
        ],
      ],
    ],
    TablesInterface::PROJECT_TEMPLATES => [
      'description' => t('Information about project templates.'),
      'fields' => [
        'template_id' => [
          'description' => t('Internal project template ID'),
          'type' => 'serial', //Evaluates to INT auto_increment in MySQL
          'not null' => TRUE,
          'unsigned' => TRUE,
        ],
        'name' => [
          'description' => t('Name of the project template'),
          'type' => 'varchar',
          'length' => 255,
          'not null' => TRUE,
        ],
        'server_id' => [
          'description' => t('Project Template ID in the LanguageWire platform'),
          'type' => 'int',
          'not null' => FALSE,
        ],
        'target_languages' => [
          'description' => t('Comma-separated list of target languages'),
          'type' => 'text',
          'not null' => TRUE,
        ],
        'user_id' => [
          'description' => t('Default user ID'),
          'type' => 'int',
          'not null' => TRUE,
        ],
        'work_area_id' => [
          'description' => t('Default work area ID'),
          'type' => 'int',
          'not null' => TRUE,
        ],
        'invoicing_account_id' => [
          'description' => t('Default invoicing account ID'),
          'type' => 'int',
          'not null' => TRUE,
        ],
        'translation_memory_id' => [
          'description' => t('Default translation memory ID'),
          'type' => 'int',
          'not null' => TRUE,
        ],
        'term_base_id' => [
          'description' => t('Default termbase ID'),
          'type' => 'int',
          'not null' => TRUE,
        ],
        'order_type' => [
          'description' => t('Default order type'),
          'type' => 'varchar',
          'length' => 190,
          'not null' => TRUE,
        ],
        'translator_id' => [
          'description' => t('TMGMT Translator ID'),
          'type' => 'varchar',
          'length' => 190,
          'not null' => TRUE,
        ],
        'description' => [
          'description' => t('Default description'),
          'type' => 'text',
          'not null' => FALSE,
        ],
        'project_name' => [
          'description' => t('Default project name'),
          'type' => 'text',
          'not null' => FALSE,
        ],
        'source_language' => [
          'description' => t('Default source language'),
          'type' => 'varchar',
          'length' => 100,
          'not null' => FALSE,
        ],
        'desired_deadline' => [
          'description' => t('Default deadline'),
          'type' => 'varchar',
          'length' => 100,
          'not null' => FALSE,
        ],
        'job_types' => [
          'description' => t('Comma-separated list of allowed job types'),
          'type' => 'text',
          'not null' => FALSE,
        ],
        'briefing_to_languagewire' => [
          'type' => 'text',
          'description' => "Briefing to LanguageWire",
          'not null' => FALSE,
        ]
      ],
      'primary key' => ['template_id'],
    ]
  ];
}

/**
 * Adds bundling support for projects
 */
function languagewire_translation_provider_update_9204(): string {
    $schema = Database::getConnection()->schema();

    // Projects table
    $projectBundleID = [
        'description' => t('Bundle ID'),
        'type' => 'varchar',
        'length' => 255,
        'not null' => FALSE,
    ];

    $schema->addField(TablesInterface::PROJECTS, 'bundle_id', $projectBundleID);

    return (string)t('Added bundling support.');
}

/**
 * Tries to increase the size of message field of tmgmt message table
 */
function languagewire_translation_provider_update_9205(): string {
  $schema = Database::getConnection()->schema();

  try {
    // Tmgmt message table
    $schema->changeField(
      'tmgmt_message',
      'message',
      'message',
      [
        'description' => t('Message'),
        'type' => 'text',
        'not null' => FALSE,
      ]
    );

    return (string)t('TMGMT message field type changed successfully.');
  } catch (Exception $e) {
    return (string)t("TMGMT message field type could not be changed: {$e->getMessage()}.");
  }
}

/**
 * Add the primary key to the configuration item table.
 */
function languagewire_translation_provider_update_9206(): string {
  $schema = Database::getConnection()->schema();
  try {
    $schema->addPrimaryKey(TablesInterface::CONFIGURATION_ITEM, ['item_id', 'name', 'type', 'translator_id']);
    return (string)t('Added primary key to the configuration item table.');
  } catch (Exception $e) {
    return (string)t("Could not add primary key to the configuration item table: {$e->getMessage()}.");
  }
}

/**
 * Update content settings structure.
 */
function languagewire_translation_provider_update_9207(): string {
  // Load all tmgmt_job entities.
  /** @var \Drupal\tmgmt\Entity\Job[] $jobs */
  $jobs = \Drupal::entityTypeManager()->getStorage('tmgmt_job')->loadMultiple();

  $job_item_storage = \Drupal::entityTypeManager()->getStorage('tmgmt_job_item');

  foreach ($jobs as $job) {
    if (!$job->hasTranslator() || $job->getTranslator()->getPluginId() !== 'languagewire') {
      continue;
    }

    $settings = $job->get('settings')->getValue();

    foreach ($settings as &$setting) {
      if (empty($setting['content_settings'])) {
        continue;
      }

      $updated_content_settings = [];

      foreach ($setting['content_settings'] as $item_delta => $item) {
        if (preg_match('/item-(\d+)/', $item_delta, $matches)) {
          $item_id = $matches[1];

          /** @var \Drupal\tmgmt\JobItemInterface $job_item */
          if ($job_item = $job_item_storage->load($item_id)) {
            $tmgmt_job_item = new TmgmtJobItem($job_item);

            $item_key = $tmgmt_job_item->itemKey();
            $updated_content_settings['item-' . $item_key] = [];
            foreach ($setting['content_settings'][$item_delta] as $content_delta => $content_item) {
              if (preg_match('/content-' . $item_id . '__(.+)/', $content_delta, $content_matches)) {
                $content_key = $content_matches[1];
                $updated_content_settings['item-' . $item_key]['content-' . $content_key] = $content_item;
              }
            }
          }
        }
      }

      $setting['content_settings'] = $updated_content_settings;
    }

    // Update job settings with new content settings structure.
    $job->set('settings', $settings);//->save();
  }

  return (string) t('Updated content settings structure for LanguageWire TMGMT jobs.');
}
