<?php

namespace NeurogenesisTheme\Helpers;

defined('ABSPATH') || exit;

/**
 * Eligibility, copy context, and persistence for the admin rating notice.
 */
class RatingNotice
{
    private const USER_META_DISMISSED     = '_neurogenesis_theme_rating_dismissed';
    private const USER_META_REMIND_UNTIL  = '_neurogenesis_theme_rating_remind_until';
    private const USER_META_SNOOZE_COUNT  = '_neurogenesis_theme_rating_snooze_count';
    private const MAX_SNOOZE_ATTEMPTS     = 2;
    private const REMIND_DAYS             = 7;
    private const MIN_DAYS_WITHOUT_IMPORT = 7;

    /**
     * Design mode: bypass timing, screen, dismiss, and remind gates.
     * Enable with: add_filter( 'neurogenesis_theme_rating_debug', '__return_true' );
     */
    public static function is_debug(): bool
    {
        return (bool) apply_filters('neurogenesis_theme_rating_debug', false);
    }

    public static function should_render(): bool
    {
        if (!is_user_logged_in() || !current_user_can('edit_posts')) {
            return false;
        }

        if (self::is_debug()) {
            return true;
        }

        if (self::is_dismissed_permanently()) {
            return false;
        }

        if (self::is_in_remind_period()) {
            return false;
        }

        if (self::snooze_count() >= self::MAX_SNOOZE_ATTEMPTS) {
            return false;
        }

        if (!self::passes_timing_gate()) {
            return false;
        }

        if (!self::is_allowed_screen()) {
            return false;
        }

        return (bool) apply_filters('neurogenesis_theme_rating_should_show', true);
    }

    public static function passes_timing_gate(): bool
    {
        if (null !== ContentLayouts::imported_layout_slug()) {
            return true;
        }

        return self::days_since_install() >= self::MIN_DAYS_WITHOUT_IMPORT;
    }

    public static function is_allowed_screen(): bool
    {
        global $pagenow;

        $has_import = null !== ContentLayouts::imported_layout_slug();

        if (isset($_GET['page']) && NEUROGENESIS_THEME_PAGE_ID === $_GET['page']) {
            $route = isset($_GET['route'])
                ? sanitize_key(wp_unslash((string) $_GET['route']))
                : 'dashboard';

            if ('dashboard' !== $route) {
                return false;
            }

            return $has_import;
        }

        if ('index.php' === $pagenow) {
            return self::days_since_install() >= self::MIN_DAYS_WITHOUT_IMPORT;
        }

        return false;
    }

    public static function days_since_install(): int
    {
        $raw = ThemeOptions::get(ThemeOptions::INSTALLED_ON, '');

        if (!is_string($raw) || '' === $raw) {
            return self::MIN_DAYS_WITHOUT_IMPORT;
        }

        $installed = strtotime($raw . ' 00:00:00');

        if (false === $installed) {
            return self::MIN_DAYS_WITHOUT_IMPORT;
        }

        return max(0, (int) floor((time() - $installed) / DAY_IN_SECONDS));
    }

    public static function imported_page_count(): int
    {
        $meta_key = neurogenesis_theme_registry_get('neurogenesis_theme.var_names/meta_content_imported');

        if (!is_string($meta_key) || '' === $meta_key) {
            return 0;
        }

        $query = new \WP_Query(
            [
                'post_type'              => 'page',
                'post_status'            => 'publish',
                'posts_per_page'         => 1,
                'fields'                 => 'ids',
                'no_found_rows'          => false,
                'update_post_meta_cache' => false,
                'update_post_term_cache' => false,
                'meta_key'               => $meta_key,
                'meta_value'             => '1',
            ]
        );

        return (int) $query->found_posts;
    }

