<?php

namespace Duplicator\Views;

use Duplicator\Controllers\PackagesPageController;
use Duplicator\Controllers\StoragePageController;
use Duplicator\Core\Views\TplMng;
use Duplicator\Libs\Snap\SnapUtil;
use Duplicator\Package\AbstractPackage;
use Duplicator\Package\Create\BuildComponents;
use WP_Screen;

class PackageScreen extends ScreenBase
{
    /**
     * Class contructor
     *
     * @param string $page Page
     *
     * @return void
     */
    public function __construct($page)
    {
        add_action('load-' . $page, [$this, 'init']);
        add_filter('screen_settings', [$this, 'showOptions'], 10, 2);
    }

    /**
     * Init Backup screen
     *
     * @return void
     */
    public function init(): void
    {
        add_action('admin_head', [self::class, 'displayColsCss']);
    }

    /**
     * Display columns css
     *
     * @return void
     */
    public static function displayColsCss(): void
    {
        $uiOpts = UserUIOptions::getInstance();

        $showNote    = $uiOpts->get(UserUIOptions::VAL_SHOW_COL_NOTE);
        $showSize    = $uiOpts->get(UserUIOptions::VAL_SHOW_COL_SIZE);
        $showCreated = $uiOpts->get(UserUIOptions::VAL_SHOW_COL_CREATED);
        $showAge     = $uiOpts->get(UserUIOptions::VAL_SHOW_COL_AGE);
        ?>
        <style>
            <?php if (!$showNote) { ?>
                .dup-packtbl .dup-note-column {
                    display: none;
                }
            <?php } ?>

            <?php if (!$showSize) { ?>
                .dup-packtbl .dup-size-column {
                    display: none;
                }
            <?php } ?>

            <?php if (!$showCreated) { ?>
                .dup-packtbl .dup-created-column {
                    display: none;
                }
            <?php } ?>

            <?php if (!$showAge) { ?>
                .dup-packtbl .dup-age-column {
                    display: none;
                }
            <?php } ?>
        </style>
        <?php
    }

    /**
     * Packages List: Screen Options Tab
     *
     * @param string    $screen_settings Screen settings
     * @param WP_Screen $args            Screen args
     *
     * @return string
     */
    public function showOptions($screen_settings, WP_Screen $args)
    {


        // Only display on Backups screen and not build screens
        if (
            !PackagesPageController::getInstance()->isCurrentPage() ||
            PackagesPageController::getCurrentInnerPage(PackagesPageController::LIST_INNER_PAGE_LIST) !== PackagesPageController::LIST_INNER_PAGE_LIST
        ) {
            return $screen_settings;
        }

        return TplMng::getInstance()->render('admin_pages/packages/screen_options', [], false);
    }

    /**
     * Set duplicator screen option
     *
     * @param mixed  $screen_option The value to save instead of the option value. Default false (to skip saving the current option).
     * @param string $option        The option name.
     * @param int    $value         The option value.
     *
     * @return bool
     */
    public static function setScreenOptions($screen_option, $option, $value): bool
    {
        $uiOpts = UserUIOptions::getInstance();

        $perPage = SnapUtil::sanitizeIntInput(SnapUtil::INPUT_REQUEST, 'dupli-per-page', 10);
        $perPage = max(10, $perPage); // Minimum 10 entries per page

        $uiOpts->set(UserUIOptions::VAL_PACKAGES_PER_PAGE, $perPage);

        $dateFormat = SnapUtil::sanitizeIntInput(SnapUtil::INPUT_REQUEST, 'dupli-created-format', 1);
        $uiOpts->set(UserUIOptions::VAL_CREATED_DATE_FORMAT, $dateFormat);

        $showNote = SnapUtil::sanitizeBoolInput(SnapUtil::INPUT_REQUEST, 'dupli-note-hide');
        $uiOpts->set(UserUIOptions::VAL_SHOW_COL_NOTE, $showNote);

        $showSize = SnapUtil::sanitizeBoolInput(SnapUtil::INPUT_REQUEST, 'dupli-size-hide');
        $uiOpts->set(UserUIOptions::VAL_SHOW_COL_SIZE, $showSize);

        $showCreated = SnapUtil::sanitizeBoolInput(SnapUtil::INPUT_REQUEST, 'dupli-created-hide');
        $uiOpts->set(UserUIOptions::VAL_SHOW_COL_CREATED, $showCreated);

        $showAge = SnapUtil::sanitizeBoolInput(SnapUtil::INPUT_REQUEST, 'dupli-age-hide');
        $uiOpts->set(UserUIOptions::VAL_SHOW_COL_AGE, $showAge);

        $uiOpts->save();

        // Returning false from the filter will skip saving the current option
        return false;
    }

