<?php

declare(strict_types=1);

if (session_status() !== PHP_SESSION_ACTIVE) {
    session_set_cookie_params([
        'httponly' => true,
        'secure' => (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'),
        'samesite' => 'Lax',
    ]);
    session_start();
}

$config = require dirname(__DIR__) . '/config.php';
date_default_timezone_set((string) ($config['site']['timezone'] ?? 'Europe/Istanbul'));

function cfg(?string $path = null, mixed $default = null): mixed
{
    global $config;
    if ($path === null || $path === '') {
        return $config;
    }

    $value = $config;
    foreach (explode('.', $path) as $segment) {
        if (!is_array($value) || !array_key_exists($segment, $value)) {
            return $default;
        }
        $value = $value[$segment];
    }
    return $value;
}

function e(mixed $value): string
{
    return htmlspecialchars((string) $value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}

function money(float|int $amount): string
{
    return number_format((float) $amount, 0, ',', '.') . ' TL';
}

function site_url(string $path = ''): string
{
    $base = rtrim((string) cfg('site.base_url', ''), '/');
    if ($base !== '') {
        return $base . '/' . ltrim($path, '/');
    }
    return $path === '' ? './' : $path;
}

function csrf_token(): string
{
    if (empty($_SESSION['csrf_token'])) {
        $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
    }
    return $_SESSION['csrf_token'];
}

function verify_csrf(?string $token): bool
{
    return is_string($token)
        && isset($_SESSION['csrf_token'])
        && hash_equals($_SESSION['csrf_token'], $token);
}

function package_details(int $quantity): ?array
{
    $prices = cfg('product.prices', []);
    if (!isset($prices[$quantity])) {
        return null;
    }

    return [
        'quantity' => $quantity,
        'price' => (float) $prices[$quantity],
        'label' => $quantity . ' Adet ' . cfg('product.short_name'),
    ];
}

function turkey_provinces(): array
{
    return [
        1=>'Adana',2=>'Adıyaman',3=>'Afyonkarahisar',4=>'Ağrı',5=>'Amasya',6=>'Ankara',7=>'Antalya',8=>'Artvin',9=>'Aydın',10=>'Balıkesir',
        11=>'Bilecik',12=>'Bingöl',13=>'Bitlis',14=>'Bolu',15=>'Burdur',16=>'Bursa',17=>'Çanakkale',18=>'Çankırı',19=>'Çorum',20=>'Denizli',
        21=>'Diyarbakır',22=>'Edirne',23=>'Elazığ',24=>'Erzincan',25=>'Erzurum',26=>'Eskişehir',27=>'Gaziantep',28=>'Giresun',29=>'Gümüşhane',30=>'Hakkâri',
        31=>'Hatay',32=>'Isparta',33=>'Mersin',34=>'İstanbul',35=>'İzmir',36=>'Kars',37=>'Kastamonu',38=>'Kayseri',39=>'Kırklareli',40=>'Kırşehir',
        41=>'Kocaeli',42=>'Konya',43=>'Kütahya',44=>'Malatya',45=>'Manisa',46=>'Kahramanmaraş',47=>'Mardin',48=>'Muğla',49=>'Muş',50=>'Nevşehir',
        51=>'Niğde',52=>'Ordu',53=>'Rize',54=>'Sakarya',55=>'Samsun',56=>'Siirt',57=>'Sinop',58=>'Sivas',59=>'Tekirdağ',60=>'Tokat',
        61=>'Trabzon',62=>'Tunceli',63=>'Şanlıurfa',64=>'Uşak',65=>'Van',66=>'Yozgat',67=>'Zonguldak',68=>'Aksaray',69=>'Bayburt',70=>'Karaman',
        71=>'Kırıkkale',72=>'Batman',73=>'Şırnak',74=>'Bartın',75=>'Ardahan',76=>'Iğdır',77=>'Yalova',78=>'Karabük',79=>'Kilis',80=>'Osmaniye',81=>'Düzce',
    ];
}

function create_order_id(): string
{
    return 'MTR-' . date('ymd') . '-' . strtoupper(bin2hex(random_bytes(3)));
}

function storage_path(string $folder = ''): string
{
    return dirname(__DIR__) . '/storage/' . ltrim($folder, '/');
}

function save_order(array $order): bool
{
    if (!cfg('orders.local_storage_enabled', true)) {
        $_SESSION['orders'][$order['id']] = $order;
        return true;
    }

    $directory = storage_path('orders');
    if (!is_dir($directory) && !mkdir($directory, 0750, true) && !is_dir($directory)) {
        return false;
    }

    $json = json_encode($order, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    return $json !== false && file_put_contents($directory . '/' . $order['id'] . '.json', $json, LOCK_EX) !== false;
}

function load_order(string $id): ?array
{
    if (!preg_match('/^MTR-[A-Z0-9-]+$/', $id)) {
        return null;
    }

    if (!cfg('orders.local_storage_enabled', true)) {
        return $_SESSION['orders'][$id] ?? null;
    }

    $path = storage_path('orders/' . $id . '.json');
    if (!is_file($path)) {
        return null;
    }
    $data = json_decode((string) file_get_contents($path), true);
    return is_array($data) ? $data : null;
}

function authorized_order(string $id, string $token): ?array
{
    $order = load_order($id);
    if (!$order || empty($order['access_token_hash']) || !hash_equals($order['access_token_hash'], hash('sha256', $token))) {
        return null;
    }
    return $order;
}

function client_ip_hash(): string
{
    $ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
    return hash_hmac('sha256', $ip, (string) cfg('site.app_key'));
}

function post_value(string $key): string
{
    return trim((string) ($_POST[$key] ?? ''));
}

function validate_checkout(array $post): array
{
    $errors = [];
    $required = [
        'first_name' => 'Ad', 'last_name' => 'Soyad', 'email' => 'E-posta', 'phone' => 'Telefon',
        'province' => 'İl', 'district' => 'İlçe', 'neighborhood' => 'Mahalle', 'address' => 'Açık adres',
    ];

    foreach ($required as $field => $label) {
        $value = trim((string) ($post[$field] ?? ''));
        if ($value === '' && in_array($field, ['district', 'neighborhood'], true)) {
            $value = trim((string) ($post[$field . '_manual'] ?? ''));
        }
        if ($value === '') {
            $errors[$field] = $label . ' alanı zorunludur.';
        }
    }

    if (!filter_var($post['email'] ?? '', FILTER_VALIDATE_EMAIL)) {
        $errors['email'] = 'Geçerli bir e-posta adresi girin.';
    }
    $phoneDigits = preg_replace('/\D+/', '', (string) ($post['phone'] ?? ''));
    if (strlen($phoneDigits) < 10 || strlen($phoneDigits) > 13) {
        $errors['phone'] = 'Geçerli bir telefon numarası girin.';
    }
    if (mb_strlen((string) ($post['address'] ?? '')) < 10) {
        $errors['address'] = 'Açık adresi bina ve daire bilgileriyle yazın.';
    }
    if (empty($post['contract_accepted'])) {
        $errors['contract_accepted'] = 'Sözleşmeleri okuyup onaylamalısınız.';
    }
    if (empty($post['privacy_acknowledged'])) {
        $errors['privacy_acknowledged'] = 'KVKK aydınlatma metnini okuduğunuzu onaylamalısınız.';
    }
    if (!empty($post['website'])) {
        $errors['form'] = 'Form gönderilemedi.';
    }

    return $errors;
}

function telegram_configured(): bool
{
    if (!cfg('telegram.enabled', true)) {
        return false;
    }

    $token = trim((string) cfg('telegram.bot_token'));
    $chatId = trim((string) cfg('telegram.chat_id'));
    $validToken = preg_match('/^\d+:[A-Za-z0-9_-]{20,}$/', $token) === 1;
    $validChat = preg_match('/^-?\d+$/', $chatId) === 1 || preg_match('/^@[A-Za-z0-9_]{5,}$/', $chatId) === 1;
    return $validToken && $validChat;
}

function telegram_log(string $event, string $status, string $detail = ''): void
{
    if (!cfg('telegram.debug_log', true)) {
        return;
    }

    $entry = json_encode([
        'time' => date(DATE_ATOM),
        'event' => $event,
        'status' => $status,
        'detail' => mb_substr($detail, 0, 700),
    ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);

    if ($entry !== false) {
        @file_put_contents(storage_path('telegram.log'), $entry . PHP_EOL, FILE_APPEND | LOCK_EX);
    }
}

function telegram_response_ok(string $method, string|false $response, int $httpStatus, string $transportError = ''): bool
{
    if ($response === false) {
        telegram_log($method, 'error', $transportError !== '' ? $transportError : 'Telegram sunucusundan yanıt alınamadı.');
        return false;
    }

    $decoded = json_decode($response, true);
    $ok = $httpStatus >= 200 && $httpStatus < 300 && is_array($decoded) && ($decoded['ok'] ?? false) === true;
    if ($ok) {
        telegram_log($method, 'success', 'HTTP ' . $httpStatus);
        return true;
    }

    $description = is_array($decoded) ? (string) ($decoded['description'] ?? 'Bilinmeyen Telegram API hatası') : 'Geçersiz Telegram yanıtı';
    telegram_log($method, 'error', 'HTTP ' . $httpStatus . ' — ' . $description . ($transportError !== '' ? ' — ' . $transportError : ''));
    return false;
}

function telegram_request(string $method, array $fields): bool
{
    if (!telegram_configured()) {
        telegram_log($method, 'skipped', 'Bot token veya chat_id geçerli değil. config.php dosyasını kontrol edin.');
        return false;
    }

    $url = 'https://api.telegram.org/bot' . trim((string) cfg('telegram.bot_token')) . '/' . $method;
    if (function_exists('curl_init')) {
        $curl = curl_init($url);
        curl_setopt_array($curl, [
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => $fields,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_CONNECTTIMEOUT => 10,
            CURLOPT_TIMEOUT => 30,
            CURLOPT_SSL_VERIFYPEER => true,
            CURLOPT_HTTPHEADER => ['Accept: application/json'],
        ]);
        $response = curl_exec($curl);
        $status = (int) curl_getinfo($curl, CURLINFO_HTTP_CODE);
        $error = curl_error($curl);
        curl_close($curl);
        return telegram_response_ok($method, $response, $status, $error);
    }

    $context = stream_context_create([
        'http' => [
            'method' => 'POST',
            'header' => "Content-Type: application/x-www-form-urlencoded\r\nAccept: application/json\r\n",
            'content' => http_build_query($fields),
            'timeout' => 30,
            'ignore_errors' => true,
        ],
    ]);
    $response = @file_get_contents($url, false, $context);
    $status = 0;
    foreach ($http_response_header ?? [] as $header) {
        if (preg_match('/^HTTP\/\S+\s+(\d{3})/', $header, $matches)) {
            $status = (int) $matches[1];
            break;
        }
    }
    return telegram_response_ok($method, $response, $status, 'cURL bulunamadı; PHP stream yöntemi kullanıldı.');
}

function telegram_document_request(array $fields, string $documentPath): bool
{
    $method = 'sendDocument';
    if (!telegram_configured()) {
        telegram_log($method, 'skipped', 'Bot token veya chat_id geçerli değil. config.php dosyasını kontrol edin.');
        return false;
    }
    if (!is_file($documentPath) || !is_readable($documentPath)) {
        telegram_log($method, 'error', 'Dekont dosyası okunamıyor.');
        return false;
    }

    $url = 'https://api.telegram.org/bot' . trim((string) cfg('telegram.bot_token')) . '/' . $method;
    $mime = (new finfo(FILEINFO_MIME_TYPE))->file($documentPath) ?: 'application/octet-stream';

    if (function_exists('curl_init') && class_exists('CURLFile')) {
        $fields['document'] = new CURLFile($documentPath, $mime, basename($documentPath));
        $curl = curl_init($url);
        curl_setopt_array($curl, [
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => $fields,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_CONNECTTIMEOUT => 10,
            CURLOPT_TIMEOUT => 45,
            CURLOPT_SSL_VERIFYPEER => true,
            CURLOPT_HTTPHEADER => ['Accept: application/json'],
        ]);
        $response = curl_exec($curl);
        $status = (int) curl_getinfo($curl, CURLINFO_HTTP_CODE);
        $error = curl_error($curl);
        curl_close($curl);
        return telegram_response_ok($method, $response, $status, $error);
    }

    $boundary = '----MoenTR' . bin2hex(random_bytes(12));
    $body = '';
    foreach ($fields as $name => $value) {
        $body .= '--' . $boundary . "\r\n";
        $body .= 'Content-Disposition: form-data; name="' . $name . '"' . "\r\n\r\n";
        $body .= (string) $value . "\r\n";
    }
    $body .= '--' . $boundary . "\r\n";
    $body .= 'Content-Disposition: form-data; name="document"; filename="' . basename($documentPath) . '"' . "\r\n";
    $body .= 'Content-Type: ' . $mime . "\r\n\r\n";
    $body .= (string) file_get_contents($documentPath) . "\r\n";
    $body .= '--' . $boundary . "--\r\n";

    $context = stream_context_create([
        'http' => [
            'method' => 'POST',
            'header' => "Content-Type: multipart/form-data; boundary={$boundary}\r\nContent-Length: " . strlen($body) . "\r\nAccept: application/json\r\n",
            'content' => $body,
            'timeout' => 45,
            'ignore_errors' => true,
        ],
    ]);
    $response = @file_get_contents($url, false, $context);
    $status = 0;
    foreach ($http_response_header ?? [] as $header) {
        if (preg_match('/^HTTP\/\S+\s+(\d{3})/', $header, $matches)) {
            $status = (int) $matches[1];
            break;
        }
    }
    return telegram_response_ok($method, $response, $status, 'cURL bulunamadı; multipart stream yöntemi kullanıldı.');
}

function order_message(array $order, string $title = '🛍 Yeni Sipariş'): string
{
    return implode("\n", [
        '<b>' . e($title) . '</b>',
        '<b>Sipariş:</b> ' . e($order['id']),
        '<b>Ürün:</b> ' . e($order['product']['name']),
        '<b>Adet:</b> ' . e($order['product']['quantity']),
        '<b>Tutar:</b> ' . e(money($order['totals']['grand_total'])),
        '<b>Müşteri:</b> ' . e($order['customer']['first_name'] . ' ' . $order['customer']['last_name']),
        '<b>Telefon:</b> ' . e($order['customer']['phone']),
        '<b>E-posta:</b> ' . e($order['customer']['email']),
        '<b>Adres:</b> ' . e($order['address']['neighborhood'] . ', ' . $order['address']['district'] . ' / ' . $order['address']['province']),
        e(mb_substr($order['address']['line'], 0, 220)),
        '<b>Not:</b> ' . e(mb_substr($order['customer']['note'] ?: '-', 0, 120)),
        '<b>Durum:</b> ' . e($order['status']),
    ]);
}

function notify_new_order(array $order): bool
{
    if (!cfg('telegram.notify_new_order', true)) {
        return true;
    }
    return telegram_request('sendMessage', [
        'chat_id' => (string) cfg('telegram.chat_id'),
        'text' => order_message($order),
        'parse_mode' => 'HTML',
        'disable_web_page_preview' => 'true',
    ]);
}

function notify_receipt(array $order, string $receiptPath): bool
{
    if (!cfg('telegram.notify_receipt', true)) {
        return true;
    }

    $messageSent = telegram_request('sendMessage', [
        'chat_id' => (string) cfg('telegram.chat_id'),
        'text' => order_message($order, '🧾 Yeni Dekont Yüklendi'),
        'parse_mode' => 'HTML',
        'disable_web_page_preview' => 'true',
    ]);
    $documentSent = telegram_document_request([
        'chat_id' => (string) cfg('telegram.chat_id'),
        'caption' => '<b>Dekont:</b> ' . e($order['id']) . "\n<b>Müşteri:</b> " . e($order['customer']['first_name'] . ' ' . $order['customer']['last_name']) . "\n<b>Tutar:</b> " . e(money($order['totals']['grand_total'])),
        'parse_mode' => 'HTML',
    ], $receiptPath);
    return $messageSent && $documentSent;
}

function whatsapp_url(array $order): string
{
    $number = preg_replace('/\D+/', '', (string) cfg('site.whatsapp_number'));
    $message = sprintf(
        "Merhaba, %s numaralı %s tutarındaki siparişimin ödemesini yaptım. Dekontumu şimdi gönderiyorum.",
        $order['id'],
        money($order['totals']['grand_total'])
    );
    return 'https://wa.me/' . $number . '?text=' . rawurlencode($message);
}

function legal_config_missing(): bool
{
    $fields = [cfg('seller.address'), cfg('seller.tax_number'), cfg('bank.iban')];
    foreach ($fields as $field) {
        $value = (string) $field;
        if ($value === '' || str_contains($value, 'BURAYA') || str_contains($value, 'VERGİ') || str_starts_with($value, 'TR00')) {
            return true;
        }
    }
    return false;
}
