<?php

namespace NewsletterBridge\Lib;

use NewsletterBridge\Utils\Service;
use NewsletterBridge\Config\DatabaseConfig;


/**
 * Si occupa di interrogare il 
 * querydispatcher 
 * 
 * @method getOffers( string ) ritorna le offerte per la query in ingresso
 * 
 */
class DB extends Service {

    function __construct() {

        $this->setName("Database Storage");
        $this->setCode("db");
        $this->setDescription("Gestisce il salvataggio delle iscrizioni nel database");
        $this->setParams([]);
        
    }

    public function subscribe($param)
    {
        $config = DatabaseConfig::getConfig();

        $email   = $param['email'] ?? '';
        
        if (empty($email) || !preg_match('/^([a-z0-9_\.-])+@(([a-z0-9_-])+\.)+[a-z]{2,6}$/Di', $email)) 
            return (["ERROR","Formato email non valido"]);
    
        $ip = (!empty($param['ip'])) ? $param['ip'] :  $this->getUserIP();

        $inviaDem = $param['inviaDem'] ?? 'true';
        $inviaDem = ($inviaDem == 'true' || $inviaDem == '1') ? 1 : 0; // NORMALIZE INVIADEV VALUE
        $url = $param['url'] ?? "";
        
        
        $pdo = new \PDO($config->dsn, $config->user, $config->password, $config->options);
        $stmt = $pdo->prepare("SELECT * FROM users where email = ? AND domain = ?");
        $stmt->execute([$email, $config->domain]);
        $row = $stmt->fetch(\PDO::FETCH_ASSOC);
        // deleted era a 2 nel caso di optin su registrazione
        // ora è a 0 
        // da sistemare con attenzione
        if (! $row) {
            if ($inviaDem == 1) {
                $sql = "INSERT INTO users (deleted,domain,email,trattamento_privacy_day,invio_dem,invio_dem_day,from_ip) VALUES (0,?,?,NOW(),?,NOW(),?)";
                $stmt = $pdo->prepare($sql);
                $stmt->execute([$config->domain, $email, $inviaDem, $ip]);
            } else {
                $sql = "INSERT INTO users (deleted,domain,email,trattamento_privacy_day,invio_dem,from_ip) VALUES (0,?,?,NOW(),?,?)";
                $stmt = $pdo->prepare($sql);
                $stmt->execute([$config->domain, $email, $inviaDem, $ip]);
            }
            $lastID = $pdo->lastInsertId();
        } else {
            if ($row["deleted"] == 1) {
                $sql = "UPDATE users set deleted = '0', trattamento_privacy_day = NOW() ";
                $params = [];
                if ($inviaDem == 1) {
                    $sql .= " , invio_dem = ? ,  invio_dem_day = NOW() ";
                    $params[] = $inviaDem;
                }
                $sql .= " where ID = ?";
                $params[] = $row["ID"];
                $stmt = $pdo->prepare($sql);
                $stmt->execute($params);
            }

            if ($row["invio_dem"] != $inviaDem && !isset($param['optin'])) {
                $sql = "UPDATE users set invio_dem_day = NOW() , invio_dem = ? where ID = ?";
                $stmt = $pdo->prepare($sql);
                $stmt->execute([$inviaDem, $row["ID"]]);
            }
            $lastID = $row["ID"];
        }

        return ["SUCCESS","Email inscritta con successo"];
    } // end function subscribe()

    public function subscribeoptin($param)
    {
        $config = DatabaseConfig::getConfig();
        $domain = $config->domain;
        $email   = $param['email'] ?? '';
        
        if (empty($email) || !preg_match('/^([a-z0-9_\.-])+@(([a-z0-9_-])+\.)+[a-z]{2,6}$/Di', $email)) 
            return (["ERROR","Formato email non valido"]);
    
        $pdo = new \PDO($config->dsn, $config->user, $config->password, $config->options);
        $stmt = $pdo->prepare("SELECT * FROM users where email = ? AND domain = ?");
        $stmt->execute([$email, $domain]);
        $row = $stmt->fetch(\PDO::FETCH_ASSOC);
        if (! $row) {
            return (["ERROR","Formato email non valido"]);
        } else {
            $sql = "UPDATE users set deleted = '0' where ID = ?";
            $stmt = $pdo->prepare($sql);
            $stmt->execute([$row["ID"]]);
        }

        return ["SUCCESS","Email inscritta con successo"];
    } // end function subscribe()
    