    /**
     * Build the list of icons rendered in the package flags cell, in display order.
     *
     * The shape icon comes first and carries the full aggregated tooltip; the
     * remaining core icons (storage, post-restore) carry their own simple
     * tooltip and, for storage, the clickable storage-details behaviour. Addon
     * icons (schedule/manual, disaster recovery) are appended afterwards by the
     * `duplicator_package_flags_icons` action.
     *
     * Every entry shares the same shape so the template is a flat loop:
     *   - icon:         FontAwesome class string (e.g. "fa-solid fa-hard-drive")
     *   - class:        extra CSS class for the wrapping span (may be empty)
     *   - tooltip:      tooltip body (HTML allowed); a plain string renders as a simple tooltip
     *   - tooltipTitle: optional tooltip header; empty means a simple (headerless) tooltip
     *   - onclick:      optional inline JS handler; empty means the icon is not clickable
     *
     * @param AbstractPackage $package The package
     *
     * @return array<int, array{icon: string, class: string, tooltip: string, tooltipTitle: string, onclick: string}>
     */
    public static function getFlagsCellIcons(AbstractPackage $package): array
    {
        $icons = [];

        $icons[] = [
            'icon'         => self::getShapeIcon($package),
            'class'        => '',
            'tooltip'      => TplMng::getInstance()->render(
                'admin_pages/packages/row_parts/flags_tooltip',
                ['tooltipGroups' => self::getFlagsTooltipGroups($package)],
                false
            ),
            'tooltipTitle' => esc_attr__('Backup details', 'duplicator-pro'),
            'onclick'      => '',
        ];

        $storageClick = sprintf(
            "DupliJs.Pack.ShowRemote(%d, '%s');",
            $package->getId(),
            esc_js($package->getNameHash())
        );
        if ($package->hasFlag(AbstractPackage::FLAG_HAVE_LOCAL)) {
            $icons[] = [
                'icon'         => 'fa-solid fa-hard-drive',
                'class'        => 'cursor-pointer',
                'tooltip'      => esc_attr__('The Backup is in Local Storage', 'duplicator-pro'),
                'tooltipTitle' => '',
                'onclick'      => $storageClick,
            ];
        }
        if ($package->hasFlag(AbstractPackage::FLAG_HAVE_REMOTE)) {
            $icons[] = [
                'icon'         => 'fa-solid fa-cloud',
                'class'        => 'cursor-pointer remote-storage-flag',
                'tooltip'      => esc_attr__('The Backup is in Remote Storage', 'duplicator-pro'),
                'tooltipTitle' => '',
                'onclick'      => $storageClick,
            ];
        }
        if ($package->hasFlag(AbstractPackage::FLAG_CREATED_AFTER_RESTORE)) {
            $icons[] = [
                'icon'         => 'fa-solid fa-clock-rotate-left maroon',
                'class'        => '',
                'tooltip'      => esc_attr__('This Backup is created after the Last Restored Backup', 'duplicator-pro'),
                'tooltipTitle' => '',
                'onclick'      => '',
            ];
        }

        return $icons;
    }

