<?php

namespace WPSN\Modules\Onboarding;

use WPSN\Core\Settings;

defined('ABSPATH') || exit;

/**
 * Builds the real first-run checklist for the Setup Wizard.
 *
 * This keeps the wizard actionable instead of showing only static links.
 */
final class OnboardingChecklistBuilder
{
    private Settings $settings;

    public function __construct(Settings $settings)
    {
        $this->settings = $settings;
    }

    /**
     * @param array<string,mixed> $context
     * @return array<int,array<string,mixed>>
     */
    public function build(array $context = []): array
    {
        $items = [
            $this->buildCoreOutputItem(),
            $this->buildSitemapItem(),
            $this->buildIdentityItem(),
            $this->buildSocialImageItem(),
            $this->buildBreadcrumbsItem(),
            $this->buildSearchConsoleItem($context),
            $this->buildIndexNowItem($context),
        ];

        if ($this->moduleEnabled('local_seo', false)) {
            $items[] = $this->buildLocalBusinessItem();
        }

        return $items;
    }

    /**
     * @param array<int,array<string,mixed>> $items
     * @return array<string,int>
     */
    public function summary(array $items): array
    {
        $summary = [
            'all_total' => 0,
            'all_done' => 0,
            'essentials_total' => 0,
            'essentials_done' => 0,
            'recommended_total' => 0,
            'recommended_done' => 0,
            'integrations_total' => 0,
            'integrations_done' => 0,
        ];

        foreach ($items as $item) {
            if (!is_array($item)) {
                continue;
            }

            $section = isset($item['section']) ? (string) $item['section'] : '';
            $status = isset($item['status']) ? (string) $item['status'] : '';

            $summary['all_total']++;
            if ($status === 'done') {
                $summary['all_done']++;
            }

            if ($section === 'essentials' || $section === 'recommended' || $section === 'integrations') {
                $summary[$section . '_total']++;
                if ($status === 'done') {
                    $summary[$section . '_done']++;
                }
            }
        }

        return $summary;
    }

    /**
     * @return array<string,mixed>
     */
    private function buildCoreOutputItem(): array
    {
        $labels = [
            'meta_tags' => __('Meta tags', 'wp-seo-next'),
            'schema' => __('Schema', 'wp-seo-next'),
            'social' => __('Social meta', 'wp-seo-next'),
            'sitemap' => __('XML Sitemap', 'wp-seo-next'),
            'robots' => __('robots.txt', 'wp-seo-next'),
            'breadcrumbs' => __('Breadcrumbs', 'wp-seo-next'),
        ];

        $defaults = [
            'meta_tags' => true,
            'schema' => true,
            'social' => true,
            'sitemap' => true,
            'robots' => true,
            'breadcrumbs' => true,
        ];

        $active = [];
        foreach ($labels as $moduleId => $label) {
            if ($this->moduleEnabled($moduleId, (bool) ($defaults[$moduleId] ?? false))) {
                $active[] = $label;
            }
        }

        if (!empty($active)) {
            return $this->item(
                'core_output',
                'essentials',
                'done',
                __('Core SEO output is active', 'wp-seo-next'),
                sprintf(
                    /* translators: %s: module labels */
                    __('Active modules: %s', 'wp-seo-next'),
                    implode(', ', $active)
                ),
                'settings',
                __('Open settings', 'wp-seo-next')
            );
        }

        return $this->item(
            'core_output',
            'essentials',
            'todo',
            __('Core SEO output is active', 'wp-seo-next'),
            __('Enable at least one frontend SEO output module so the plugin can output SEO data on the site.', 'wp-seo-next'),
            'settings',
            __('Open settings', 'wp-seo-next')
        );
    }

    /**
     * @return array<string,mixed>
     */
    private function buildSitemapItem(): array
    {
        if ($this->moduleEnabled('sitemap', true)) {
            return $this->item(
                'sitemap',
                'essentials',
                'done',
                __('XML Sitemap is enabled', 'wp-seo-next'),
                __('The sitemap module is on and ready to expose crawlable URLs.', 'wp-seo-next'),
                'settings',
                __('Open settings', 'wp-seo-next')
            );
        }

        return $this->item(
            'sitemap',
            'essentials',
            'todo',
            __('XML Sitemap is enabled', 'wp-seo-next'),
            __('Enable the sitemap module so search engines can discover your URLs more easily.', 'wp-seo-next'),
            'settings',
            __('Open settings', 'wp-seo-next')
        );
    }