    public function unsubscribe($param)
    {
        $config = DatabaseConfig::getConfig();
        
        $ip    = $this->getUserIP();
        $email   = $param['email'] ?? '';
        
        if (empty($email) || !preg_match('/^([a-z0-9_\.-])+@(([a-z0-9_-])+\.)+[a-z]{2,6}$/Di', $email)) 
            return (["ERROR","Formato email non valido"]);
            
        $pdo = new \PDO($config->dsn, $config->user, $config->password, $config->options);    
        $stmt = $pdo->prepare("UPDATE users set deleted = '1' , ip_deleted= ?, delete_day = NOW() where email = ? AND domain = ?");
        $stmt->execute([$ip, $email, $config->domain]);

        return ["SUCCESS","Email disinscritta con successo"];
    }

    private function getUserIP()
    {
        // Get real visitor IP behind CloudFlare network
        if (isset($_SERVER["HTTP_CF_CONNECTING_IP"])) {
                  $_SERVER['REMOTE_ADDR'] = $_SERVER["HTTP_CF_CONNECTING_IP"];
                  $_SERVER['HTTP_CLIENT_IP'] = $_SERVER["HTTP_CF_CONNECTING_IP"];
        }
        $client  = @$_SERVER['HTTP_CLIENT_IP'];
        $forward = @$_SERVER['HTTP_X_FORWARDED_FOR'];
        $remote  = $_SERVER['REMOTE_ADDR'];
    
        if(filter_var($client, FILTER_VALIDATE_IP))
        {
            $ip = $client;
        }
        elseif(filter_var($forward, FILTER_VALIDATE_IP))
        {
            $ip = $forward;
        }
        else
        {
            $ip = $remote;
        }
    
        return $ip;
    }
    
    /**
     * Salva un messaggio inviato nel database
     */
    public function writeMessage($idMessage, $subject, $group) {
        $config = DatabaseConfig::getConfig();
        
        $pdo = new \PDO($config->dsn, $config->user, $config->password, $config->options);
        
        $sql = "INSERT INTO messages (ID, subject, IDGroup) VALUES (?, ?, ?)";
        $stmt = $pdo->prepare($sql);
        $stmt->execute([$idMessage, $subject, $group]);
        
        return $pdo->lastInsertId();
    }
    
