<?php
namespace Bookaro\Utils;

defined( 'ABSPATH' ) || exit;

/**
 * Compatibility bridge for payout split settings/meta.
 *
 * Legacy `booking_deposit_*` options and `bookaro_deposit_*` order meta are
 * still read so existing sites continue to work. Public/runtime terminology is
 * normalized to payout split + website share values.
 */
final class PaymentSplitCompatibility
{
    public const PAYMENT_STATE_WEBSITE_SHARE_PAID_ONLINE = 'website_share_paid_online';
    public const PAYMENT_STATE_DEPOSIT_PAID_LEGACY = 'deposit_paid';

    /**
     * @return array<string,string>
     */
    public static function legacy_payment_state_aliases(): array
    {
        return [
            self::PAYMENT_STATE_DEPOSIT_PAID_LEGACY => self::PAYMENT_STATE_WEBSITE_SHARE_PAID_ONLINE,
            'website_share_paid' => self::PAYMENT_STATE_WEBSITE_SHARE_PAID_ONLINE,
            'split_paid_online' => self::PAYMENT_STATE_WEBSITE_SHARE_PAID_ONLINE,
        ];
    }

    public static function normalize_payment_state_key( string $state_key ): string
    {
        $state_key = sanitize_key( $state_key );
        if ( $state_key === '' ) {
            return '';
        }

        $aliases = self::legacy_payment_state_aliases();
        if ( isset( $aliases[ $state_key ] ) ) {
            return $aliases[ $state_key ];
        }

        return $state_key;
    }

    public static function is_website_share_paid_online_state( string $state_key ): bool
    {
        return self::normalize_payment_state_key( $state_key ) === self::PAYMENT_STATE_WEBSITE_SHARE_PAID_ONLINE;
    }

    public static function get_legacy_payment_state_key( string $state_key ): string
    {
        if ( self::is_website_share_paid_online_state( $state_key ) ) {
            return self::PAYMENT_STATE_DEPOSIT_PAID_LEGACY;
        }

        return sanitize_key( $state_key );
    }

    /**
     * @param array<string, mixed> $options
     * @return array{
     *     payout_split_type:string,
     *     website_share_percent:int,
     *     website_share_amount:float
     * }
     */
    public static function get_runtime_split_from_options( array $options = [] ): array
    {
        $type = self::normalize_payout_split_type(
            (string) self::read_option_value(
                $options,
                [ 'payout_split_type', 'booking_deposit_type', 'deposit_type' ],
                'percent'
            )
        );

        $percent = self::normalize_website_share_percent(
            self::read_option_value(
                $options,
                [ 'website_share_percent', 'booking_deposit_percent', 'deposit_percent' ],
                100
            )
        );

        $amount = self::normalize_website_share_amount(
            self::read_option_value(
                $options,
                [ 'website_share_amount', 'booking_deposit_amount', 'deposit_amount' ],
                0
            )
        );

        return [
            'payout_split_type' => $type,
            'website_share_percent' => $percent,
            'website_share_amount' => $amount,
        ];
    }

    public static function normalize_payout_split_type( string $type ): string
    {
        $type = sanitize_key( $type );
        if ( ! in_array( $type, [ 'percent', 'fixed' ], true ) ) {
            $type = 'percent';
        }

        return $type;
    }

    /**
     * @param mixed $percent
     */
    public static function normalize_website_share_percent( $percent, int $default = 100 ): int
    {
        $value = (int) $percent;
        if ( $value < 0 || $value > 100 ) {
            $value = $default;
        }
        if ( $value < 0 ) {
            $value = 0;
        }
        if ( $value > 100 ) {
            $value = 100;
        }

        return $value;
    }

    /**
     * @param mixed $amount
     */
    public static function normalize_website_share_amount( $amount, float $default = 0.0 ): float
    {
        if ( $amount === '' || $amount === null || ! is_numeric( $amount ) ) {
            $value = $default;
        } else {
            $value = (float) $amount;
        }
        if ( $value < 0 ) {
            $value = 0.0;
        }

        return $value;
    }

