<?php

declare(strict_types=1);

namespace SiteFort\Modules\WhiteLabel;

use SiteFort\Includes\Interfaces\Module;
use SiteFort\Includes\SettingsStore;

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

class WhiteLabel implements Module {

    private $branding = [];

    public function __construct( string $plugin_name, string $version ) {
        $this->branding = self::get_active_branding();
    }

    /**
     * Sanitize a branding text value.
     *
     * @param mixed $value Raw text value.
     * @param int   $max_length Maximum stored length.
     * @return string
     */
    public static function sanitize_brand_text( $value, int $max_length = 160 ): string {
        $value = sanitize_text_field( (string) $value );
        if ( function_exists( 'mb_substr' ) ) {
            return mb_substr( $value, 0, $max_length );
        }
        return substr( $value, 0, $max_length );
    }

    /**
     * Sanitize a public branding URL.
     *
     * @param mixed $value Raw URL value.
     * @return string
     */
    public static function sanitize_brand_url( $value ): string {
        $url = trim( (string) $value );
        if ( '' === $url ) {
            return '';
        }

        if ( strlen( $url ) > 2048 || preg_match( '/[\x00-\x1F\x7F]/', $url ) ) {
            return '';
        }

        $parts = wp_parse_url( $url );
        if ( ! is_array( $parts ) ) {
            return '';
        }

        $scheme = strtolower( (string) ( $parts['scheme'] ?? '' ) );
        $host   = strtolower( trim( (string) ( $parts['host'] ?? '' ) ) );
        if ( 'https' !== $scheme || '' === $host || ! empty( $parts['user'] ) || ! empty( $parts['pass'] ) ) {
            return '';
        }
        if ( 'localhost' === $host || substr( $host, -6 ) === '.local' ) {
            return '';
        }
        if ( filter_var( $host, FILTER_VALIDATE_IP ) && ! filter_var( $host, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) ) {
            return '';
        }

        return esc_url_raw( $url, [ 'https' ] );
    }

    /**
     * Normalize boolean values from JSON, import files, and options.
     *
     * @param mixed $value Raw boolean-like value.
     * @return bool
     */
    private static function normalize_brand_bool( $value ): bool {
        if ( is_bool( $value ) ) {
            return $value;
        }
        if ( is_int( $value ) || is_float( $value ) ) {
            return (int) $value === 1;
        }
        if ( is_string( $value ) ) {
            return in_array( strtolower( trim( $value ) ), [ '1', 'true', 'yes', 'on' ], true );
        }
        return false;
    }

    private static function normalize_brand_compare( string $value ): string {
        $normalized = preg_replace( '/\s+/', ' ', trim( $value ) );
        return strtolower( is_string( $normalized ) ? $normalized : trim( $value ) );
    }

    private static function is_vendor_plugin_name( string $value ): bool {
        return self::normalize_brand_compare( $value ) === 'sitefort';
    }

    private static function is_vendor_company_name( string $value ): bool {
        return self::normalize_brand_compare( $value ) === 'sitefort security';
    }

    private static function is_sitefort_default_branding( array $branding ): bool {
        if ( self::normalize_brand_compare( (string) ( $branding['plugin_name'] ?? '' ) ) !== 'sitefort' ) {
            return false;
        }

        $company_name = self::normalize_brand_compare( (string) ( $branding['company_name'] ?? '' ) );
        if ( $company_name !== '' && $company_name !== 'sitefort security' ) {
            return false;
        }

        foreach ( [ 'plugin_description', 'author_name', 'admin_footer_text', 'email_from_name', 'author_url', 'plugin_url', 'support_url' ] as $field ) {
            if ( ! empty( $branding[ $field ] ) ) {
                return false;
            }
        }

        return empty( $branding['hide_attribution'] ) && empty( $branding['hide_plugin'] );
    }

    private static function remove_vendor_brand_defaults( array $branding ): array {
        if ( self::is_sitefort_default_branding( $branding ) ) {
            return [];
        }

        if ( isset( $branding['plugin_name'] ) && self::is_vendor_plugin_name( (string) $branding['plugin_name'] ) ) {
            unset( $branding['plugin_name'] );
        }

        if ( isset( $branding['company_name'] ) && self::is_vendor_company_name( (string) $branding['company_name'] ) ) {
            unset( $branding['company_name'] );
        }

        return $branding;
    }