    /**
     * @return array<string, mixed>
     */
    public static function view_context(): array
    {
        $theme_slug   = sanitize_key(get_stylesheet());
        $review_url   = sprintf(
            'https://wordpress.org/support/theme/%1$s/reviews/#new-post',
            rawurlencode($theme_slug)
        );
        $review_url   = (string) apply_filters('neurogenesis_theme_rating_review_url', $review_url, $theme_slug);
        $support_url  = sprintf(
            'https://wordpress.org/support/theme/%1$s/',
            rawurlencode($theme_slug)
        );
        $support_url  = (string) apply_filters('neurogenesis_theme_rating_support_url', $support_url, $theme_slug);
        $days         = self::days_since_install();
        $page_count   = self::imported_page_count();
        $has_import   = null !== ContentLayouts::imported_layout_slug();

        return [
            'review_url'          => $review_url,
            'support_url'         => $support_url,
            'days_since_install'  => $days,
            'imported_page_count' => $page_count,
            'has_import'          => $has_import,
            'personalized_line'   => self::personalized_line($days, $page_count, $has_import),
            'can_remind'          => self::snooze_count() < 1,
            'review_clipboard'    => self::review_clipboard_text(),
        ];
    }

    public static function personalized_line(int $days, int $page_count, bool $has_import): string
    {
        if ($has_import && $page_count > 0) {
            return sprintf(
                /* translators: %d: number of imported starter pages */
                _n(
                    'You have %d starter page live with Thinko — nice work!',
                    'You have %d starter pages live with Thinko — nice work!',
                    $page_count,
                    'thinko'
                ),
                $page_count
            );
        }

        if ($days >= self::MIN_DAYS_WITHOUT_IMPORT) {
            return sprintf(
                /* translators: %d: number of days */
                _n(
                    'You have been using Thinko for %d day — that means a lot to us.',
                    'You have been using Thinko for %d days — that means a lot to us.',
                    $days,
                    'thinko'
                ),
                $days
            );
        }

        return __('Thanks for building with Thinko.', 'thinko');
    }

    public static function review_clipboard_text(): string
    {
        return (string) apply_filters(
            'neurogenesis_theme_rating_review_clipboard_text',
            __(
                'Thinko made it easy to launch a polished site quickly. Flexible layouts and a thoughtful editing experience. Highly recommended!',
                'thinko'
            )
        );
    }

    public static function is_dismissed_permanently(): bool
    {
        return '1' === get_user_meta(get_current_user_id(), self::USER_META_DISMISSED, true);
    }

    public static function is_in_remind_period(): bool
    {
        $until = (int) get_user_meta(get_current_user_id(), self::USER_META_REMIND_UNTIL, true);

        return $until > 0 && time() < $until;
    }

    public static function snooze_count(): int
    {
        return max(0, (int) get_user_meta(get_current_user_id(), self::USER_META_SNOOZE_COUNT, true));
    }

    public static function dismiss_permanently(): void
    {
        $user_id = get_current_user_id();
        update_user_meta($user_id, self::USER_META_DISMISSED, '1');
        delete_user_meta($user_id, self::USER_META_REMIND_UNTIL);
    }

    public static function remind_later(): void
    {
        $user_id = get_current_user_id();
        $count   = self::snooze_count() + 1;

        update_user_meta($user_id, self::USER_META_SNOOZE_COUNT, (string) $count);
        update_user_meta(
            $user_id,
            self::USER_META_REMIND_UNTIL,
            (string) (time() + (self::REMIND_DAYS * DAY_IN_SECONDS))
        );

        if ($count >= self::MAX_SNOOZE_ATTEMPTS) {
            update_user_meta($user_id, self::USER_META_DISMISSED, '1');
        }
    }

    public static function record_snooze_without_rating(): void
    {
        $user_id = get_current_user_id();
        $count   = self::snooze_count() + 1;

        update_user_meta($user_id, self::USER_META_SNOOZE_COUNT, (string) $count);

        if ($count >= self::MAX_SNOOZE_ATTEMPTS) {
            self::dismiss_permanently();
        }
    }
}
