<?php
declare(strict_types=1);

namespace WP_AUX\Services\Admin\AuxComponents;

use AuxCF;
use AuxCF\Entities\FieldEntity;
use WP_AUX;
use WP_AUX\Entities\Admin\AuxComponents\AuxComponentsAuditComponentEntity;
use WP_AUX\Entities\Admin\AuxComponents\AuxComponentsAuditFieldEntity;
use WP_AUX\Entities\Admin\AuxComponents\AuxComponentAuditFileEntity;
use WP_AUX\Services\HtmlService;

class AuxComponentsAuditPageService
{
  public static function relativeFilePath(string $filePath, string $relativeTo): string
  {
    $relativeTo = rtrim($relativeTo, '/');
    return substr(strstr($filePath, $relativeTo), strlen($relativeTo) + 1);
  }

  public static function renderDetailsDetails(
    string $title,
    string $description,
    array $file,
    \DateTimeImmutable $fileDate,
    ?array $extends = null,
    ?object $documentObject = null
  ): void
  {
    ?>
    <h2>
      <?php echo $title; ?>
      <?php if ($documentObject) self::renderDocumentationLink($documentObject); ?>
    </h2>
    <?php echo HtmlService::formattedValue($description, '<div class="details-summary">%s</div>'); ?>
    <div>
      Defined in <?php self::renderFilePath($file[0], $file[1]); ?>
      <?php
      if ($extends) {
        ?>
        extending <?php self::renderFilePath($extends[0], $extends[1]); ?>
        <?php
      }
      ?>
    </div>
    <time>Last modified on <?php echo $fileDate->format('l, F j, Y @ h:i a'); ?></time>
    <?php
  }

  public static function renderDetailsBlock(
    string $title,
    string $description,
    AuxComponentAuditFileEntity $file,
    ?AuxComponentAuditFileEntity $extends = null,
    ?object $documentObject = null
  ): void
  {
    ?>
    <h2>
      <?php echo $title; ?>
      <?php if ($documentObject) self::renderDocumentationLink($documentObject); ?>
    </h2>
    <?php echo HtmlService::formattedValue($description, '<div class="details-summary">%s</div>'); ?>
    <div>
      Defined in <?php self::renderFilePath($file->getRelativePath(), $file->getPathKey()); ?>
      <?php
      if ($extends) {
        ?>
        extending <?php self::renderFilePath($extends->getRelativePath(), $extends->getPathKey()); ?>
        <?php
      }
      ?>
    </div>
    <time>Last modified on <?php echo $file->getDateString(); ?></time>
    <?php
  }

  public static function renderDirectoryPath(string $dir, string $type) {
    echo sprintf('<code class="dir-path dir-path-%s">/WP_AUX/%s</code>', $type, $dir);
  }

  public static function getFilePathRelativeTo(string $filePath, string $return = 'array'): mixed
  {
    $try = [
      '/WP_AUX/' . WP_AUX::FIELDS_DIR . '/' => 'field',
      '/WP_AUX/' . WP_AUX::FIELD_GROUPS_DIR . '/' => 'group',
      '/WP_AUX/' . WP_AUX::FIELDS_COLLECTIONS_DIR . '/' => 'collection',
      '/AuxCF/' . AuxCF::FIELDS_DIR . '/' => 'base',
    ];

    foreach ($try as $dir => $type) {
      if (substr_count($filePath, $dir)) {
        if ('array' === $return) {
          return [$dir, $type];
        } else {
          return $type;
        }
      }
    }

    return '';
  }

  public static function renderFilePath(string $filePath, string $type) {
    $relativeTo = self::getFilePathRelativeTo($filePath);

    if ($relativeTo) {
      $relativePath = $relativeTo[0];
      $type = $relativeTo[1];
    }

    $filePath = $relativeTo ? self::relativeFilePath($filePath, $relativeTo[0]) : basename($filePath);

    $tooltipAttr = '';
    if ($relativeTo) {
      $tooltipAttr = ' data-tippy-content="' . $relativePath . $filePath . '"';
    }

    echo sprintf(
      '<code class="file-path file-path-%s"%s>%s</code>',
      $type,
      $tooltipAttr,
      $filePath
    );
  }

  public static function renderDocumentationLink(AuxComponentsAuditComponentEntity $auditComponent): void
  {
    $documentationLink = '';

    if ($documentationUrl = $auditComponent->getDocumenationUrl()) {
      $documentationLink = sprintf(
        '<a href="%s" class="aux-documentation-link">AUX Docs <span class="dashicons dashicons-external"></span></a>',
        $documentationUrl
      );
    }

    echo $documentationLink;
  }

  public static function renderComponentDetails(AuxComponentsAuditComponentEntity $auditComponent): void
  {
    $fieldGroup = $auditComponent->fieldGroup;

    $fieldGroupCollecctions = [];
    foreach ($auditComponent->auditFields as $auditField) {
      if ($collectionFilePath = $auditField->getCollectionPath()) {
        $fieldGroupCollecctions[$collectionFilePath] = $collectionFilePath;
      }
    }
    ?>
    <div id="component-<?php echo $auditComponent->key; ?>" style="display: none;">
      <div class="component-details">
        <?php
        self::renderDetailsBlock(
          $auditComponent->title,
          $fieldGroup->getDescription(),
          $auditComponent->file,
          null,
          $auditComponent
        );
        ?>

        <div class="fields-summary">
          <?php
          if ($fieldGroupCollecctions) {
            ?>
            <h3>Fields Collections</h3>
            <p>This component uses fields from <?php echo count($fieldGroupCollecctions); ?>
              "Fields Collections" found in the <?php self::renderDirectoryPath(WP_AUX::FIELDS_COLLECTIONS_DIR, 'collection'); ?>
              directory.</p>
            <?php
          }
          ?>
          <h3>Fields</h3>
          <p>Fields are set up as "entities" in the
            <?php self::renderDirectoryPath(WP_AUX::FIELDS_DIR, 'field'); ?> directory.
            Fields extend base field types in the
            <code class="dir-path dir-path-base">/AuxCF/Entities/Field</code> directory.</p>
        </div>
        <?php
        AuxComponentsAuditFieldService::renderFieldsList($auditComponent);
        ?>
      </div>
    </div>
    <?php
  }

}