    public static function resolve_website_share_amount(
        float $full_amount,
        string $payout_split_type,
        float $website_share_amount,
        int $website_share_percent
    ): float {
        $full_amount = max( 0.0, $full_amount );
        if ( $full_amount <= 0 ) {
            return 0.0;
        }

        $payout_split_type = self::normalize_payout_split_type( $payout_split_type );
        $website_share_amount = self::normalize_website_share_amount( $website_share_amount );
        $website_share_percent = self::normalize_website_share_percent( $website_share_percent );
        $decimals = function_exists( 'wc_get_price_decimals' ) ? (int) wc_get_price_decimals() : 2;

        if ( $payout_split_type === 'fixed' ) {
            return round( min( $full_amount, $website_share_amount ), $decimals );
        }

        if ( $website_share_percent <= 0 ) {
            return 0.0;
        }
        if ( $website_share_percent >= 100 ) {
            return round( $full_amount, $decimals );
        }

        return round( ( $full_amount * $website_share_percent ) / 100, $decimals );
    }

    /**
     * @param object $order
     * @return array{
     *     payout_split_type:string,
     *     website_share_percent:int,
     *     website_share_amount:float,
     *     website_share_value:float,
     *     website_share_paid_online:float,
     *     legacy_split_meta_used:bool
     * }
     */
    public static function read_order_split_meta( $order ): array
    {
        $public_type_raw = self::read_order_meta_value( $order, 'bookaro_payout_split_type', '' );
        $legacy_type_raw = self::read_order_meta_value( $order, 'bookaro_deposit_type', '' );
        $public_percent_raw = self::read_order_meta_value( $order, 'bookaro_website_share_percent', '' );
        $legacy_percent_raw = self::read_order_meta_value( $order, 'bookaro_deposit_percent', '' );
        $public_amount_raw = self::read_order_meta_value( $order, 'bookaro_website_share_amount', '' );
        $legacy_amount_raw = self::read_order_meta_value( $order, 'bookaro_deposit_amount', '' );
        $public_value_raw = self::read_order_meta_value( $order, 'bookaro_website_share_value', '' );
        $legacy_value_raw = self::read_order_meta_value( $order, 'bookaro_deposit_value', '' );
        $public_paid_online_raw = self::read_order_meta_value( $order, 'bookaro_website_share_paid_online', '' );

        $type = self::normalize_payout_split_type(
            (string) ( $public_type_raw !== '' ? $public_type_raw : $legacy_type_raw )
        );
        $percent = self::normalize_website_share_percent(
            $public_percent_raw !== '' ? $public_percent_raw : $legacy_percent_raw
        );
        $amount = self::normalize_website_share_amount(
            $public_amount_raw !== '' ? $public_amount_raw : $legacy_amount_raw
        );
        $value = self::normalize_website_share_amount(
            $public_value_raw !== '' ? $public_value_raw : $legacy_value_raw
        );
        $paid_online = self::normalize_website_share_amount( $public_paid_online_raw, 0.0 );

        return [
            'payout_split_type' => $type,
            'website_share_percent' => $percent,
            'website_share_amount' => $amount,
            'website_share_value' => $value,
            'website_share_paid_online' => $paid_online,
            // Compatibility-only marker for legacy `bookaro_deposit_*` order meta.
            'legacy_split_meta_used' => (
                ( $public_type_raw === '' && $legacy_type_raw !== '' ) ||
                ( $public_percent_raw === '' && $legacy_percent_raw !== '' ) ||
                ( $public_amount_raw === '' && $legacy_amount_raw !== '' ) ||
                ( $public_value_raw === '' && $legacy_value_raw !== '' )
            ),
        ];
    }

    /**
     * @param object $order
     * @param array{
     *     payout_split_type?:string,
     *     website_share_percent?:int,
     *     website_share_amount?:float,
     *     website_share_value?:float,
     *     website_share_paid_online?:float
     * } $data
     */
    public static function write_order_split_meta( $order, array $data ): void
    {
        if ( ! is_object( $order ) || ! method_exists( $order, 'update_meta_data' ) ) {
            return;
        }

        $type = self::normalize_payout_split_type( (string) ( $data['payout_split_type'] ?? 'percent' ) );
        $percent = self::normalize_website_share_percent( $data['website_share_percent'] ?? 100 );
        $amount = self::normalize_website_share_amount( $data['website_share_amount'] ?? 0 );
        $value = self::normalize_website_share_amount( $data['website_share_value'] ?? 0 );
        $paid_online = self::normalize_website_share_amount( $data['website_share_paid_online'] ?? 0 );

        $order->update_meta_data( 'bookaro_payout_split_type', $type );
        $order->update_meta_data( 'bookaro_website_share_percent', $percent );
        $order->update_meta_data( 'bookaro_website_share_amount', $amount );
        $order->update_meta_data( 'bookaro_website_share_value', $value );
        $order->update_meta_data( 'bookaro_website_share_paid_online', $paid_online );

        // Legacy `bookaro_deposit_*` mirrors retained for backward compatibility.
        $order->update_meta_data( 'bookaro_deposit_type', $type );
        $order->update_meta_data( 'bookaro_deposit_percent', $percent );
        $order->update_meta_data( 'bookaro_deposit_amount', $amount );
        $order->update_meta_data( 'bookaro_deposit_value', $value );
    }

