<?php

namespace Drupal\straker_translate\Element;

use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Url;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\straker_translate\Event\TargetSecondaryActionsEvent;
use Drupal\straker_translate\StrakerTranslate;

/**
 * Trait for straker_translate_target_status and straker_translate_target_statuses reuse.
 */
trait StrakerTranslateTargetTrait {

  /**
   * Get the target action url based on the source status.
   *
   * @param \Drupal\Core\Entity\ContentEntityInterface $entity
   *   The entity.
   * @param string $target_status
   *   The target status.
   * @param string $langcode
   *   The language code.
   *
   * @return \Drupal\Core\Url
   *   An url object.
   */
  protected function getTargetActionUrl(ContentEntityInterface &$entity, $target_status, $langcode) {
    $url = NULL;
    $document_id = \Drupal::service('straker_translate.content_translation')->getDocumentId($entity);
    $target_file_id = \Drupal::service('straker_translate.content_translation')->getTargetFileId($entity, $langcode);
    $locale = \Drupal::service('straker_translate.language_locale_mapper')->getLocaleForLangcode($langcode);
    if ($document_id) {
      if ($target_status == StrakerTranslate::STATUS_READY || $target_status == StrakerTranslate::STATUS_ERROR) {
        if ($target_file_id && $document_id) {
          $url = Url::fromRoute('straker_translate.entity.download',
            [
              'doc_id' => $document_id,
              'file_id' => $target_file_id,
              'langcode' => $langcode,
            ],
            ['query' => $this->getDestinationWithQueryArray()]);
        }
      }
      if ($target_status == StrakerTranslate::STATUS_CURRENT ||
        $target_status == StrakerTranslate::STATUS_LOCKED ||
        $target_status == StrakerTranslate::STATUS_INTERMEDIATE ||
        $target_status == StrakerTranslate::STATUS_EDITED) {
        $url = Url::fromRoute('straker_translate.workbench', [
          'doc_id' => $document_id,
        ]);
      }

      if ($target_status == StrakerTranslate::STATUS_DISABLED) {
        $url = NULL;
      }
    }
    return $url;
  }

  /**
   * Get secondary target actions, which will be shown when expanded.
   *
   * @param \Drupal\Core\Entity\ContentEntityInterface $entity
   *   The entity.
   * @param string $target_status
   *   The target status.
   * @param string $langcode
   *   The language code.
   *
   * @return array
   *   Array of links.
   */
  protected function getSecondaryTargetActionUrls(ContentEntityInterface &$entity, $target_status, $langcode) {
    $url = NULL;
    $document_id = \Drupal::service('straker_translate.content_translation')->getDocumentId($entity);
    $target_file_id = \Drupal::service('straker_translate.content_translation')->getTargetFileId($entity, $langcode);
    $locale = \Drupal::service('straker_translate.language_locale_mapper')->getLocaleForLangcode($langcode);
    $langcode_upper = strtoupper($langcode);
    $actions = [];
    if ($document_id) {
      if ($target_status == StrakerTranslate::STATUS_READY) {
        if ($target_file_id && $document_id) {
          $actions['download'] = [
            'title' => $this->t('Download translation'),
            'url' => Url::fromRoute('straker_translate.entity.download',
              [
                'doc_id' => $document_id,
                'file_id' => $target_file_id,
                'langcode' => $langcode,
              ],
              ['query' => $this->getDestinationWithQueryArray()]),
            'new_window' => FALSE,
          ];
        }
        $actions['workbench'] = [
          'title' => $this->t('Open in Verify'),
          'url' => Url::fromRoute('straker_translate.workbench', [
            'doc_id' => $document_id,
          ]),
          'new_window' => TRUE,
        ];
        // @todo add url for disassociate.
      }
      if ($target_status == StrakerTranslate::STATUS_ERROR) {
        if ($target_file_id && $document_id) {
          $actions['download'] = [
            'title' => $this->t('Retry download'),
            'url' => Url::fromRoute('straker_translate.entity.download',
                [
                  'doc_id' => $document_id,
                  'file_id' => $target_file_id,
                  'langcode' => $langcode,
                ],
                ['query' => $this->getDestinationWithQueryArray()]),
            'new_window' => FALSE,
          ];
        }
      }
      if ($target_status == StrakerTranslate::STATUS_CURRENT) {
        if ($entity->hasLinkTemplate('canonical') && $entity->hasTranslation($langcode)) {
          $actions['view'] = [
            'title' => $this->t('View translation'),
            'url' => $entity->getTranslation($langcode)->toUrl(),
            'new_window' => FALSE,
          ];
        }
        $actions['workbench'] = [
          'title' => $this->t('Open in Verify'),
          'url' => Url::fromRoute('straker_translate.workbench', [
            'doc_id' => $document_id,
          ]),
          'new_window' => TRUE,
        ];
        $actions['lock'] = [
          'title' => $this->t('Lock Target'),
          'url' => Url::fromRoute('straker_translate.entity.lock_target',
            [
              'doc_id' => $document_id,
              'locale' => $locale,
            ],
            ['query' => $this->getDestinationWithQueryArray()]),
          'new_window' => FALSE,
        ];
      }
      if ($target_status == StrakerTranslate::STATUS_LOCKED) {
        if ($entity->hasLinkTemplate('canonical') && $entity->hasTranslation($langcode)) {
          $actions['view'] = [
            'title' => $this->t('View translation'),
            'url' => $entity->getTranslation($langcode)->toUrl(),
            'new_window' => FALSE,
          ];
        }
        $actions['workbench'] = [
          'title' => $this->t('Open in Verify'),
          'url' => Url::fromRoute('straker_translate.workbench', [
            'doc_id' => $document_id,
          ]),
          'new_window' => TRUE,
        ];
        $actions['unlock'] = [
          'title' => $this->t('Unlock Target'),
          'url' => Url::fromRoute('straker_translate.entity.unlock_target',
            [
              'doc_id' => $document_id,
              'locale' => $locale,
            ],
            ['query' => $this->getDestinationWithQueryArray()]),
          'new_window' => FALSE,
        ];
      }
      if ($target_status == StrakerTranslate::STATUS_EDITED) {
        if ($entity->hasLinkTemplate('canonical') && $entity->hasTranslation($langcode)) {
          $actions['view'] = [
            'title' => $this->t('View translation'),
            'url' => $entity->getTranslation($langcode)->toUrl(),
            'new_window' => FALSE,
          ];
        }
        $actions['workbench'] = [
          'title' => $this->t('Open in Verify'),
          'url' => Url::fromRoute('straker_translate.workbench', [
            'doc_id' => $document_id,
          ]),
          'new_window' => TRUE,
        ];

        $actions['download'] = [
          'title' => $this->t('Download existing translation'),
          'url' => Url::fromRoute('straker_translate.entity.download',
            [
              'doc_id' => $document_id,
              'file_id' => $target_file_id,
              'langcode' => $langcode,
            ],
          ['query' => $this->getDestinationWithQueryArray()]),
          'new_window' => FALSE,
        ];
      }
    }
    if (in_array($target_status, [StrakerTranslate::STATUS_UNTRACKED, StrakerTranslate::STATUS_ARCHIVED])) {
      if ($entity->hasLinkTemplate('canonical') && $entity->hasTranslation($langcode)) {
        $actions['view'] = [
          'title' => $this->t('View translation'),
          'url' => $entity->getTranslation($langcode)->toUrl(),
          'new_window' => FALSE,
        ];
      }

    }
    if ($entity->hasTranslation($langcode) && $entity->getEntityType()->hasLinkTemplate('drupal:content-translation-delete')) {
      $entity_type_id = $entity->getEntityTypeId();
      $delete_url = $entity->access('delete') ? $entity->getTranslation($langcode)->toUrl('delete-form') :
        Url::fromRoute("entity.$entity_type_id.content_translation_delete", [$entity_type_id => $entity->id(), 'language' => $langcode]);
      $delete_url->setOption('query', $this->getDestinationWithQueryArray());
      $actions['delete'] = [
        'title' => $this->t('Delete translation'),
        'url' => $delete_url,
        'new_window' => FALSE,
      ];
    }

    $event = new TargetSecondaryActionsEvent($entity, $target_status, $langcode, $actions);

    // Get the event_dispatcher service and dispatch the event.
    $event_dispatcher = \Drupal::service('event_dispatcher');
    $event_dispatcher->dispatch($event, TargetSecondaryActionsEvent::EVENT_NAME);

    return $event->getActions();
  }

