<?php

namespace App\Services;

use App\Config\Database;
use PDO;

class OrderProcessor
{
    public function process($orderId, $type, $csvPath)
    {
        $conn = Database::getInstance()->getConnection();

        if (!file_exists($csvPath)) {
            throw new \Exception("Arquivo CSV não encontrado.");
        }

        $handle = fopen($csvPath, "r");
        if ($handle === FALSE) {
            throw new \Exception("Erro ao abrir arquivo CSV.");
        }

        $domains = [];
        while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
            $raw = trim($data[0]);
            if (empty($raw))
                continue;

            $domain = $this->cleanDomain($raw);

            if ($domain) {
                $domains[] = $domain;
            }
        }
        fclose($handle);

        $domains = array_unique($domains); // Remove duplicates in batch

        $conn->beginTransaction();

        try {
            $stmtCheck = $conn->prepare("SELECT id FROM domains WHERE name = :name");
            $stmtInsertDomain = $conn->prepare("INSERT INTO domains (name, status, last_order_id) VALUES (:name, :status, :order_id)");
            $stmtUpdateDomain = $conn->prepare("UPDATE domains SET status = :status, last_order_id = :order_id WHERE id = :id");
            $stmtInsertItem = $conn->prepare("INSERT INTO order_items (order_id, domain_id, action) VALUES (:order_id, :domain_id, :action)");

            $status = ($type === 'block') ? 'blocked' : 'unblocked';

            foreach ($domains as $domainName) {
                // Check if exists
                $stmtCheck->execute(['name' => $domainName]);
                $existing = $stmtCheck->fetch();

                $domainId = null;

                if ($existing) {
                    $domainId = $existing['id'];
                    $stmtUpdateDomain->execute([
                        'status' => $status,
                        'order_id' => $orderId,
                        'id' => $domainId
                    ]);
                } else {
                    $stmtInsertDomain->execute([
                        'name' => $domainName,
                        'status' => $status,
                        'order_id' => $orderId
                    ]);
                    $domainId = $conn->lastInsertId();
                }

                // Insert Item History
                $stmtInsertItem->execute([
                    'order_id' => $orderId,
                    'domain_id' => $domainId,
                    'action' => $type
                ]);
            }

            $conn->commit();
            return count($domains);

        } catch (\Exception $e) {
            $conn->rollBack();
            throw $e;
        }
    }

    private function cleanDomain($input)
    {
        // 1. Remove whitespace and common trailing punctuation
        $input = trim($input);
        $input = rtrim($input, ';,."\'');

        // 2. Transliterate accents (e.g., domínio -> dominio)
        // Using iconv to transliterate to ASCII
        if (function_exists('iconv')) {
            $input = iconv('UTF-8', 'ASCII//TRANSLIT', $input);
        }

        // 3. Handle Protocols and URLs
        // If it doesn't have a protocol but looks like a URL path (e.g. domain.com/page), parse_url might fail or treat as path.
        // We prepend http:// if missing to help parse_url, unless it's a mailto
        if (stripos($input, 'mailto:') === 0) {
            $input = str_ireplace('mailto:', '', $input);
        }

        if (strpos($input, '://') === false) {
            $input = 'http://' . $input;
        }

        $parsed = parse_url($input);
        if (!$parsed || !isset($parsed['host'])) {
            return null;
        }

        $domain = $parsed['host'];

        // 4. Remove 'www.' prefix (requested "www é um protocolo")
        if (strpos($domain, 'www.') === 0) {
            $domain = substr($domain, 4);
        }

        // 5. Lowercase
        $domain = strtolower($domain);

        // 6. Final Validation
        // Must contain at least one dot (unless localhost, but for blocking usually FQDN)
        // Must allow hyphens, dots, numbers, letters.
        if (!preg_match('/^([a-z0-9]([a-z0-9-]*[a-z0-9])?\.)+[a-z0-9]([a-z0-9-]*[a-z0-9])?$/', $domain)) {
            return null;
        }

        return $domain;
    }
}
