<?php

namespace Drupal\straker_translate\Plugin\StrakerTranslateFormComponent\Field;

use Drupal\Core\Entity\EntityInterface;
use Drupal\straker_translate\FormComponent\StrakerTranslateFormComponentFieldBase;
use Drupal\straker_translate\StrakerTranslateConfigurationServiceInterface;

/**
 * Defines a Straker Translate form-field plugin for target translation status.
 *
 * @StrakerTranslateFormComponentField(
 *   id = "target_status",
 *   title = @Translation("Target Status"),
 *   weight = 450,
 *   form_ids = {
 *     "straker_translate_management",
 *     "straker_translate_entity_management",
 *     "straker_translate_job_content_entities_management"
 *   }
 * )
 */
class TargetStatus extends StrakerTranslateFormComponentFieldBase {

  /**
   * {@inheritdoc}
   */
  public function getHeader($entity_type_id = NULL) {
    return $this->t('Target Status');
  }

  /**
   * {@inheritdoc}
   */
  public function getData(EntityInterface $entity) {
    // Get the Straker Translate translation service
    $translation_service = \Drupal::service('straker_translate.content_translation');
    /** @var \Drupal\straker_translate\StrakerTranslateConfigurationServiceInterface $config_service */
    $config_service = \Drupal::service('straker_translate.configuration');
    $source_language = $entity->getUntranslated()->language()->getId();
    $document_id = $translation_service->getDocumentId($entity);

    // Only get languages enabled for Straker translation
    $languages = $config_service->getEnabledLanguages();
    $target_status_html = '';

    foreach ($languages as $langcode => $language) {
      if ($langcode !== $source_language) {
        $target_status = $translation_service->getTargetStatus($entity, $langcode);

        // If document exists but target status is NULL/empty, default to 'REQUEST' status
        if ($document_id && (!$target_status || $target_status === NULL)) {
          $target_status = 'REQUEST';
        }

        // Skip if no document and no status (entity not tracked at all)
        if (!$document_id && (!$target_status || $target_status === NULL)) {
          continue;
        }

        // If document exists and target status is UNTRACKED, show 'New Language' as the status text
        if ($document_id && $target_status === 'UNTRACKED') {
          $status_text = $this->t('New Language');
          $target_status = $this->t('NEWLANGUAGE');
        } else {
          $status_text = $this->getStatusText($target_status);
        }
        $css_class = $this->getStatusCssClass($target_status);
        $tooltip = $this->getStatusTooltip($target_status, $langcode);

        // Check if this PENDING status should have a dropdown
        // Only show dropdown for PENDING if it's specifically from an unlock action
        // We can determine this by checking if there's a translation AND the source is CURRENT
        // (indicating the document wasn't just re-uploaded or edited)
        $is_unlocked_pending = false;
        if ($target_status === 'PENDING' && $entity->hasTranslation($langcode)) {
          $source_status = $translation_service->getSourceStatus($entity);
          // Only show dropdown if source is CURRENT (not edited/re-uploaded)
          if ($source_status === 'CURRENT') {
            $is_unlocked_pending = true;
          }
        }

        // Create a pill for each language status with dropdown if applicable
        $needs_dropdown = in_array($target_status, ['CURRENT', 'READY', 'LOCKED']) || $is_unlocked_pending;

        if ($needs_dropdown) {
          $target_status_html .= $this->buildStatusWithDropdown($css_class, $status_text, $tooltip, $entity, $target_status, $langcode);
        } else {
          $target_status_html .= '<div class="target-status-pill-wrapper">';
          $target_status_html .= '<span class="language-icon ' . $css_class . '" title="' . $tooltip . '">';
          $target_status_html .= $status_text; // Just the status, no language code
          $target_status_html .= '</span></div>';
        }
      }
    }

    return [
      'data' => [
        '#markup' => $target_status_html ?: '<span class="target-status-none">' . $this->t('No targets') . '</span>',
        '#attached' => [
          'library' => ['straker_translate/base', 'straker_translate/target_status_dropdown'],
        ],
      ],
    ];
  }

  /**
   * Get CSS class for a target status.
   */
  protected function getStatusCssClass($target_status) {
    switch ($target_status) {
      case 'CURRENT':
        return 'target-current';
      case 'PENDING':
        return 'target-pending';
      case 'READY':
        return 'target-ready';
      case 'REQUEST':
        return 'target-request';
      case 'UNTRACKED':
        return 'target-untracked';
      case 'PROCESSING':
        return 'target-processing';
      case 'INTERMEDIATE':
        return 'target-intermediate';
      case 'ERROR':
        return 'target-error';
      case 'CANCELLED':
        return 'target-cancelled';
      case 'DISABLED':
        return 'target-disabled';
      case 'LOCKED':
        return 'target-locked';
      case 'NEWLANGUAGE':
        return 'target-newlanguage';
      default:
        return 'target-unknown';
    }
  }

