<?php

namespace Blazemedia\Blackhole;

use Blazemedia\Blackhole\Tools\SimpleDB;
use Blazemedia\Blackhole\Types\PostItem;

class OfferListProvider {

    const DEFAULT_CUTOFF_DAYS = 180;
    const DEFAULT_TRAFFIC_LOOKBACK_DAYS = 7;
    const DEFAULT_USERS_THRESHOLD = 10;
    const DEFAULT_ANALYTICS_ENABLED = true;

    private array $dryRunCandidates = array();
    private int $trafficLookbackDays = self::DEFAULT_TRAFFIC_LOOKBACK_DAYS;
    private int $usersThreshold = self::DEFAULT_USERS_THRESHOLD;
    private bool $analyticsEnabled = self::DEFAULT_ANALYTICS_ENABLED;
    private array $settings = array();


    function __construct(
        protected SimpleDB $db,
        private bool $dryRun = false
        ) {
        $this->settings = get_option( 'blackhole_settings_option', array() );
        $this->trafficLookbackDays = $this->resolveTrafficLookbackDays();
        $this->usersThreshold = $this->resolveUsersThreshold();
        $this->analyticsEnabled = $this->resolveAnalyticsEnabled();
    }


    function scan() {

        $beforeTimestamp = $this->getCutoffTimestamp();
        $cutoffDayStart = strtotime( date( 'Y-m-d 00:00:00', $beforeTimestamp ) );

        echo "Before: ".date('Y-m-d', $beforeTimestamp ) . "\n";

        if ( $this->dryRun ) {
            $yesterdayStart = strtotime( 'yesterday 00:00:00' );
            $todayStart = strtotime( 'today 00:00:00' );

            echo "Dry run window: " . date( 'Y-m-d', $yesterdayStart ) . "\n";
            $this->db->forEachOfferPostInRange( [$this, 'checkWpPost'], $yesterdayStart, $todayStart );
            return;
        }

        $oldestTimestamp = $this->db->getOldestOfferPostTimestampBefore( $beforeTimestamp );
        if ( $oldestTimestamp <= 0 ) {
            echo "No posts found in selected range.\n";
            return;
        }

        $cursor = strtotime( date( 'Y-m-d 00:00:00', $oldestTimestamp ) );
        while ( $cursor < $cutoffDayStart ) {
            $nextCursor = $cursor + DAY_IN_SECONDS;
            echo "Processing day: " . date( 'Y-m-d', $cursor ) . "\n";
            $this->db->forEachOfferPostInRange( [$this, 'checkWpPost'], $cursor, $nextCursor );
            $cursor = $nextCursor;
        }
    }


    public function checkWpPost( $wp_post ){
        /// if already inserted do nothing
        if( !$this->dryRun && $this->db->exists( $wp_post->ID) ) return;
        
        $post = new PostItem( $wp_post, $this->trafficLookbackDays, $this->analyticsEnabled );

        echo json_encode( $post->toArray() ) ."\n";

        if( $this->hasNotEnoughTraffic( $post ) ) $this->insertIntoList( $post );
    }


    function insertIntoList( PostItem $post ) {
        if ( $this->dryRun ) {
            $this->dryRunCandidates[] = $post->toArray();
            return;
        }

        $this->db->save( $post );
    }


    function hasNotEnoughTraffic( $post ) {
        if ( !$this->analyticsEnabled ) {
            return true;
        }

        return $post->users < $this->usersThreshold;
    }

    public function getDryRunCandidates() : array {
        return $this->dryRunCandidates;
    }

    private function getCutoffTimestamp() : int {
        $mode = isset( $this->settings['cutoff_mode'] ) ? sanitize_key( $this->settings['cutoff_mode'] ) : 'days';

        if ( $mode === 'fixed_date' && !empty( $this->settings['cutoff_date'] ) ) {
            $fixedDate = sanitize_text_field( $this->settings['cutoff_date'] );
            $fixedTimestamp = strtotime( $fixedDate . ' 23:59:59' );

            if ( $fixedTimestamp !== false ) {
                return $fixedTimestamp;
            }
        }

        $days = isset( $this->settings['cutoff_days'] ) ? absint( $this->settings['cutoff_days'] ) : self::DEFAULT_CUTOFF_DAYS;
        if ( $days <= 0 ) {
            $days = self::DEFAULT_CUTOFF_DAYS;
        }

        return strtotime('now') - ( DAY_IN_SECONDS * $days );
    }

    private function resolveTrafficLookbackDays() : int {
        $days = isset( $this->settings['traffic_lookback_days'] ) ? absint( $this->settings['traffic_lookback_days'] ) : self::DEFAULT_TRAFFIC_LOOKBACK_DAYS;
        return $days > 0 ? $days : self::DEFAULT_TRAFFIC_LOOKBACK_DAYS;
    }

    private function resolveUsersThreshold() : int {
        $threshold = isset( $this->settings['users_threshold'] ) ? absint( $this->settings['users_threshold'] ) : self::DEFAULT_USERS_THRESHOLD;
        return $threshold >= 0 ? $threshold : self::DEFAULT_USERS_THRESHOLD;
    }

    private function resolveAnalyticsEnabled() : bool {
        if ( !array_key_exists( 'analytics_enabled', $this->settings ) ) {
            return self::DEFAULT_ANALYTICS_ENABLED;
        }

        return !empty( $this->settings['analytics_enabled'] );
    }

}