  /**
   * Get a destination query with the current uri.
   *
   * @return array
   *   A valid query array for the Url construction.
   */
  protected function getDestinationWithQueryArray() {
    return ['destination' => \Drupal::request()->getRequestUri()];
  }

  /**
   * Get the target status label.
   *
   * @param string $status
   *   The target status.
   * @param string $langcode
   *   The language code.
   * @param bool|null $translation_exists
   *   TRUE if translation exists.
   *
   * @return string
   *   The source status human-friendly label.
   */
  protected function getTargetStatusText($status, $langcode, $translation_exists = NULL) {
    $language = ConfigurableLanguage::load($langcode);
    switch ($status) {
      case StrakerTranslate::STATUS_UNTRACKED:
        return $language->label() . ' - ' . $this->t('Translation exists, but it is not being tracked by Straker Translate');

      case StrakerTranslate::STATUS_REQUEST:
        return $language->label() . ' - ' . $this->t('Request translation');

      case StrakerTranslate::STATUS_PENDING:
        return $language->label() . ' - ' . $this->t('In-progress');

      case StrakerTranslate::STATUS_READY:
        return $language->label() . ' - ' . $this->t('Ready for Download');

      case StrakerTranslate::STATUS_INTERMEDIATE:
        return $language->label() . ' - ' . $this->t('In-progress (interim translation downloaded)');

      case StrakerTranslate::STATUS_CURRENT:
        return $language->label() . ' - ' . $this->t('Current');

      case StrakerTranslate::STATUS_LOCKED:
        return $language->label() . ' - ' . $this->t('Target Locale is Locked');

      case StrakerTranslate::STATUS_EDITED:
        return $language->label() . ' - ' . $this->t('Not current');

      case StrakerTranslate::STATUS_ERROR:
        return $language->label() . ' - ' . $this->t('Error');

      case StrakerTranslate::STATUS_CANCELLED:
        return $language->label() . ' - ' . $this->t('Cancelled by user');

      case StrakerTranslate::STATUS_DELETED:
        if (!isset($translation_exists)) {
          return $language->label() . ' - ' . $this->t('This target was deleted in Straker Translate.');
        } if ($translation_exists) {
          return $language->label() . ' - ' . $this->t('This target was deleted in Straker Translate and the translation exists.');
        }
        return $language->label() . ' - ' . $this->t('This target was deleted in Straker Translate and the translation does not exist.');

      case StrakerTranslate::STATUS_ARCHIVED:
        if (!isset($translation_exists)) {
          return $language->label() . ' - ' . $this->t('This target was archived in Straker Translate.');
        } if ($translation_exists) {
          return $language->label() . ' - ' . $this->t('This target was archived in Straker Translate and the translation exists.');
        }
        return $language->label() . ' - ' . $this->t('This target was archived in Straker Translate and the translation does not exist.');

      default:
        return $language->label() . ' - ' . ucfirst(strtolower($status));
    }
  }

}