    /**
     * @return array<string,mixed>
     */
    private function buildIdentityItem(): array
    {
        $orgName = trim((string) $this->settings->get('schema.org_name', ''));
        $logo = trim((string) $this->settings->get('schema.org_logo_url', ''));
        $localName = trim((string) $this->settings->get('local.business.name', ''));

        if ($orgName !== '' || $localName !== '' || $logo !== '') {
            $parts = [];
            if ($orgName !== '') {
                $parts[] = sprintf(
                    /* translators: %s: organization name */
                    __('Organization: %s', 'wp-seo-next'),
                    $orgName
                );
            } elseif ($localName !== '') {
                $parts[] = sprintf(
                    /* translators: %s: business name */
                    __('Business: %s', 'wp-seo-next'),
                    $localName
                );
            }
            if ($logo !== '') {
                $parts[] = __('Logo is set', 'wp-seo-next');
            }

            return $this->item(
                'identity',
                'essentials',
                'done',
                __('Site identity is configured', 'wp-seo-next'),
                implode(' · ', $parts),
                'settings',
                __('Open settings', 'wp-seo-next')
            );
        }

        return $this->item(
            'identity',
            'essentials',
            'todo',
            __('Site identity is configured', 'wp-seo-next'),
            __('Set organization/business name and logo for schema defaults, brand consistency, and better rich results.', 'wp-seo-next'),
            'settings',
            __('Open settings', 'wp-seo-next')
        );
    }

    /**
     * @return array<string,mixed>
     */
    private function buildSocialImageItem(): array
    {
        $img = trim((string) $this->settings->get('social.default_image_url', ''));
        if ($img !== '') {
            return $this->item(
                'social_image',
                'essentials',
                'done',
                __('Default social image is set', 'wp-seo-next'),
                __('A fallback Open Graph/Twitter image is configured for pages without their own image.', 'wp-seo-next'),
                'settings',
                __('Open settings', 'wp-seo-next')
            );
        }

        return $this->item(
            'social_image',
            'essentials',
            'todo',
            __('Default social image is set', 'wp-seo-next'),
            __('Set a default social image so shared URLs look consistent when no per-page image is available.', 'wp-seo-next'),
            'settings',
            __('Open settings', 'wp-seo-next')
        );
    }

    /**
     * @return array<string,mixed>
     */
    private function buildBreadcrumbsItem(): array
    {
        $enabled = $this->moduleEnabled('breadcrumbs', true);
        $uiEnabled = (bool) $this->settings->get('breadcrumbs.ui_enabled', true);
        $schemaEnabled = (bool) $this->settings->get('breadcrumbs.schema_enabled', true);

        if ($enabled && ($uiEnabled || $schemaEnabled)) {
            return $this->item(
                'breadcrumbs',
                'recommended',
                'done',
                __('Breadcrumbs are configured', 'wp-seo-next'),
                sprintf(
                    /* translators: 1: UI state 2: Schema state */
                    __('Visible trail: %1$s · BreadcrumbList schema: %2$s', 'wp-seo-next'),
                    $uiEnabled ? __('On', 'wp-seo-next') : __('Off', 'wp-seo-next'),
                    $schemaEnabled ? __('On', 'wp-seo-next') : __('Off', 'wp-seo-next')
                ),
                'settings',
                __('Open settings', 'wp-seo-next')
            );
        }

        return $this->item(
            'breadcrumbs',
            'recommended',
            'info',
            __('Breadcrumbs are configured', 'wp-seo-next'),
            __('Optional, but recommended for navigation, internal linking context, and BreadcrumbList schema on larger sites.', 'wp-seo-next'),
            'settings',
            __('Open settings', 'wp-seo-next')
        );
    }

    /**
     * @return array<string,mixed>
     */
    private function buildLocalBusinessItem(): array
    {
        $name = trim((string) $this->settings->get('local.business.name', ''));
        $phone = trim((string) $this->settings->get('local.business.telephone', ''));
        $street = trim((string) $this->settings->get('local.business.street_address', ''));
        $city = trim((string) $this->settings->get('local.business.address_locality', ''));

        if ($name !== '' && ($phone !== '' || $street !== '' || $city !== '')) {
            return $this->item(
                'local_business',
                'recommended',
                'done',
                __('Local business profile is filled in', 'wp-seo-next'),
                __('Business name is set together with contact/address details for Local SEO defaults and NAP output.', 'wp-seo-next'),
                'settings',
                __('Open settings', 'wp-seo-next')
            );
        }

        return $this->item(
            'local_business',
            'recommended',
            'todo',
            __('Local business profile is filled in', 'wp-seo-next'),
            __('Complete the main business fields (name plus phone or address) to improve LocalBusiness schema and NAP consistency.', 'wp-seo-next'),
            'settings',
            __('Open settings', 'wp-seo-next')
        );
    }

