<?php
namespace WoolentorPro\Modules\FreeShippingBar\Frontend;
use WooLentorPro\Traits\Singleton;
use WoolentorPro\Modules\FreeShippingBar\Free_Shipping_Bar_Pro;

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

class Geo_Targeting {
    use Singleton;

    private function __construct() {
        add_filter( 'woolentor_fsb_get_threshold', [ $this, 'geo_threshold' ], 10, 1 );
    }

    public function geo_threshold( $threshold ) {
        if ( Free_Shipping_Bar_Pro::setting( 'enable_geo_targeting', 'off' ) !== 'on' ) {
            return $threshold;
        }

        $zone_threshold = $this->get_customer_zone_threshold();
        if ( $zone_threshold > 0 ) {
            return $zone_threshold;
        }

        $fallback = (float) Free_Shipping_Bar_Pro::setting( 'geo_fallback_threshold', 0 );
        if ( $fallback > 0 ) {
            return $fallback;
        }

        return $threshold;
    }

    private function get_customer_zone_threshold() {
        if ( ! function_exists( 'WC' ) || ! WC()->customer ) {
            return 0;
        }

        $customer = WC()->customer;
        $country  = $customer->get_shipping_country() ?: $customer->get_billing_country();
        $state    = $customer->get_shipping_state()   ?: $customer->get_billing_state();
        $postcode = $customer->get_shipping_postcode() ?: $customer->get_billing_postcode();

        if ( empty( $country ) ) {
            $geo     = \WC_Geolocation::geolocate_ip();
            $country = $geo['country'] ?? '';
        }

        if ( empty( $country ) ) {
            return 0;
        }

        $matched_zone = \WC_Shipping_Zones::get_zone_matching_package( [
            'destination' => [
                'country'  => $country,
                'state'    => $state,
                'postcode' => $postcode,
            ],
        ] );

        if ( ! $matched_zone ) {
            return 0;
        }

        foreach ( $matched_zone->get_shipping_methods( true ) as $method ) {
            if ( $method->id === 'free_shipping' ) {
                $min = isset( $method->instance_settings['min_amount'] )
                    ? (float) $method->instance_settings['min_amount']
                    : 0;
                if ( $min > 0 ) {
                    return $min;
                }
            }
        }

        return 0;
    }
}