    /**
     * @param object $order
     * @return array{
     *     full_amount:float,
     *     payment_mode:string,
     *     website_amount:float,
     *     provider_amount:float,
     *     payout_split_type:string,
     *     website_share_percent:int,
     *     website_share_amount:float,
     *     website_share_paid_online:float,
     *     legacy_split_meta_used:bool
     * }
     */
    public static function resolve_order_settlement( $order, float $fallback_full_amount = 0.0 ): array
    {
        $full_amount = (float) self::read_order_meta_value( $order, 'bookaro_full_amount', 0.0 );
        if ( $full_amount <= 0 ) {
            $full_amount = max( 0.0, $fallback_full_amount );
        }
        $payment_mode = sanitize_key( (string) self::read_order_meta_value( $order, 'bookaro_payment_mode', '' ) );
        $website_amount = max( 0.0, (float) self::read_order_meta_value( $order, 'bookaro_website_amount', 0.0 ) );
        $provider_amount = max( 0.0, (float) self::read_order_meta_value( $order, 'bookaro_provider_amount', 0.0 ) );

        $split = self::read_order_split_meta( $order );
        if ( $website_amount <= 0 && $provider_amount <= 0 ) {
            if ( $payment_mode === 'pay_later' ) {
                $website_amount = 0.0;
                $provider_amount = max( 0.0, $full_amount );
            } else {
                $website_amount = self::resolve_website_share_amount(
                    $full_amount,
                    (string) $split['payout_split_type'],
                    (float) $split['website_share_amount'],
                    (int) $split['website_share_percent']
                );
                $provider_amount = max( 0.0, $full_amount - $website_amount );
            }
        }

        $website_share_paid_online = max( 0.0, (float) $split['website_share_paid_online'] );
        if ( $website_share_paid_online <= 0 && $payment_mode !== 'pay_later' ) {
            $website_share_paid_online = $website_amount;
        }
        if ( $payment_mode === 'pay_later' ) {
            $website_share_paid_online = 0.0;
        }

        return [
            'full_amount' => max( 0.0, $full_amount ),
            'payment_mode' => $payment_mode,
            'website_amount' => max( 0.0, $website_amount ),
            'provider_amount' => max( 0.0, $provider_amount ),
            'payout_split_type' => (string) $split['payout_split_type'],
            'website_share_percent' => (int) $split['website_share_percent'],
            'website_share_amount' => (float) $split['website_share_amount'],
            'website_share_paid_online' => $website_share_paid_online,
            'legacy_split_meta_used' => ! empty( $split['legacy_split_meta_used'] ),
        ];
    }

    /**
     * @param array<string, mixed> $options
     * @param array<int, string> $keys
     * @param mixed $default
     * @return mixed
     */
    private static function read_option_value( array $options, array $keys, $default )
    {
        foreach ( $keys as $key ) {
            if ( array_key_exists( $key, $options ) ) {
                return $options[ $key ];
            }
        }

        if ( function_exists( 'bookaro_get_option' ) ) {
            $sentinel = '__bookaro_split_missing__';
            foreach ( $keys as $key ) {
                $value = bookaro_get_option( $key, $sentinel );
                if ( $value !== $sentinel ) {
                    return $value;
                }
            }
        }

        return $default;
    }

    /**
     * @param object $order
     * @param mixed $default
     * @return mixed
     */
    private static function read_order_meta_value( $order, string $key, $default )
    {
        if ( ! is_object( $order ) || ! method_exists( $order, 'get_meta' ) ) {
            return $default;
        }

        $value = $order->get_meta( $key, true );
        if ( $value === '' || $value === null ) {
            return $default;
        }

        return $value;
    }
}