  /**
   * Get human-readable text for a target status.
   */
  protected function getStatusText($target_status) {
    switch ($target_status) {
      case 'CURRENT':
        return $this->t('Synced with Verify');
      case 'PENDING':
        return $this->t('Pending');
      case 'READY':
        return $this->t('Ready for Download');
      case 'REQUEST':
        return $this->t('Requested');
      case 'UNTRACKED':
        return $this->t('Not Started');
      case 'PROCESSING':
        return $this->t('In Progress');
      case 'INTERMEDIATE':
        return $this->t('Partial');
      case 'ERROR':
        return $this->t('Error');
      case 'CANCELLED':
        return $this->t('Cancelled');
      case 'DISABLED':
        return $this->t('Disabled');
      case 'LOCKED':
        return $this->t('Locked');
      // No NEW_LANGUAGE case
      default:
        return $this->t('Unknown');
    }
  }

  /**
   * Get tooltip text for a target status.
   */
  protected function getStatusTooltip($target_status, $langcode) {
    $language_name = \Drupal::service('language_manager')->getLanguage($langcode)->getName();

    switch ($target_status) {
      case 'CURRENT':
        return $this->t('@language translation is complete and up-to-date', ['@language' => $language_name]);
      case 'PENDING':
        return $this->t('@language translation is pending', ['@language' => $language_name]);
      case 'READY':
        return $this->t('@language translation is ready for download', ['@language' => $language_name]);
      case 'REQUEST':
        return $this->t('@language translation has been requested', ['@language' => $language_name]);
      case 'UNTRACKED':
        return $this->t('@language translation not started', ['@language' => $language_name]);
      case 'PROCESSING':
        return $this->t('@language translation in progress', ['@language' => $language_name]);
      case 'INTERMEDIATE':
        return $this->t('@language translation partially complete', ['@language' => $language_name]);
      case 'ERROR':
        return $this->t('@language translation error', ['@language' => $language_name]);
      case 'CANCELLED':
        return $this->t('@language translation cancelled', ['@language' => $language_name]);
      case 'DISABLED':
        return $this->t('@language translation disabled', ['@language' => $language_name]);
      case 'LOCKED':
        return $this->t('@language translation is locked', ['@language' => $language_name]);
      case 'NEWLANGUAGE':
        return $this->t('@language was added after document upload', ['@language' => $language_name]);
      default:
        return $this->t('@language translation status unknown', ['@language' => $language_name]);
    }
  }

  /**
   * Build a status pill with dropdown functionality for target statuses.
   */
  protected function buildStatusWithDropdown($css_class, $status_text, $tooltip, EntityInterface $entity, $status, $langcode) {
    $actions = $this->getTargetStatusActions($entity, $status, $langcode);
    $dropdown_id = 'target-status-' . $entity->getEntityTypeId() . '-' . $entity->id() . '-' . $langcode;

    $dropdown_html = '';

    if (!empty($actions)) {
      $dropdown_html = '<span class="target-status-dropdown-toggle"></span>';
      $dropdown_html .= '<ul class="target-status-dropdown-menu" id="' . $dropdown_id . '">';
      foreach ($actions as $action) {
        $target = $action['new_window'] ? ' target="_blank"' : '';
        $dropdown_html .= '<li><a href="' . $action['url']->toString() . '"' . $target . '>' . $action['title'] . '</a></li>';
      }
      $dropdown_html .= '</ul>';
    }

    // Add CSS class if there's a dropdown
    $wrapper_class = 'target-status-pill-wrapper';
    if (!empty($actions)) {
      $wrapper_class .= ' has-dropdown';
    }

    // Match project status structure exactly
    return '<div class="' . $wrapper_class . '"><span class="language-icon ' . $css_class . '" title="' . $tooltip . '">' . $status_text . $dropdown_html . '</span></div>';
  }

