<?php
declare(strict_types=1);

namespace Help4BuilderSuite\Modules\Calendar;

if (! defined('ABSPATH')) {
    exit;
}

final class LegacyPostBridge
{
    private const POST_TYPE = 'bp_calendar_event';
    private const SOURCE_ID = 'legacy-bp-calendar';
    private const DIRTY_OPTION = 'h4bs_calendar_legacy_bp_dirty';
    private const FINGERPRINT_OPTION = 'h4bs_calendar_legacy_bp_fingerprint';

    public static function refresh(): void
    {
        self::import(false);
    }

    public static function forceRefresh(): void
    {
        self::import(true);
    }

    public static function markDirty(int $postId): void
    {
        if ($postId > 0) update_option(self::DIRTY_OPTION, '1', false);
    }

    public static function markDeletedPostDirty(int $postId): void
    {
        if ($postId > 0 && get_post_type($postId) === self::POST_TYPE) update_option(self::DIRTY_OPTION, '1', false);
    }

    /** @param mixed $metaValue */
    public static function markMetaDirty($metaId, int $postId, string $metaKey, $metaValue): void
    {
        unset($metaId, $metaValue);
        if ($postId > 0 && str_starts_with($metaKey, '_bp_') && get_post_type($postId) === self::POST_TYPE) {
            update_option(self::DIRTY_OPTION, '1', false);
        }
    }

    private static function import(bool $force): void
    {
        if (! post_type_exists(self::POST_TYPE)) return;
        $postIds = get_posts([
            'post_type' => self::POST_TYPE,
            'post_status' => 'publish',
            'numberposts' => -1,
            'fields' => 'ids',
            'orderby' => 'ID',
            'order' => 'ASC',
            'suppress_filters' => false,
        ]);
        if ($postIds === []) return;

        $fingerprint = hash('sha256', wp_json_encode([
            'count' => count($postIds),
            'ids' => array_map('intval', $postIds),
            'last_sync' => (string) get_option('bp_calendar_last_sync', ''),
        ]));
        $workspaceExists = get_option(Workspace::OPTION, null) !== null;
        $dirty = (string) get_option(self::DIRTY_OPTION, '1') === '1';
        if (! $force && $workspaceExists && ! $dirty && hash_equals((string) get_option(self::FINGERPRINT_OPTION, ''), $fingerprint)) return;

        $workspace = Workspace::load();
        $workspace['source_events'] = array_values(array_filter((array) $workspace['source_events'], static fn($event): bool => ! is_array($event) || ($event['source_id'] ?? '') !== self::SOURCE_ID));
        $workspace['local_events'] = array_values(array_filter((array) $workspace['local_events'], static fn($event): bool => ! is_array($event) || ! str_starts_with((string) ($event['id'] ?? ''), 'legacy-bp:')));
        foreach (array_keys((array) $workspace['overrides']) as $eventId) {
            if (str_starts_with((string) $eventId, 'legacy-bp:')) unset($workspace['overrides'][$eventId]);
        }
        $workspace['sources'] = array_values(array_filter((array) $workspace['sources'], static fn($source): bool => ! is_array($source) || ($source['id'] ?? '') !== self::SOURCE_ID));
        $workspace['sources'][] = [
            'id' => self::SOURCE_ID,
            'name' => __('Imported legacy calendar', 'help4-builder-suite'),
            'provider' => 'google',
            'enabled' => true,
            'status' => 'connected',
            'last_sync_at' => (string) get_option('bp_calendar_last_sync', ''),
            'last_sync_count' => count($postIds),
            'extensions' => ['contract' => 'bp_calendar_event', 'read_only_bridge' => true],
        ];

        foreach ($postIds as $postId) {
            $postId = (int) $postId;
            $googleUid = self::meta($postId, '_bp_google_uid');
            $eventId = 'legacy-bp:' . $postId;
            $source = [
                'id' => $eventId,
                'source_id' => $googleUid !== '' ? self::SOURCE_ID : '',
                'title' => self::sourceValue($postId, '_bp_source_title', get_the_title($postId)),
                'description' => self::sourceValue($postId, '_bp_source_description', ''),
                'start' => self::sourceValue($postId, '_bp_source_start', ''),
                'end' => self::sourceValue($postId, '_bp_source_end', ''),
                'all_day' => self::meta($postId, '_bp_source_all_day') === '1',
                'location' => self::sourceValue($postId, '_bp_source_location', ''),
                'category' => self::sourceValue($postId, '_bp_source_category', 'event'),
                'venue_name' => self::sourceValue($postId, '_bp_source_location', ''),
                'ticket_url' => self::meta($postId, '_bp_override_cta_url'),
                'updated_at' => self::meta($postId, '_bp_google_updated'),
                'extensions' => [
                    'legacy_post_id' => $postId,
                    'legacy_post_type' => self::POST_TYPE,
                    'google_uid' => $googleUid,
                    'google_key' => self::meta($postId, '_bp_google_key'),
                ],
            ];
            if ($googleUid !== '') $workspace['source_events'][] = $source;
            else $workspace['local_events'][] = $source;

            $workspace['overrides'][$eventId] = [
                'hidden' => self::meta($postId, '_bp_hidden') === '1',
                'title' => self::meta($postId, '_bp_override_title'),
                'description' => self::meta($postId, '_bp_override_description'),
                'category' => self::meta($postId, '_bp_override_category'),
                'venue_name' => self::meta($postId, '_bp_override_location'),
                'ticket_url' => self::meta($postId, '_bp_override_cta_url'),
                'extensions' => [
                    'cta_label' => self::meta($postId, '_bp_override_cta_label'),
                    'source_location' => self::meta($postId, '_bp_source_location'),
                    'source_all_day' => self::meta($postId, '_bp_source_all_day'),
                ],
            ];
        }

        $workspace['revision'] = max(1, (int) ($workspace['revision'] ?? 1)) + 1;
        $workspace['updated_at'] = current_time('mysql', true);
        $workspace['extensions']['legacy_post_bridge'] = [
            'contract_version' => '1.0',
            'post_type' => self::POST_TYPE,
            'source_id' => self::SOURCE_ID,
            'imported_count' => count($postIds),
            'fingerprint' => $fingerprint,
            'refreshed_at' => current_time('mysql', true),
            'destructive' => false,
        ];
        update_option(Workspace::OPTION, Workspace::sanitize($workspace), false);
        update_option(self::FINGERPRINT_OPTION, $fingerprint, false);
        update_option(self::DIRTY_OPTION, '0', false);
        do_action('h4bs_calendar_legacy_imported', count($postIds), $fingerprint);
    }

    private static function meta(int $postId, string $key): string
    {
        return (string) get_post_meta($postId, $key, true);
    }

    private static function sourceValue(int $postId, string $key, string $fallback): string
    {
        $value = self::meta($postId, $key);
        return $value !== '' ? $value : $fallback;
    }
}