    /**
     * Normalize branding payloads before persistence.
     *
     * @param mixed $branding Raw branding payload.
     * @return array<string,mixed>
     */
    public static function normalize_branding( $branding ): array {
        if ( ! is_array( $branding ) ) {
            return [];
        }

        $clean_data = [];

        $required_text_fields = [
            'plugin_name'  => 80,
            'company_name' => 120,
        ];
        foreach ( $required_text_fields as $field => $max_length ) {
            if ( array_key_exists( $field, $branding ) ) {
                $value = self::sanitize_brand_text( $branding[ $field ], $max_length );
                if ( '' !== $value ) {
                    $clean_data[ $field ] = $value;
                }
            }
        }

        $text_fields = [
            'plugin_description' => 300,
            'author_name'        => 120,
            'admin_footer_text'  => 240,
            'email_from_name'    => 120,
        ];
        foreach ( $text_fields as $field => $max_length ) {
            if ( array_key_exists( $field, $branding ) ) {
                $value = self::sanitize_brand_text( $branding[ $field ], $max_length );
                if ( '' !== $value ) {
                    $clean_data[ $field ] = $value;
                }
            }
        }

        $url_fields = [ 'author_url', 'plugin_url', 'support_url', 'logo_url' ];
        foreach ( $url_fields as $field ) {
            if ( array_key_exists( $field, $branding ) ) {
                $value = self::sanitize_brand_url( $branding[ $field ] );
                if ( '' !== $value ) {
                    $clean_data[ $field ] = $value;
                }
            }
        }

        $bool_fields = [ 'hide_attribution', 'hide_plugin' ];
        foreach ( $bool_fields as $field ) {
            if ( array_key_exists( $field, $branding ) ) {
                $value = self::normalize_brand_bool( $branding[ $field ] );
                if ( $value ) {
                    $clean_data[ $field ] = true;
                }
            }
        }

        return self::remove_vendor_brand_defaults( $clean_data );
    }

    /**
     * Sanitize persisted branding payloads.
     *
     * @param mixed $branding Raw branding payload.
     * @return array<string,mixed>
     */
    private static function sanitize_branding( $branding ): array {
        return self::normalize_branding( $branding );
    }

    /**
     * Check whether stored license state may expose branding.
     *
     * @param array<string,mixed> $cloud_settings Stored cloud settings.
     * @return bool
     */
    public static function license_allows_branding( array $cloud_settings ): bool {
        $status = strtolower( sanitize_key( (string) ( $cloud_settings['license_status'] ?? '' ) ) );
        $plan = strtolower( sanitize_key( (string) ( $cloud_settings['license_plan'] ?? 'free' ) ) );
        $site_token = sanitize_text_field( (string) ( $cloud_settings['site_token'] ?? '' ) );
        $site_secret = sanitize_text_field( (string) ( $cloud_settings['site_secret'] ?? '' ) );

        return in_array( $status, [ 'active', 'valid' ], true )
            && in_array( $plan, [ 'pro', 'managed' ], true )
            && $site_token !== ''
            && $site_secret !== '';
    }

    /**
     * Return sanitized branding only when license state allows it.
     *
     * @return array<string,mixed>
     */
    public static function get_active_branding(): array {
        if (
            ! class_exists( '\\SiteFort\\Modules\\Cloud\\Service\\CloudSettings' )
            || ! self::license_allows_branding( \SiteFort\Modules\Cloud\Service\CloudSettings::get_all() )
        ) {
            return [];
        }

        return self::sanitize_branding( SettingsStore::get( SettingsStore::COL_BRANDING ) );
    }

    /**
     * Synchronize persisted branding with license state.
     *
     * @param array<string,mixed> $cloud_settings Stored cloud settings after hydration.
     * @param mixed              $branding_data Raw branding payload from Console.
     * @param bool               $branding_present Whether Console included branding.
     */
    public static function sync_for_license_state( array $cloud_settings, $branding_data = null, bool $branding_present = false ): void {
        if ( ! self::license_allows_branding( $cloud_settings ) ) {
            if ( ! empty( SettingsStore::get( SettingsStore::COL_BRANDING ) ) ) {
                self::update_settings( [] );
            }
            return;
        }

        if ( $branding_present ) {
            self::update_settings( $branding_data );
        }
    }

