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

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

class Visibility {
    use Singleton;

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

    public function advanced_visibility( $show ) {
        if ( ! $this->check_exclude_pages() ) {
            return false;
        }

        // OR condition: if Layer 1 (Display On Pages) blocked this page, category
        // targeting can still grant access — but only on actual category/product pages,
        // not on home/shop/cart where check_category_targeting() would bypass with true.
        if ( ! $show ) {
            $raw        = Free_Shipping_Bar_Pro::setting( 'target_categories', [] );
            $categories = is_array( $raw )
                ? array_filter( $raw )
                : array_filter( array_map( 'trim', explode( ',', (string) $raw ) ) );

            if ( ! empty( $categories ) && ( is_product_category() || is_product() ) && $this->check_category_targeting() ) {
                $show = true;
            }
        }

        if ( ! $show ) {
            return false;
        }

        if ( ! $this->check_category_targeting() ) {
            return false;
        }

        if ( ! $this->check_user_role_targeting() ) {
            return false;
        }

        if ( ! $this->check_schedule() ) {
            return false;
        }

        return $show;
    }

    private function check_exclude_pages() {
        $exclude_ids = $this->parse_id_list( Free_Shipping_Bar_Pro::setting( 'target_exclude_pages', '' ) );
        if ( empty( $exclude_ids ) ) {
            return true;
        }
        return ! in_array( \Woolentor\Modules\FreeShippingBar\Frontend\Bar_Renderer::get_current_page_id(), $exclude_ids, true );
    }

    private function check_category_targeting() {
        $raw        = Free_Shipping_Bar_Pro::setting( 'target_categories', [] );
        $categories = is_array( $raw )
            ? array_filter( $raw )
            : array_filter( array_map( 'trim', explode( ',', (string) $raw ) ) );
        if ( empty( $categories ) ) {
            return true;
        }

        if ( is_product_category() ) {
            $term = get_queried_object();
            return in_array( $term->slug, $categories, true )
                || in_array( (string) $term->term_id, $categories, true );
        }

        if ( is_product() ) {
            $terms = get_the_terms( get_queried_object_id(), 'product_cat' );
            if ( ! $terms || is_wp_error( $terms ) ) {
                return false;
            }
            foreach ( $terms as $term ) {
                if ( in_array( $term->slug, $categories, true )
                    || in_array( (string) $term->term_id, $categories, true ) ) {
                    return true;
                }
            }
            return false;
        }

        return true;
    }

    private function check_user_role_targeting() {
        $required_role = Free_Shipping_Bar_Pro::setting( 'target_user_role', 'all' );

        if ( $required_role === 'all' ) {
            return true;
        }

        $logged_in = is_user_logged_in();

        if ( $required_role === 'guest' )     return ! $logged_in;
        if ( $required_role === 'logged_in' ) return $logged_in;

        if ( $required_role === 'customer' ) {
            if ( ! $logged_in ) return false;
            return wc_get_customer_order_count( get_current_user_id() ) > 0;
        }

        return true;
    }

    private function check_schedule() {
        if ( Free_Shipping_Bar_Pro::setting( 'enable_schedule', 'off' ) !== 'on' ) {
            return true;
        }

        $now   = time();
        $start = Free_Shipping_Bar_Pro::setting( 'schedule_start', '' );
        $end   = Free_Shipping_Bar_Pro::setting( 'schedule_end', '' );

        if ( $start !== '' ) {
            $start_ts = strtotime( $start );
            if ( $start_ts && $now < $start_ts ) return false;
        }

        if ( $end !== '' ) {
            $end_ts = strtotime( $end );
            if ( $end_ts && $now > $end_ts ) return false;
        }

        return true;
    }

    private function parse_id_list( $value ) {
        if ( empty( $value ) ) {
            return [];
        }
        $items = is_array( $value ) ? $value : explode( ',', (string) $value );
        return array_filter( array_map( 'intval', $items ) );
    }
}
