<?php
function inbox_setting(PDO $pdo, string $key, string $default = ''): string
{
    try {
        $stmt = $pdo->prepare("SELECT setting_value FROM settings WHERE setting_key = :k LIMIT 1");
        $stmt->execute([':k' => $key]);
        $val = $stmt->fetchColumn();
        return $val !== false ? (string)$val : $default;
    } catch (Throwable $e) {
        return $default;
    }
}
function inboxSettings(PDO $pdo, string $key, string $default = ''): string { return inbox_setting($pdo, $key, $default); }

function inbox_decode_mime_header_text($text): string
{
    $text = (string)$text;
    if ($text === '') return '';
    if (function_exists('iconv_mime_decode')) {
        $decoded = @iconv_mime_decode($text, ICONV_MIME_DECODE_CONTINUE_ON_ERROR, 'UTF-8');
        if (is_string($decoded) && $decoded !== '') return $decoded;
    }
    if (function_exists('mb_decode_mimeheader')) {
        $decoded = @mb_decode_mimeheader($text);
        if (is_string($decoded) && $decoded !== '') return $decoded;
    }
    return $text;
}
function inbox_clean(string $text): string
{
    $text = str_replace(["\r\n", "\r"], "\n", $text);
    $text = html_entity_decode($text, ENT_QUOTES | ENT_HTML5, 'UTF-8');
    $text = preg_replace('/[ \t]+/', ' ', $text);
    $text = preg_replace("/\n{3,}/", "\n\n", $text);
    return trim($text);
}
function inbox_preview_text($text, $limit = 1200): string
{
    $text = inbox_clean((string)$text);
    if (mb_strlen($text, 'UTF-8') <= $limit) return $text;
    return rtrim(mb_substr($text, 0, $limit, 'UTF-8')) . '...';
}
function inbox_convert_to_utf8(string $body, string $charset = ''): string
{
    $charset = trim($charset, "\"' ");
    if ($charset === '' || strtoupper($charset) === 'UTF-8') return $body;
    if (function_exists('mb_convert_encoding')) {
        $tmp = @mb_convert_encoding($body, 'UTF-8', $charset);
        if (is_string($tmp) && $tmp !== '') return $tmp;
    }
    if (function_exists('iconv')) {
        $tmp = @iconv($charset, 'UTF-8//IGNORE', $body);
        if (is_string($tmp) && $tmp !== '') return $tmp;
    }
    return $body;
}
function inbox_extract_readable_text($raw): string
{
    $raw = trim((string)$raw);
    if ($raw === '') return '';
    $raw = str_replace(["\r\n", "\r"], "\n", $raw);
    $bestPlain = '';
    $bestHtml = '';

    if (preg_match('/boundary="?([^"\n;]+)"?/i', $raw, $m)) {
        $boundary = $m[1];
        $parts = explode('--' . $boundary, $raw);
        foreach ($parts as $part) {
            $headersAndBody = preg_split("/\n\s*\n/", trim($part), 2);
            $headers = $headersAndBody[0] ?? '';
            $body = $headersAndBody[1] ?? '';
            if ($body === '') continue;
            $encoding = '';
            $charset = '';
            if (preg_match('/Content-Transfer-Encoding:\s*([^\s]+)/i', $headers, $em)) $encoding = strtolower(trim($em[1]));
            if (preg_match('/charset="?([^"\n;]+)"?/i', $headers, $cm)) $charset = $cm[1];
            if ($encoding === 'base64') {
                $tmp = base64_decode(preg_replace('/\s+/', '', $body), true);
                if ($tmp !== false) $body = $tmp;
            } elseif ($encoding === 'quoted-printable') {
                $body = quoted_printable_decode($body);
            }
            $body = inbox_convert_to_utf8($body, $charset);
            if (stripos($headers, 'Content-Type: text/plain') !== false) {
                $bestPlain = inbox_clean($body);
                if ($bestPlain !== '') break;
            }
            if ($bestHtml === '' && stripos($headers, 'Content-Type: text/html') !== false) {
                $html = preg_replace('/<(br|\/p|\/div|\/li|\/tr|\/h[1-6])\b[^>]*>/i', "\n", $body);
                $html = preg_replace('/<li\b[^>]*>/i', "• ", $html);
                $html = strip_tags($html);
                $bestHtml = inbox_clean($html);
            }
        }
    }
    if ($bestPlain !== '') return $bestPlain;
    if ($bestHtml !== '') return $bestHtml;
    if (stripos($raw, 'base64') !== false) {
        $chunks = preg_split("/\n\s*\n/", $raw, 2);
        $body = $chunks[1] ?? '';
        $decoded = base64_decode(preg_replace('/\s+/', '', $body), true);
        if ($decoded !== false) return inbox_clean($decoded);
    }
    return inbox_clean($raw);
}
function inbox_extract_phone($text): string
{
    if (preg_match('/(\+?\d[\d\s\-]{7,}\d)/', (string)$text, $m)) return trim($m[1]);
    return '';
}
function inbox_extract_amount($text): string
{
    if (preg_match('/(\d+(?:[.,]\d{1,2})?)\s?(?:€|eur|euro)/i', (string)$text, $m)) return str_replace(',', '.', trim($m[1]));
    return '';
}
function inbox_extract_deposit($text): string
{
    if (preg_match('/(?:deposit|advance|προκαταβολ[ήης])[^0-9]{0,20}(\d+(?:[.,]\d{1,2})?)/iu', (string)$text, $m)) return str_replace(',', '.', trim($m[1]));
    return '';
}
function inbox_extract_project_type($text): string
{
    $t = mb_strtolower((string)$text, 'UTF-8');
    if (strpos($t, 'ανακατασκευ') !== false || strpos($t, 'reconstruction') !== false) return 'Reconstruction';
    if (strpos($t, 'πισίν') !== false || strpos($t, 'pool') !== false || strpos($t, 'new pool') !== false) return 'Pool';
    return '';
}
function inbox_guess_type($subject, $body): string
{
    $txt = mb_strtolower((string)$subject . ' ' . (string)$body, 'UTF-8');
    if (strpos($txt, 'expense') !== false || strpos($txt, 'τιμολ') !== false || strpos($txt, 'δαπαν') !== false) return 'expense';
    if (strpos($txt, 'project') !== false || strpos($txt, 'pool') !== false || strpos($txt, 'πισίν') !== false) return 'project';
    if (strpos($txt, 'customer') !== false || strpos($txt, 'πελάτ') !== false) return 'customer';
    return 'unknown';
}
function inbox_extract_lines($subject, $body): array
{
    $subject=(string)$subject; $body=(string)$body;
    return [
        'signature_name' => '',
        'signature_company' => '',
        'signature_email' => '',
        'signature_phone' => inbox_extract_phone($body),
        'amount' => inbox_extract_amount($body),
        'deposit' => inbox_extract_deposit($body),
        'project_type' => inbox_extract_project_type($subject . "\n" . $body),
        'suggested_type' => inbox_guess_type($subject, $body),
    ];
}
function inbox_find_customer_from_signature(PDO $pdo, array $extract)
{
    if (!empty($extract['signature_phone'])) {
        try {
            $stmt = $pdo->prepare("SELECT * FROM customers WHERE phone = :phone LIMIT 1");
            $stmt->execute([':phone' => $extract['signature_phone']]);
            $row = $stmt->fetch();
            if ($row) return $row;
        } catch (Throwable $e) {}
    }
    return null;
}
function inbox_table_columns(PDO $pdo, string $table): array
{
    static $cache = [];
    if (isset($cache[$table])) return $cache[$table];
    $cols = [];
    try {
        foreach ($pdo->query("SHOW COLUMNS FROM `" . str_replace('`','',$table) . "`")->fetchAll() as $row) {
            $cols[] = (string)$row['Field'];
        }
    } catch (Throwable $e) {}
    $cache[$table] = $cols;
    return $cols;
}
function inbox_has_col(PDO $pdo, string $table, string $col): bool
{
    return in_array($col, inbox_table_columns($pdo, $table), true);
}
function inbox_mailbox_string(PDO $pdo): string
{
    $host = inbox_setting($pdo, 'imap_host', '');
    $port = inbox_setting($pdo, 'imap_port', '993');
    $enc = inbox_setting($pdo, 'imap_encryption', 'ssl');
    $mbx = inbox_setting($pdo, 'imap_mailbox', 'INBOX');
    if ($host === '') return '';
    $flags = '/imap';
    if ($enc !== '') $flags .= '/' . $enc;
    return '{' . $host . ':' . $port . $flags . '}' . $mbx;
}
function inbox_decode_part_from_imap($imap, int $msgno, object $part, string $partNumber): array
{
    $data = $partNumber === '' ? imap_body($imap, $msgno, FT_PEEK) : imap_fetchbody($imap, $msgno, $partNumber, FT_PEEK);
    $charset = '';
    if (!empty($part->parameters)) {
        foreach ($part->parameters as $p) {
            if (strtolower($p->attribute ?? '') === 'charset') {
                $charset = (string)$p->value;
            }
        }
    }
    $encoding = (int)($part->encoding ?? 0);
    if ($encoding === 3) { // base64
        $tmp = base64_decode($data, true);
        if ($tmp !== false) $data = $tmp;
    } elseif ($encoding === 4) { // quoted printable
        $data = quoted_printable_decode($data);
    }
    $data = inbox_convert_to_utf8((string)$data, $charset);
    return ['body' => $data, 'subtype' => strtolower((string)($part->subtype ?? '')), 'type' => (int)($part->type ?? -1)];
}
function inbox_collect_bodies_and_attachments($imap, int $msgno, object $structure, string $prefix = ''): array
{
    $plain = '';
    $html = '';
    $attachments = [];

    if (!empty($structure->parts) && is_array($structure->parts)) {
        foreach ($structure->parts as $index => $part) {
            $partNumber = $prefix === '' ? (string)($index + 1) : $prefix . '.' . ($index + 1);
            if (!empty($part->parts)) {
                $nested = inbox_collect_bodies_and_attachments($imap, $msgno, $part, $partNumber);
                if ($plain === '' && $nested['plain'] !== '') $plain = $nested['plain'];
                if ($html === '' && $nested['html'] !== '') $html = $nested['html'];
                $attachments = array_merge($attachments, $nested['attachments']);
                continue;
            }

            $decoded = inbox_decode_part_from_imap($imap, $msgno, $part, $partNumber);
            $isAttachment = false;
            $filename = '';

            if (!empty($part->ifdisposition) && in_array(strtolower((string)$part->disposition), ['attachment','inline'], true)) {
                $isAttachment = true;
            }
            foreach (['dparameters','parameters'] as $prop) {
                if (!empty($part->$prop)) {
                    foreach ($part->$prop as $p) {
                        $attr = strtolower((string)($p->attribute ?? ''));
                        if (in_array($attr, ['filename','name'], true)) {
                            $filename = inbox_decode_mime_header_text((string)$p->value);
                            $isAttachment = true;
                        }
                    }
                }
            }

            if ($isAttachment) {
                $attachments[] = [
                    'filename' => $filename !== '' ? $filename : ('attachment_' . $partNumber),
                    'content' => $decoded['body'],
                    'mime' => ($decoded['type'] === 0 ? 'text/' : 'application/') . ($decoded['subtype'] !== '' ? $decoded['subtype'] : 'octet-stream'),
                ];
                continue;
            }

            if ((int)($part->type ?? -1) === 0) {
                if ($decoded['subtype'] === 'plain' && $plain === '') $plain = inbox_clean($decoded['body']);
                if ($decoded['subtype'] === 'html' && $html === '') {
                    $txt = preg_replace('/<(br|\/p|\/div|\/li|\/tr|\/h[1-6])\b[^>]*>/i', "\n", $decoded['body']);
                    $txt = preg_replace('/<li\b[^>]*>/i', "• ", $txt);
                    $txt = strip_tags($txt);
                    $html = inbox_clean($txt);
                }
            }
        }
    } else {
        $decoded = inbox_decode_part_from_imap($imap, $msgno, $structure, '');
        if ((int)($structure->type ?? -1) === 0) {
            if ($decoded['subtype'] === 'plain') $plain = inbox_clean($decoded['body']);
            if ($decoded['subtype'] === 'html') $html = inbox_clean(strip_tags($decoded['body']));
        }
    }

    return ['plain' => $plain, 'html' => $html, 'attachments' => $attachments];
}