    /**
     * Build the aggregated tooltip groups for the package flags cell.
     *
     * Each group has:
     *   - icon:    FontAwesome class string (e.g. "fa-solid fa-hard-drive"); the template
     *             wraps it in <i class="...">
     *   - label:   translated short description; may contain safe HTML (e.g. a link)
     *   - details: optional HTML rendered as a nested list under the group label
     *
     * The list is filterable via `duplicator_package_flags_tooltip_groups`.
     *
     * @param AbstractPackage $package The package
     *
     * @return array<int, array{icon: string, label: string, details: string}>
     */
    public static function getFlagsTooltipGroups(AbstractPackage $package): array
    {
        $groups = [];
        $tplMng = TplMng::getInstance();

        $storageRows = [];
        foreach ($package->getValidStorages() as $storage) {
            $iconHtml = $storage::getStypeIcon(false);
            if ($storage::isLocal()) {
                $iconHtml = str_replace(
                    'class="dup-storage-icon"',
                    'class="dup-storage-icon dup-storage-icon-invert"',
                    $iconHtml
                );
            }
            $storageRows[] = [
                'icon_html' => $iconHtml,
                'text'      => $storage->getName(),
                'url'       => StoragePageController::getEditUrl($storage),
            ];
        }
        if ($storageRows !== []) {
            $groups[] = [
                'icon'    => 'fa-solid fa-hard-drive',
                'label'   => esc_html__('Storages', 'duplicator-pro'),
                'details' => $tplMng->render(
                    'admin_pages/packages/row_parts/flags_tooltip_sublist',
                    ['rows' => $storageRows],
                    false
                ),
            ];
        }

        $shapeDetails = '';
        if (count($package->components) > 1) {
            $componentRows = array_map(
                fn($component): array => [
                    'icon_html' => '',
                    'text'      => BuildComponents::getLabel($component),
                    'url'       => '',
                ],
                $package->components
            );
            $shapeDetails  = $tplMng->render(
                'admin_pages/packages/row_parts/flags_tooltip_sublist',
                ['rows' => $componentRows],
                false
            );
        }

        $groups[] = [
            'icon'    => self::getShapeIcon($package),
            'label'   => self::getShapeLabel($package),
            'details' => $shapeDetails,
        ];

        if ($package->hasFlag(AbstractPackage::FLAG_CREATED_AFTER_RESTORE)) {
            $groups[] = [
                'icon'    => 'fa-solid fa-clock-rotate-left maroon',
                'label'   => esc_html__('Created after the last restored backup', 'duplicator-pro'),
                'details' => '',
            ];
        }

        /**
         * Filter aggregated tooltip groups for the package flags cell.
         *
         * @param array<int, array{icon: string, label: string, details: string}> $groups
         * @param AbstractPackage                                                  $package
         */
        return apply_filters('duplicator_package_flags_tooltip_groups', $groups, $package);
    }

    /**
     * Return the FontAwesome class string matching the package shape flag.
     *
     * @param AbstractPackage $package The package
     *
     * @return string
     */
    private static function getShapeIcon(AbstractPackage $package): string
    {
        if ($package->hasFlag(AbstractPackage::FLAG_FULL_BACKUP)) {
            return 'fa-solid fa-square-check';
        }
        if ($package->hasFlag(AbstractPackage::FLAG_DB_ONLY)) {
            return 'fa-solid fa-database';
        }
        if ($package->hasFlag(AbstractPackage::FLAG_MEDIA_ONLY)) {
            return 'fa-solid fa-images';
        }
        return 'fa-solid fa-puzzle-piece';
    }

    /**
     * Return the translated label matching the package shape flag.
     *
     * @param AbstractPackage $package The package
     *
     * @return string
     */
    private static function getShapeLabel(AbstractPackage $package): string
    {
        if ($package->hasFlag(AbstractPackage::FLAG_FULL_BACKUP)) {
            return esc_html__('Full Backup', 'duplicator-pro');
        }
        if ($package->hasFlag(AbstractPackage::FLAG_DB_ONLY)) {
            return esc_html__('Database Only Backup', 'duplicator-pro');
        }
        if ($package->hasFlag(AbstractPackage::FLAG_MEDIA_ONLY)) {
            return esc_html__('Media Only Backup', 'duplicator-pro');
        }
        return esc_html__('Custom Components Backup', 'duplicator-pro');
    }
}
