<?php

namespace PloverCRM\Core\Services;

/**
 * Canonical registry for internal/system-managed CRM fields.
 *
 * Keep this as the single source of truth for field definitions so features
 * do not create provider-specific fields ad hoc.
 */
class SystemFieldRegistry
{
    public const CAPABILITY_CORE_STAGES = 'core.stages';
    public const CAPABILITY_TRACKING_ENRICHMENT = 'tracking.contact_enrichment';
    public const CAPABILITY_META_LEAD_ADS = 'integrations.meta_lead_ads';
    public const TRACKING_PERMISSION_CONTACT_DATA = 'contact_tracking';
    public const TRACKING_PERMISSION_IP_INFORMATION = 'contact_ip_information';

    public const FIELD_STAGE = 'stage-plover-crm';
    public const FIELD_FACEBOOK_LEAD_ID = 'facebook_lead_id';

    public static function getFieldsForCapability(string $capabilityId): array
    {
        return match ($capabilityId) {
            self::CAPABILITY_CORE_STAGES => [
                self::stageField(),
            ],
            self::CAPABILITY_TRACKING_ENRICHMENT => self::contactEnrichmentFields(),
            self::CAPABILITY_META_LEAD_ADS => self::metaLeadAdsFields(),
            default => [],
        };
    }

    public static function getAllSystemFields(): array
    {
        return self::getFieldsForCapabilities([
            self::CAPABILITY_CORE_STAGES,
            self::CAPABILITY_TRACKING_ENRICHMENT,
            self::CAPABILITY_META_LEAD_ADS,
        ]);
    }

    public static function getAllSystemSlugs(): array
    {
        return array_values(array_filter(array_map(
            static fn (array $field): string => (string) ($field['slug'] ?? ''),
            self::getAllSystemFields()
        )));
    }

    public static function isSystemSlug(string $slug): bool
    {
        return in_array($slug, self::getAllSystemSlugs(), true);
    }

    public static function getTrackingFieldSlugs(): array
    {
        return array_values(array_filter(array_map(
            static fn (array $field): string => (string) ($field['slug'] ?? ''),
            array_filter(
                self::getFieldsForCapability(self::CAPABILITY_TRACKING_ENRICHMENT),
                static fn (array $field): bool => self::resolveTrackingPermissionGroup(
                    (string) ($field['slug'] ?? '')
                ) === self::TRACKING_PERMISSION_CONTACT_DATA
            )
        )));
    }

    public static function isTrackingSlug(string $slug): bool
    {
        return in_array($slug, self::getTrackingFieldSlugs(), true);
    }

    public static function getIpInformationFieldSlugs(): array
    {
        return [
            'ip',
            'latitude',
            'longitude',
            'plover_crm_ip_info',
        ];
    }

    public static function isIpInformationSlug(string $slug): bool
    {
        return in_array($slug, self::getIpInformationFieldSlugs(), true);
    }

    public static function getTrackingPermissionDefinitions(): array
    {
        return [
            [
                'key' => self::TRACKING_PERMISSION_CONTACT_DATA,
                'label' => 'Tracking Data',
                'description' => 'Controls read access to visitor, attribution, UTM, referral, device, and page visit tracking fields.',
                'fields' => self::getTrackingFieldSlugs(),
            ],
            [
                'key' => self::TRACKING_PERMISSION_IP_INFORMATION,
                'label' => 'IP Information',
                'description' => 'Controls read access to raw IP and IP-derived location fields.',
                'fields' => self::getIpInformationFieldSlugs(),
            ],
        ];
    }

    public static function isVisibleInIntegrationMapping(string $slug): bool
    {
        if ($slug === '') {
            return false;
        }

        if (!self::isSystemSlug($slug)) {
            return true;
        }

        return in_array($slug, self::getIntegrationMappingSystemSlugs(), true);
    }

    public static function getIntegrationMappingSystemSlugs(): array
    {
        return [
            self::FIELD_STAGE,
        ];
    }

    public static function getFieldsForCapabilities(array $capabilityIds): array
    {
        $fieldsBySlug = [];

        foreach ($capabilityIds as $capabilityId) {
            foreach (self::getFieldsForCapability((string) $capabilityId) as $field) {
                $slug = (string) ($field['slug'] ?? '');
                if ($slug === '') {
                    continue;
                }

                $fieldsBySlug[$slug] = $field;
            }
        }

        return array_values($fieldsBySlug);
    }

    public static function stageField(array $stages = []): array
    {
        $defaultStages = !empty($stages)
            ? array_values(array_filter(array_map('strval', $stages), static fn ($stage) => $stage !== ''))
            : ['New', 'Contacted', 'On Trial', 'On Hold', 'At Risk', 'Unpaid', 'Paid', 'Lost'];

        return array_merge(self::systemMeta(self::CAPABILITY_CORE_STAGES), [
            'type' => 'select',
            'field_key' => 'select',
            'label' => 'Stage',
            'options' => $defaultStages,
            'slug' => self::FIELD_STAGE,
            'group' => 'CRM',
        ]);
    }