    /**
     * Importa un utente dal CSV Tagmailer
     */
    public function importUser($data) {
        $config = DatabaseConfig::getConfig();
        
        $email = $data['email'];
        $domain = $data['domain'] ?? $config->domain;
        $inviaDem = $this->normalizeMarketingFlag($data['inviaDem'] ?? 0);
        $ip = $data['ip'] ?? $this->getUserIP();
        $dataIscrizione = $data['dataIscrizione'] ?? date('Y-m-d H:i:s');
        
        // Converte la data dal CSV nel formato MySQL
        $trattamentoPrivacyDay = $this->convertDateToMySQL($dataIscrizione);
        
        // Validazione email
        if (empty($email) || !preg_match('/^([a-z0-9_\.-])+@(([a-z0-9_-])+\.)+[a-z]{2,6}$/Di', $email)) {
            return ["ERROR", "Formato email non valido"];
        }
        
        $pdo = new \PDO($config->dsn, $config->user, $config->password, $config->options);
        
        // Verifica se l'utente esiste già
        $stmt = $pdo->prepare("SELECT * FROM users WHERE email = ? AND domain = ?");
        $stmt->execute([$email, $domain]);
        $existing_user = $stmt->fetch(\PDO::FETCH_ASSOC);
        
        if ($existing_user) {
            // Utente esiste già, aggiorna i dati se necessario
            if ($existing_user["deleted"] == 1) {
                // Riattiva l'utente
                $sql = "UPDATE users SET deleted = '0', trattamento_privacy_day = ?";
                $params = [$trattamentoPrivacyDay];
                
                if ($inviaDem == 1) {
                    $sql .= ", invio_dem = ?, invio_dem_day = ?";
                    $params[] = $inviaDem;
                    $params[] = $trattamentoPrivacyDay;
                }
                
                $sql .= " WHERE ID = ?";
                $params[] = $existing_user["ID"];
                
                $stmt = $pdo->prepare($sql);
                $stmt->execute($params);
                
                return ["SUCCESS", "Utente riattivato: " . $email];
            } else {
                // Utente già attivo, aggiorna solo invio_dem se diverso
                if ($existing_user["invio_dem"] != $inviaDem) {
                    $sql = "UPDATE users SET invio_dem_day = ?, invio_dem = ? WHERE ID = ?";
                    $stmt = $pdo->prepare($sql);
                    $stmt->execute([$trattamentoPrivacyDay, $inviaDem, $existing_user["ID"]]);
                    
                    return ["SUCCESS", "Utente aggiornato: " . $email];
                } else {
                    return ["SUCCESS", "Utente già presente: " . $email];
                }
            }
        } else {
            // Nuovo utente, inserisci solo i campi base
            if ($inviaDem == 1) {
                $sql = "INSERT INTO users (deleted, domain, email, trattamento_privacy_day, invio_dem, invio_dem_day, from_ip) VALUES (0, ?, ?, ?, ?, ?, ?)";
                $stmt = $pdo->prepare($sql);
                $stmt->execute([$domain, $email, $trattamentoPrivacyDay, $inviaDem, $trattamentoPrivacyDay, $ip]);
            } else {
                $sql = "INSERT INTO users (deleted, domain, email, trattamento_privacy_day, invio_dem, from_ip) VALUES (0, ?, ?, ?, ?, ?)";
                $stmt = $pdo->prepare($sql);
                $stmt->execute([$domain, $email, $trattamentoPrivacyDay, $inviaDem, $ip]);
            }
            
            return ["SUCCESS", "Utente importato: " . $email];
        }
    }
    
    /**
     * Converte la data dal CSV nel formato MySQL
     */
    private function convertDateToMySQL($dateString) {
        if (empty($dateString)) {
            return date('Y-m-d H:i:s');
        }
        
        // Prova diversi formati di data comuni nei CSV
        $formats = [
            'Y-m-d H:i:s',     // 2023-12-25 14:30:00
            'Y-m-d',           // 2023-12-25
            'd/m/Y H:i:s',     // 25/12/2023 14:30:00
            'd/m/Y',           // 25/12/2023
            'd-m-Y H:i:s',     // 25-12-2023 14:30:00
            'd-m-Y',           // 25-12-2023
            'Y/m/d H:i:s',     // 2023/12/25 14:30:00
            'Y/m/d',           // 2023/12/25
        ];
        
        foreach ($formats as $format) {
            $date = \DateTime::createFromFormat($format, $dateString);
            if ($date !== false) {
                return $date->format('Y-m-d H:i:s');
            }
        }
        
        // Se nessun formato funziona, prova con strtotime
        $timestamp = strtotime($dateString);
        if ($timestamp !== false) {
            return date('Y-m-d H:i:s', $timestamp);
        }
        
        // Fallback alla data corrente
        return date('Y-m-d H:i:s');
    }

    /**
     * Normalizza il flag invio_dem accettando vari formati testuali/booleani
     */
    private function normalizeMarketingFlag($value) {
        if (is_bool($value)) {
            return $value ? 1 : 0;
        }

        $normalized = strtolower(trim((string) $value));
        $trueValues = ['si', 'sì', 'true', '1', 'yes'];

        return in_array($normalized, $trueValues, true) ? 1 : 0;
    }
    
}