  /**
   * Get actions available for target statuses (replicating StrakerTranslateTargetTrait behavior).
   */
  protected function getTargetStatusActions(EntityInterface $entity, $status, $langcode) {
    $actions = [];
    $translation_service = \Drupal::service('straker_translate.content_translation');
    $language_locale_mapper = \Drupal::service('straker_translate.language_locale_mapper');

    // Get the destination query array like the target trait does
    $query_options = ['query' => ['destination' => \Drupal::request()->getRequestUri()]];

    try {
      $document_id = $translation_service->getDocumentId($entity);
      $target_file_id = $translation_service->getTargetFileId($entity, $langcode);
      $locale = $language_locale_mapper->getLocaleForLangcode($langcode);

      if ($document_id) {
        if ($status == 'READY') {
          if ($target_file_id && $document_id) {
            $actions[] = [
              'title' => $this->t('Download translation'),
              'url' => \Drupal\Core\Url::fromRoute('straker_translate.entity.download', [
                'doc_id' => $document_id,
                'file_id' => $target_file_id,
                'langcode' => $langcode,
              ], $query_options),
              'new_window' => FALSE,
            ];
          }
          $actions[] = [
            'title' => $this->t('Open in Verify'),
            'url' => \Drupal\Core\Url::fromRoute('straker_translate.workbench', [
              'doc_id' => $document_id,
            ]),
            'new_window' => TRUE,
          ];
        }

        if ($status == 'CURRENT') {
          if ($entity->hasLinkTemplate('canonical') && $entity->hasTranslation($langcode)) {
            $actions[] = [
              'title' => $this->t('View translation'),
              'url' => $entity->getTranslation($langcode)->toUrl(),
              'new_window' => FALSE,
            ];
          }
          $actions[] = [
            'title' => $this->t('Open in Verify'),
            'url' => \Drupal\Core\Url::fromRoute('straker_translate.workbench', [
              'doc_id' => $document_id,
            ]),
            'new_window' => TRUE,
          ];
          $actions[] = [
            'title' => $this->t('Lock Target'),
            'url' => \Drupal\Core\Url::fromRoute('straker_translate.entity.lock_target', [
              'doc_id' => $document_id,
              'locale' => $locale,
            ], $query_options),
            'new_window' => FALSE,
          ];

          // Add delete translation option
          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') :
              \Drupal\Core\Url::fromRoute("entity.$entity_type_id.content_translation_delete", [$entity_type_id => $entity->id(), 'language' => $langcode]);
            $delete_url->setOption('query', $query_options);
            $actions[] = [
              'title' => $this->t('Delete translation'),
              'url' => $delete_url,
              'new_window' => FALSE,
            ];
          }
        }

        if ($status == 'LOCKED') {
          if ($entity->hasLinkTemplate('canonical') && $entity->hasTranslation($langcode)) {
            $actions[] = [
              'title' => $this->t('View translation'),
              'url' => $entity->getTranslation($langcode)->toUrl(),
              'new_window' => FALSE,
            ];
          }
          $actions[] = [
            'title' => $this->t('Open in Verify'),
            'url' => \Drupal\Core\Url::fromRoute('straker_translate.workbench', [
              'doc_id' => $document_id,
            ]),
            'new_window' => TRUE,
          ];
          $actions[] = [
            'title' => $this->t('Unlock Target'),
            'url' => \Drupal\Core\Url::fromRoute('straker_translate.entity.unlock_target', [
              'doc_id' => $document_id,
              'locale' => $locale,
            ], $query_options),
            'new_window' => FALSE,
          ];

          // Add delete translation option
          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') :
              \Drupal\Core\Url::fromRoute("entity.$entity_type_id.content_translation_delete", [$entity_type_id => $entity->id(), 'language' => $langcode]);
            $delete_url->setOption('query', $query_options);
            $actions[] = [
              'title' => $this->t('Delete translation'),
              'url' => $delete_url,
              'new_window' => FALSE,
            ];
          }
        }

        // Handle PENDING status only when it's from an unlocked target (source is CURRENT)
        if ($status == 'PENDING' && $entity->hasTranslation($langcode)) {
          $source_status = $translation_service->getSourceStatus($entity);
          if ($source_status === 'CURRENT') {

            // Add delete translation option
            if ($entity->getEntityType()->hasLinkTemplate('drupal:content-translation-delete')) {
              $entity_type_id = $entity->getEntityTypeId();
              $delete_url = $entity->access('delete') ? $entity->getTranslation($langcode)->toUrl('delete-form') :
                \Drupal\Core\Url::fromRoute("entity.$entity_type_id.content_translation_delete", [$entity_type_id => $entity->id(), 'language' => $langcode]);
              $delete_url->setOption('query', $query_options);
              $actions[] = [
                'title' => $this->t('Delete translation'),
                'url' => $delete_url,
                'new_window' => FALSE,
              ];
            }
          }
        }
      }
    }
    catch (\Exception $e) {
      // Log the error but don't break the page
      \Drupal::logger('straker_translate')->error('Error generating target status actions: @message', ['@message' => $e->getMessage()]);
    }

    return $actions;
  }

}