    private static function contactEnrichmentFields(): array
    {
        $fields = [];

        $firstTouchFields = [
            'plover_crm_utm_id' => 'UTM ID',
            'plover_crm_utm_source' => 'UTM Source',
            'plover_crm_utm_medium' => 'UTM Medium',
            'plover_crm_utm_campaign' => 'UTM Campaign',
            'plover_crm_utm_term' => 'UTM Term',
            'plover_crm_utm_content' => 'UTM Content',
            'plover_crm_gclid' => 'Google Click ID',
            'plover_crm_fbclid' => 'Facebook Click ID',
            'plover_crm_msclkid' => 'Microsoft Click ID',
            'plover_crm_ttclid' => 'TikTok Click ID',
            'plover_crm_li_fat_id' => 'LinkedIn Click ID',
            'plover_crm_twclid' => 'Twitter Click ID',
            'plover_crm_referral_domain' => 'Referral Domain',
        ];

        $lastTouchFields = [
            'plover_crm_last_utm_source' => 'Last UTM Source',
            'plover_crm_last_utm_medium' => 'Last UTM Medium',
            'plover_crm_last_utm_campaign' => 'Last UTM Campaign',
            'plover_crm_last_utm_term' => 'Last UTM Term',
            'plover_crm_last_utm_content' => 'Last UTM Content',
            'plover_crm_last_referral_domain' => 'Last Referral Domain',
            'plover_crm_last_page_url' => 'Last Page URL',
        ];

        foreach ($firstTouchFields as $slug => $label) {
            $fields[] = self::trackingTextField(
                $slug,
                $label,
                str_contains($slug, 'utm_') ? 'UTM Tracking' : 'Visitor Metadata'
            );
        }

        foreach ($lastTouchFields as $slug => $label) {
            $fields[] = self::trackingTextField(
                $slug,
                $label,
                str_contains($slug, 'utm_') ? 'UTM Tracking' : 'Visitor Metadata'
            );
        }

        $fields[] = self::trackingField('textarea', 'IP info', 'plover_crm_ip_info', 'Visitor Metadata');
        $fields[] = self::trackingField('text', 'Submission URL', 'plover_crm_submission_url', 'Visitor Metadata');
        $fields[] = self::trackingField('text', 'Device Type', 'plover_crm_device_type', 'Visitor Metadata');
        $fields[] = self::trackingField('text', 'Device Brand', 'plover_crm_device_brand', 'Visitor Metadata');
        $fields[] = self::trackingField('text', 'Operating System', 'plover_crm_user_os', 'Visitor Metadata');
        $fields[] = self::trackingField('text', 'Browser Name', 'plover_crm_browser_name', 'Visitor Metadata');
        $fields[] = self::trackingField('text', 'Landing Page (First Visit)', 'plover_crm_landing_page_first_visit', 'Visitor Metadata');
        $fields[] = self::trackingField('datetime', 'Landing Datetime (First Visit)', 'plover_crm_landing_datetime_first_visit', 'Visitor Metadata');
        $fields[] = self::trackingField('datetime', 'Last Seen At', 'plover_crm_last_seen_at', 'Visitor Metadata');

        return $fields;
    }

    private static function metaLeadAdsFields(): array
    {
        return [
            array_merge(self::systemMeta(self::CAPABILITY_META_LEAD_ADS), [
                'type' => 'text',
                'field_key' => 'text',
                'label' => 'Facebook Lead ID',
                'slug' => self::FIELD_FACEBOOK_LEAD_ID,
                'group' => 'Ads',
                'readonly' => true,
            ]),
        ];
    }

    private static function trackingTextField(string $slug, string $label, string $group): array
    {
        return self::trackingField('text', $label, $slug, $group);
    }

    private static function trackingField(string $type, string $label, string $slug, string $group): array
    {
        return array_merge(self::systemMeta(self::CAPABILITY_TRACKING_ENRICHMENT), [
            'type' => $type,
            'field_key' => $type,
            'label' => $label,
            'slug' => $slug,
            'group' => $group,
            'permission_group' => self::resolveTrackingPermissionGroup($slug),
            'readonly' => true,
        ]);
    }

    private static function resolveTrackingPermissionGroup(string $slug): string
    {
        return $slug === 'plover_crm_ip_info'
            ? self::TRACKING_PERMISSION_IP_INFORMATION
            : self::TRACKING_PERMISSION_CONTACT_DATA;
    }

    private static function systemMeta(string $capabilityId): array
    {
        return [
            'system' => true,
            'owner_capability' => $capabilityId,
            'visibility' => 'internal',
        ];
    }
}
