<?php
class WarmupManager
{
    private $db;
    private $log;
    private $server_ip;
    private $tableName = 'evp_ip_warmup';
    private $config = [];

    public function __construct($db, $log = null)
    {
        $this->db = $db;
        $this->log = $log;
        $this->server_ip = isset($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR'] : '127.0.0.1';
        $this->loadConfig();
    }

    private function loadConfig()
    {
        // Default Config
        $this->config = [
            'global_enabled' => false,
            'global_limit' => 20,
            'providers' => []
        ];

        $sql = "SELECT option_name, option_value FROM evp_options WHERE option_name IN ('warmup_config', 'warmup_status')";
        $res = null;
        if (method_exists($this->db, 'select')) {
            $res = $this->db->select($sql);
        } elseif (method_exists($this->db, 'query')) {
            $res = $this->db->query($sql);
        }

        if ($res && method_exists($res, 'fetch_assoc')) {
            while ($row = $res->fetch_assoc()) {
                if ($row['option_name'] === 'warmup_config' && !empty($row['option_value'])) {
                    $loaded = json_decode($row['option_value'], true);
                    if (is_array($loaded)) {
                        $this->config = array_merge($this->config, $loaded);
                    }
                }
                if ($row['option_name'] === 'warmup_status') {
                    $this->config['global_enabled'] = ($row['option_value'] === 'true');
                }
            }
        }

        if (empty($this->config['providers'])) {
            $this->injectDefaults();
        }
    }

    private function injectDefaults()
    {
        $defaults = [
            ['name' => 'Google', 'slug' => 'google', 'domains' => 'gmail.com, googlemail.com, google.com', 'limit' => 0, 'status' => 'active'],
            ['name' => 'Outlook', 'slug' => 'outlook', 'domains' => 'outlook.com, hotmail.com, live.com, msn.com', 'limit' => 0, 'status' => 'active'],
            ['name' => 'Yahoo', 'slug' => 'yahoo', 'domains' => 'yahoo.com, ymail.com, aol.com', 'limit' => 0, 'status' => 'active'],
            ['name' => 'Apple', 'slug' => 'apple', 'domains' => 'icloud.com, me.com, mac.com', 'limit' => 0, 'status' => 'active']
        ];
        $this->config['providers'] = $defaults;
    }

    private function escape($value)
    {
        if ($this->db && isset($this->db->link) && $this->db->link instanceof mysqli) {
            return mysqli_real_escape_string($this->db->link, (string) $value);
        }
        return addslashes((string) $value);
    }

    public function canScan($domain)
    {
        // 1. Check Global Switch
        if (empty($this->config['global_enabled'])) {
            return true;
        }

        $provider = $this->identifyProvider($domain);
        if (!$provider)
            return true;

        // 2. Check Provider Status
        if ($provider['status'] !== 'active') {
            return true;
        }

        // 3. Determine Limit
        $limit = ($provider['limit'] > 0) ? $provider['limit'] : $this->config['global_limit'];

        // 4. Check Usage
        $record = $this->getWarmupRecord($provider['slug']);
        if (!$record) {
            return true;
        }

        if ($record['daily_count'] >= $limit) {
            return false;
        }

        return true;
    }

    public function incrementCount($domain)
    {
        if (empty($this->config['global_enabled']))
            return;

        $provider = $this->identifyProvider($domain);
        if (!$provider)
            return;

        $safeSlug = $this->escape($provider['slug']);
        $safeIP = $this->escape($this->server_ip);

        $limit = ($provider['limit'] > 0) ? $provider['limit'] : $this->config['global_limit'];


        // Upsert Record
        $sql = "INSERT INTO {$this->tableName} (ip_address, provider_group, daily_count, last_sent_at, current_limit) 
                VALUES ('$safeIP', '$safeSlug', 1, NOW(), $limit)
                ON DUPLICATE KEY UPDATE 
                daily_count = IF(DATE(last_sent_at) < CURDATE(), 1, daily_count + 1), 
                last_sent_at = NOW(), 
                current_limit = $limit";

        if (method_exists($this->db, 'update')) {
            $res = $this->db->update($sql);
            if (!$res && $this->log) {
                $err = isset($this->db->error) ? $this->db->error : 'Unknown DB Error';
                $this->log->system_debug("[WARMUP ERROR] SQL Failed: $sql | Error: $err");
            }
        } elseif (method_exists($this->db, 'query')) {
            $this->db->query($sql);
        }
    }



    private function identifyProvider($domain)
    {
        $domain = strtolower(trim($domain));
        // Remove @
        if (strpos($domain, '@') !== false) {
            $parts = explode('@', $domain);
            $domain = array_pop($parts);
        }

        foreach ($this->config['providers'] as $p) {
            $domains_list = explode(',', $p['domains']);
            foreach ($domains_list as $d) {
                $d = trim($d);
                if (empty($d))
                    continue;
                if ($domain === $d)
                    return $p;
                if (substr($domain, -strlen('.' . $d)) === '.' . $d)
                    return $p;
            }
        }

        return null;
    }

    public function getProviderConfig()
    {
        return $this->config['providers'];
    }

    private function getWarmupRecord($slug)
    {
        $safeSlug = $this->escape($slug);
        $safeIP = $this->escape($this->server_ip);

        $sql = "SELECT * FROM {$this->tableName} WHERE provider_group = '$safeSlug' AND ip_address = '$safeIP' LIMIT 1";

        $res = null;
        if ($this->db instanceof DB) {
            $res = $this->db->select($sql);
        } elseif (method_exists($this->db, 'select')) {
            $res = $this->db->select($sql);
        } elseif (method_exists($this->db, 'query')) {
            $res = $this->db->query($sql);
        }

        if ($res && method_exists($res, 'fetch_assoc')) {
            $row = $res->fetch_assoc();
            // Lazy Reset check for Read
            if (isset($row['last_sent_at'])) {
                $lastDate = date('Y-m-d', strtotime($row['last_sent_at']));
                $today = date('Y-m-d');
                if ($lastDate < $today) {
                    $row['daily_count'] = 0; // Effective reset
                }
            }
            return $row;
        }
        return null;
    }
}
?>