<?php
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

class PC_Membership_Access_Control {

    public static function init() {
        add_action( 'wp', array( __CLASS__, 'check_access' ) );
        add_action( 'template_redirect', array( __CLASS__, 'handle_restricted_access' ) );
    }

    public static function check_access() {
        if ( is_admin() ) {
            return;
        }

        if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
            return;
        }

        $content_id = 0;
        $content_type = '';

        if ( is_singular( 'post' ) ) {
            $content_id = get_the_ID();
            $content_type = 'post';
        } elseif ( is_singular( 'page' ) ) {
            $content_id = get_the_ID();
            $content_type = 'page';
        } elseif ( is_category() || is_archive() ) {
            $cat = get_queried_object();
            if ( $cat && isset( $cat->term_id ) ) {
                $content_id = $cat->term_id;
                $content_type = 'category';
            }
        }

        if ( empty( $content_id ) || empty( $content_type ) ) {
            return;
        }

        $rule = self::get_access_rule( $content_type, $content_id );

        if ( ! $rule ) {
            return;
        }

        if ( self::user_has_access( $rule ) ) {
            return;
        }

        self::redirect_user( $rule );
    }

    private static function get_access_rule( $content_type, $content_id ) {
        global $wpdb;

        return $wpdb->get_row( $wpdb->prepare(
            "SELECT * FROM {$wpdb->prefix}pc_membership_access_rules WHERE content_type = %s AND content_id = %d",
            $content_type,
            $content_id
        ) );
    }

    private static function user_has_access( $rule ) {
        if ( ! is_user_logged_in() ) {
            return false;
        }

        $plan_ids = maybe_unserialize( $rule->plan_ids );
        if ( ! is_array( $plan_ids ) ) {
            $plan_ids = array( $plan_ids );
        }

        if ( empty( $plan_ids ) ) {
            return true;
        }

        $user_id = get_current_user_id();

        global $wpdb;
        $subscription = $wpdb->get_row( $wpdb->prepare(
            "SELECT plan_id FROM {$wpdb->prefix}pc_membership_subscriptions WHERE user_id = %d AND status = 'active'",
            $user_id
        ) );

        if ( ! $subscription ) {
            return false;
        }

        return in_array( $subscription->plan_id, $plan_ids );
    }

    private static function redirect_user( $rule ) {
        $redirect_url = '';

        switch ( $rule->redirect_type ) {
            case 'custom':
                $redirect_url = ! empty( $rule->custom_url ) ? $rule->custom_url : self::get_default_redirect();
                break;
            case 'login':
                $redirect_url = self::get_page_url( 'login' );
                break;
            default:
                $redirect_url = self::get_page_url( 'checkout' );
        }

        if ( ! $redirect_url ) {
            $redirect_url = home_url();
        }

        wp_redirect( $redirect_url );
        exit;
    }

    private static function get_default_redirect() {
        return self::get_page_url( 'checkout' );
    }

    private static function get_page_url( $page_type ) {
        $options = get_option( 'pc_membership_options' );
        $page_id = isset( $options[ $page_type . '_page_id' ] ) ? absint( $options[ $page_type . '_page_id' ] ) : 0;
        return $page_id ? get_permalink( $page_id ) : '';
    }

    public static function handle_restricted_access() {
        if ( ! is_user_logged_in() ) {
            return;
        }

        global $post;

        if ( ! $post ) {
            return;
        }

        $content_type = $post->post_type === 'page' ? 'page' : 'post';

        $rule = self::get_access_rule( $content_type, $post->ID );

        if ( ! $rule ) {
            return;
        }

        if ( self::user_has_access( $rule ) ) {
            return;
        }

        self::redirect_user( $rule );
    }

    public static function is_content_restricted( $content_id, $content_type = 'post' ) {
        $rule = self::get_access_rule( $content_type, $content_id );
        return ! empty( $rule );
    }

    public static function can_access_content( $user_id, $content_id, $content_type = 'post' ) {
        $rule = self::get_access_rule( $content_type, $content_id );

        if ( ! $rule ) {
            return true;
        }

        if ( ! $user_id ) {
            return false;
        }

        $plan_ids = maybe_unserialize( $rule->plan_ids );
        if ( ! is_array( $plan_ids ) ) {
            $plan_ids = array( $plan_ids );
        }

        global $wpdb;
        $subscription = $wpdb->get_row( $wpdb->prepare(
            "SELECT plan_id FROM {$wpdb->prefix}pc_membership_subscriptions WHERE user_id = %d AND status = 'active'",
            $user_id
        ) );

        if ( ! $subscription ) {
            return false;
        }

        return in_array( $subscription->plan_id, $plan_ids );
    }

    public static function restrict_post( $post_id, $plan_ids, $redirect_type = 'checkout', $custom_url = '' ) {
        global $wpdb;

        $content_type = get_post_type( $post_id ) === 'page' ? 'page' : 'post';

        $existing = $wpdb->get_var( $wpdb->prepare(
            "SELECT id FROM {$wpdb->prefix}pc_membership_access_rules WHERE content_type = %s AND content_id = %d",
            $content_type,
            $post_id
        ) );

        if ( $existing ) {
            return $wpdb->update( $wpdb->prefix . 'pc_membership_access_rules', array(
                'plan_ids' => maybe_serialize( $plan_ids ),
                'redirect_type' => $redirect_type,
                'custom_url' => $redirect_type === 'custom' ? $custom_url : '',
            ), array( 'id' => $existing ) );
        }

        return $wpdb->insert( $wpdb->prefix . 'pc_membership_access_rules', array(
            'content_type'  => $content_type,
            'content_id'    => $post_id,
            'plan_ids'      => maybe_serialize( $plan_ids ),
            'redirect_type' => $redirect_type,
            'custom_url'    => $redirect_type === 'custom' ? $custom_url : '',
        ) );
    }

    public static function unrestrict_post( $post_id ) {
        global $wpdb;

        $content_type = get_post_type( $post_id ) === 'page' ? 'page' : 'post';

        return $wpdb->delete( $wpdb->prefix . 'pc_membership_access_rules', array(
            'content_type' => $content_type,
            'content_id'   => $post_id,
        ) );
    }
}