    public function initialize( \SiteFort\Includes\Module_Loader $loader ) {
        if ( empty( $this->branding ) ) {
            return;
        }

        $loader->add_action( 'admin_menu', $this, 'update_menu_name', 999 );
        $loader->add_filter( 'admin_footer_text', $this, 'update_footer_text', 999 );
        $loader->add_filter( 'all_plugins', $this, 'override_plugin_metadata', 999 );
        $loader->add_filter( 'admin_title', $this, 'override_admin_title', 999 );
    }

    public function update_menu_name() {
        global $menu;
        $plugin_name = $this->branding['plugin_name'] ?? 'SiteFort';

        if ( empty( $plugin_name ) || strcasecmp( $plugin_name, 'SiteFort' ) === 0 ) {
            return;
        }

        foreach ( $menu as $key => $item ) {
            if ( $item[2] === 'sitefort' ) {
                $menu[$key][0] = esc_html( $plugin_name );
                break;
            }
        }
    }

    public function update_footer_text( $text ) {
        $screen = get_current_screen();
        if ( ! $screen || strpos( $screen->id, 'sitefort' ) === false ) {
            return $text;
        }

        if ( ! empty( $this->branding['admin_footer_text'] ) ) {
            return wp_kses_post( $this->branding['admin_footer_text'] );
        }
        if ( ! empty( $this->branding['hide_attribution'] ) ) {
            return '';
        }
        return $text;
    }

    /**
     * Override plugin metadata on the Plugins page.
     *
     * @param array $plugins
     * @return array
     */
    public function override_plugin_metadata( $plugins ) {
        $plugin_file = '';
        foreach ( [ 'sitefort/sitefort.php' ] as $candidate ) {
            if ( isset( $plugins[ $candidate ] ) ) {
                $plugin_file = $candidate;
                break;
            }
        }

        if ( $plugin_file === '' ) {
            return $plugins;
        }

        if ( ! empty( $this->branding['hide_plugin'] ) ) {
            // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only query flag used only to reveal a hidden admin list entry.
            if ( sanitize_text_field( wp_unslash( $_GET['show_hidden_plugins'] ?? '' ) ) !== '1' ) {
                unset( $plugins[ $plugin_file ] );
                return $plugins;
            }
        }

        $b = $this->branding;

        // Text fields: escaped for display.
        $text_map = [
            'plugin_name'        => [ 'Name', 'Title' ],
            'plugin_description' => [ 'Description' ],
            'author_name'        => [ 'Author', 'AuthorName' ],
        ];
        foreach ( $text_map as $key => $fields ) {
            if ( ! empty( $b[ $key ] ) ) {
                foreach ( $fields as $f ) {
                    $plugins[ $plugin_file ][ $f ] = esc_html( $b[ $key ] );
                }
            }
        }

        // URL fields: escaped as URLs.
        $url_map = [
            'author_url' => 'AuthorURI',
            'plugin_url' => 'PluginURI',
        ];
        foreach ( $url_map as $key => $field ) {
            if ( ! empty( $b[ $key ] ) ) {
                $plugins[ $plugin_file ][ $field ] = esc_url( $b[ $key ], [ 'https' ] );
            }
        }

        return $plugins;
    }

    /**
     * Get the branded email sender name, or empty string if not set.
     *
     * @return string
     */
    public static function get_email_from_name(): string {
        $branding = self::get_active_branding();
        $name = $branding['email_from_name'] ?? '';
        return $name !== '' ? sanitize_text_field( $name ) : '';
    }

    /**
     * Replace "SiteFort" in the browser admin title.
     *
     * @param string $admin_title
     * @return string
     */
    public function override_admin_title( $admin_title ) {
        $screen = get_current_screen();
        if ( ! $screen || strpos( $screen->id, 'sitefort' ) === false ) {
            return $admin_title;
        }
        $plugin_name = $this->branding['plugin_name'] ?? '';
        if ( $plugin_name !== '' && strcasecmp( $plugin_name, 'SiteFort' ) !== 0 ) {
            return str_ireplace( 'SiteFort', esc_html( $plugin_name ), $admin_title );
        }
        return $admin_title;
    }
    
    /**
     * Persist sanitized branding data.
     *
     * @param mixed $branding_data Raw branding payload.
     */
    public static function update_settings( $branding_data ) {
        if ( empty( $branding_data ) || ! is_array( $branding_data ) ) {
            SettingsStore::save( SettingsStore::COL_BRANDING, [] );
            return;
        }

        SettingsStore::save( SettingsStore::COL_BRANDING, self::normalize_branding( $branding_data ) );
    }
}
