<?php

declare(strict_types=1);

use App\Core\Auth;
use App\Core\Csrf;
use App\Core\Database;
use App\Core\Env;
use App\Core\Permission;
use App\Core\Session;
use App\Services\DocumentTemplateService;

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

function url(string $path = ''): string
{
    $base = rtrim((string)Env::get('APP_BASE_PATH', ''), '/');
    $path = '/' . ltrim($path, '/');
    return $base . ($path === '/' ? '/' : $path);
}

function asset(string $path): string
{
    return url('/assets/' . ltrim($path, '/'));
}

function redirect(string $path): void
{
    header('Location: ' . url($path));
    exit;
}

function csrf_field(): string
{
    return '<input type="hidden" name="_token" value="' . e(Csrf::token()) . '">';
}

function old(string $key, mixed $default = ''): mixed
{
    $old = Session::pull('_old', []);
    Session::put('_old', $old);
    return $old[$key] ?? $default;
}

function flash(string $key, mixed $value = null): mixed
{
    if (func_num_args() === 2) {
        Session::flash($key, $value);
        return null;
    }
    return Session::getFlash($key);
}

function current_user(): ?array
{
    return Auth::user();
}

function can(string $permissionCode): bool
{
    return Permission::has($permissionCode);
}

function money_ars(mixed $amount): string
{
    return '$ ' . number_format((float)$amount, 2, ',', '.');
}

function money_usd(mixed $amount): string
{
    return 'US$ ' . number_format((float)$amount, 2, ',', '.');
}

function decimal_fmt(mixed $amount, int $decimals = 2): string
{
    return number_format((float)$amount, $decimals, ',', '.');
}

function document_template(): array
{
    static $cache = [];
    $user = current_user();
    $service = new DocumentTemplateService();
    if (!$user) {
        return DocumentTemplateService::defaults();
    }

    $companyId = (int)Auth::companyId();
    if ($companyId <= 0) {
        return DocumentTemplateService::defaults();
    }

    if (!isset($cache[$companyId])) {
        try {
            $cache[$companyId] = $service->settings(Database::pdo(), $companyId);
        } catch (Throwable) {
            $cache[$companyId] = DocumentTemplateService::defaults();
        }
    }

    return $cache[$companyId];
}

function document_company_profile(?int $branchId = null): array
{
    static $cache = [];
    $companyId = (int)Auth::companyId();
    $key = $companyId . ':' . (int)($branchId ?? 0);

    if (!isset($cache[$key])) {
        try {
            $cache[$key] = (new DocumentTemplateService())->companyProfile(Database::pdo(), $companyId, $branchId);
        } catch (Throwable) {
            $cache[$key] = [
                'business_name' => 'Empresa',
                'trade_name' => 'CRM Agro',
                'cuit' => '',
                'iva_condition' => '',
                'address' => '',
                'city' => '',
                'province' => '',
                'phone' => '',
                'email' => '',
                'branch_name' => '',
                'logo_path' => '',
            ];
        }
    }

    return $cache[$key];
}

function document_template_attrs(?array $template = null): string
{
    $tpl = $template ?? document_template();
    $class = document_template_class($tpl);
    $style = document_template_style($tpl);
    return 'class="document-page printable-document comprobante ' . e($class) . '" style="' . e($style) . '"';
}

function document_initials(string $name): string
{
    $parts = preg_split('/\s+/', trim($name)) ?: [];
    $letters = '';
    foreach ($parts as $part) {
        if ($part === '') {
            continue;
        }

        if (function_exists('mb_substr')) {
            $letters .= mb_substr($part, 0, 1, 'UTF-8');
        } else {
            $letters .= substr($part, 0, 1);
        }

        $length = function_exists('mb_strlen') ? mb_strlen($letters, 'UTF-8') : strlen($letters);
        if ($length >= 2) {
            break;
        }
    }

    $letters = $letters !== '' ? $letters : 'AG';
    return function_exists('mb_strtoupper') ? mb_strtoupper($letters, 'UTF-8') : strtoupper($letters);
}

function document_template_settings(): array
{
    return document_template();
}

function document_template_style(?array $template = null): string
{
    try {
        return DocumentTemplateService::styleVars($template ?? document_template());
    } catch (Throwable) {
        return '';
    }
}

function document_template_class(?array $template = null): string
{
    $tpl = $template ?? document_template();
    $density = preg_replace('/[^a-z]/', '', strtolower((string)($tpl['density'] ?? 'compact'))) ?: 'compact';
    $page = strtolower((string)($tpl['page_size'] ?? 'A4')) === 'letter' ? 'doc-paper-letter' : 'doc-paper-a4';
    $header = preg_replace('/[^a-z]/', '', strtolower((string)($tpl['header_style'] ?? 'corporate'))) ?: 'corporate';
    $layout = in_array((string)($tpl['layout_mode'] ?? 'standard'), ['standard', 'custom'], true) ? (string)$tpl['layout_mode'] : 'standard';
    $priceLayout = in_array((string)($tpl['price_footer_layout'] ?? 'notes_left_totals_right'), ['notes_left_totals_right', 'totals_left_notes_right', 'stacked'], true)
        ? (string)$tpl['price_footer_layout']
        : 'notes_left_totals_right';
    $width = in_array((string)($tpl['document_width'] ?? 'auto'), ['auto', 'narrow', 'wide'], true) ? (string)$tpl['document_width'] : 'auto';

    return trim(
        'tpl-density-' . $density . ' ' .
        $page . ' ' .
        'tpl-header-' . $header . ' ' .
        'tpl-layout-' . $layout . ' ' .
        'tpl-prices-' . str_replace('_', '-', $priceLayout) . ' ' .
        'tpl-width-' . $width
    );
}

function company_profile(?int $branchId = null): array
{
    return document_company_profile($branchId);
}

function document_company(): array
{
    return document_company_profile(Auth::branchId());
}

function document_logo_url(?string $path): string
{
    $path = trim((string)$path);
    if ($path === '') {
        return '';
    }

    // No se aceptan logos remotos para evitar dependencias externas y fugas de datos.
    if (preg_match('#^https?://#i', $path)) {
        return '';
    }

    // v0.13.5: logos guardados en storage y servidos por controlador autenticado.
    // Esto evita depender de permisos de escritura sobre /public/uploads.
    if (str_starts_with($path, 'storage://company-logos/')) {
        $file = basename(substr($path, strlen('storage://company-logos/')));
        if ($file === '' || preg_match('/^[a-zA-Z0-9._-]+$/', $file) !== 1) {
            return '';
        }
        return url('/config/company/logo-file?file=' . rawurlencode($file));
    }

    $path = '/' . ltrim($path, '/');
    return url($path);
}

function document_logo_block(array $company, ?array $template = null): string
{
    $tpl = $template ?? document_template();
    if (empty($tpl['show_logo'])) {
        return '';
    }

    $companyName = trim((string)($company['trade_name'] ?? $company['business_name'] ?? 'CRM Agro')) ?: 'CRM Agro';
    $logoPath = trim((string)($company['logo_path'] ?? ''));
    $logoUrl = document_logo_url($logoPath);

    if ($logoUrl !== '') {
        return '<div class="doc-logo doc-logo-image"><img src="' . e($logoUrl) . '" alt="' . e($companyName) . '"></div>';
    }

    return '<div class="doc-logo doc-logo-text">' . e(document_initials($companyName)) . '</div>';
}