    /**
     * @param array<string,mixed> $context
     * @return array<string,mixed>
     */
    private function buildSearchConsoleItem(array $context): array
    {
        $moduleEnabled = $this->moduleEnabled('search_console', true);
        $property = trim((string) $this->settings->get('search_console.property', ''));
        $connected = !empty($context['gsc_connected']);

        if (!$moduleEnabled) {
            return $this->item(
                'search_console',
                'integrations',
                'info',
                __('Search Console is connected', 'wp-seo-next'),
                __('Optional integration is disabled. Turn it on when you want GSC opportunities, briefs, and internal-link data.', 'wp-seo-next'),
                'search_console',
                __('Open Search Console', 'wp-seo-next')
            );
        }

        if ($connected && $property !== '') {
            return $this->item(
                'search_console',
                'integrations',
                'done',
                __('Search Console is connected', 'wp-seo-next'),
                sprintf(
                    /* translators: %s: selected property */
                    __('Connected property: %s', 'wp-seo-next'),
                    $property
                ),
                'search_console',
                __('Open Search Console', 'wp-seo-next')
            );
        }

        if ($connected) {
            return $this->item(
                'search_console',
                'integrations',
                'todo',
                __('Search Console is connected', 'wp-seo-next'),
                __('Google authorization is ready, but no property is selected yet.', 'wp-seo-next'),
                'search_console',
                __('Open Search Console', 'wp-seo-next')
            );
        }

        if ($property !== '') {
            return $this->item(
                'search_console',
                'integrations',
                'todo',
                __('Search Console is connected', 'wp-seo-next'),
                __('A property is selected, but the Google connection is not complete yet.', 'wp-seo-next'),
                'search_console',
                __('Open Search Console', 'wp-seo-next')
            );
        }

        return $this->item(
            'search_console',
            'integrations',
            'info',
            __('Search Console is connected', 'wp-seo-next'),
            __('Optional integration. Connect GSC to unlock opportunities, query optimizer data, alerts, and internal linking suggestions.', 'wp-seo-next'),
            'search_console',
            __('Open Search Console', 'wp-seo-next')
        );
    }

    /**
     * @param array<string,mixed> $context
     * @return array<string,mixed>
     */
    private function buildIndexNowItem(array $context): array
    {
        $moduleEnabled = $this->moduleEnabled('indexnow', false);
        $featureEnabled = $moduleEnabled && (bool) $this->settings->get('indexnow.enabled', false);
        $hasKey = !empty($context['indexnow_has_key']);

        if (!$featureEnabled) {
            return $this->item(
                'indexnow',
                'integrations',
                'info',
                __('IndexNow is ready', 'wp-seo-next'),
                __('Optional integration is off. Enable it when you want instant URL submission and sitemap pings.', 'wp-seo-next'),
                'indexnow',
                __('Open IndexNow tools', 'wp-seo-next')
            );
        }

        if ($hasKey) {
            return $this->item(
                'indexnow',
                'integrations',
                'done',
                __('IndexNow is ready', 'wp-seo-next'),
                __('IndexNow is enabled and a key is present.', 'wp-seo-next'),
                'indexnow',
                __('Open IndexNow tools', 'wp-seo-next')
            );
        }

        return $this->item(
            'indexnow',
            'integrations',
            'todo',
            __('IndexNow is ready', 'wp-seo-next'),
            __('IndexNow is enabled, but the key is missing. Generate a key before you submit URLs.', 'wp-seo-next'),
            'indexnow',
            __('Open IndexNow tools', 'wp-seo-next')
        );
    }

    /**
     * @return array<string,mixed>
     */
    private function item(string $key, string $section, string $status, string $title, string $summary, string $action, string $actionLabel): array
    {
        return [
            'key' => $key,
            'section' => $section,
            'status' => $status,
            'title' => $title,
            'summary' => $summary,
            'action' => $action,
            'action_label' => $actionLabel,
        ];
    }

    private function moduleEnabled(string $moduleId, bool $default): bool
    {
        return $this->settings->moduleEnabled($moduleId, $default);
    }
}
