<?php
declare(strict_types=1);

/**
 * Global helper functions — loaded by Autoloader.
 */

if (!function_exists('env')) {
    function env(string $key, $default = null)
    {
        $value = $_ENV[$key] ?? getenv($key);
        if ($value === false || $value === null) {
            return $default;
        }
        $lower = strtolower((string) $value);
        if ($lower === 'true') return true;
        if ($lower === 'false') return false;
        if ($lower === 'null') return null;
        if ($lower === '') return $default;
        return $value;
    }
}

if (!function_exists('app')) {
    function app(): \App\Core\App
    {
        return \App\Core\App::getInstance();
    }
}

if (!function_exists('db')) {
    function db(): \App\Core\Database
    {
        return \App\Core\App::getInstance()->db();
    }
}

if (!function_exists('config')) {
    function config(?string $key = null, $default = null)
    {
        $app = \App\Core\App::getInstance();
        if ($key === null) {
            return $app->config();
        }
        return $app->config($key, $default);
    }
}

if (!function_exists('session')) {
    function session(?string $key = null, $default = null)
    {
        $sess = \App\Core\App::getInstance()->session();
        if ($key === null) {
            return $sess;
        }
        return $sess->get($key, $default);
    }
}

if (!function_exists('redirect')) {
    function redirect(string $url): \App\Core\Response
    {
        return (new \App\Core\Response())->redirect($url);
    }
}

if (!function_exists('url')) {
    function url(string $path = ''): string
    {
        $path = ltrim($path, '/');
        $basePath = rtrim(parse_url(config('app.url', ''), PHP_URL_PATH) ?: '', '/');
        if ($path === '') {
            return $basePath ?: '/';
        }
        return $basePath . '/' . $path;
    }
}

if (!function_exists('route')) {
    function route(string $name, array $params = []): string
    {
        return \App\Core\Router::url($name, $params);
    }
}

if (!function_exists('old')) {
    function old(string $key, $default = ''): string
    {
        $oldInput = \App\Core\App::getInstance()->session()->get('_old_input', []);
        $value = $oldInput[$key] ?? $default;
        return (string) $value;
    }
}

if (!function_exists('csrf_field')) {
    function csrf_field(): string
    {
        return \App\Core\CSRF::field();
    }
}

if (!function_exists('csrf_token')) {
    function csrf_token(): string
    {
        return \App\Core\CSRF::token();
    }
}

if (!function_exists('e')) {
    function e(?string $value): string
    {
        return htmlspecialchars($value ?? '', ENT_QUOTES, 'UTF-8');
    }
}

if (!function_exists('__')) {
    function __(string $key, ?string $default = null): string
    {
        return $default ?? $key;
    }
}

if (!function_exists('now')) {
    function now(): string
    {
        return date('Y-m-d H:i:s');
    }
}

if (!function_exists('today')) {
    function today(): string
    {
        return date('Y-m-d');
    }
}

if (!function_exists('money')) {
    function money($amount, ?string $currency = null): string
    {
        $amount = is_numeric($amount) ? (float) $amount : 0.0;
        $formatted = number_format($amount, 2, '.', ',');
        $symbol = $currency ?? config('app.currency_symbol', 'ج.م');
        return $formatted . ' ' . $symbol;
    }
}

if (!function_exists('percentage')) {
    function percentage($value): string
    {
        return number_format((float) $value, 2) . '%';
    }
}

if (!function_exists('age_from_dob')) {
    function age_from_dob(string $dob): array
    {
        try {
            $birth = new \DateTime($dob);
            $now = new \DateTime();
            $diff = $now->diff($birth);
            return [
                'years'  => $diff->y,
                'months' => $diff->m,
                'days'   => $diff->d,
                'total_months' => ($diff->y * 12) + $diff->m,
            ];
        } catch (\Exception $e) {
            return ['years' => 0, 'months' => 0, 'days' => 0, 'total_months' => 0];
        }
    }
}

if (!function_exists('arabic_date')) {
    function arabic_date(string $date): string
    {
        $months = [
            1 => 'يناير', 2 => 'فبراير', 3 => 'مارس', 4 => 'أبريل',
            5 => 'مايو', 6 => 'يونيو', 7 => 'يوليو', 8 => 'أغسطس',
            9 => 'سبتمبر', 10 => 'أكتوبر', 11 => 'نوفمبر', 12 => 'ديسمبر',
        ];
        $days = [
            'Saturday' => 'السبت', 'Sunday' => 'الأحد', 'Monday' => 'الاثنين',
            'Tuesday' => 'الثلاثاء', 'Wednesday' => 'الأربعاء',
            'Thursday' => 'الخميس', 'Friday' => 'الجمعة',
        ];

        try {
            $dt = new \DateTime($date);
            $dayName = $days[$dt->format('l')] ?? '';
            $day = $dt->format('j');
            $month = $months[(int) $dt->format('n')] ?? '';
            $year = $dt->format('Y');
            return "{$dayName} {$day} {$month} {$year}";
        } catch (\Exception $e) {
            return $date;
        }
    }
}

if (!function_exists('is_arabic')) {
    function is_arabic(string $text): bool
    {
        return (bool) preg_match('/[\x{0600}-\x{06FF}]/u', $text);
    }
}

if (!function_exists('generate_uuid')) {
    function generate_uuid(): string
    {
        $data = random_bytes(16);
        $data[6] = chr(ord($data[6]) & 0x0f | 0x40);
        $data[8] = chr(ord($data[8]) & 0x3f | 0x80);
        return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
    }
}

if (!function_exists('mask_national_id')) {
    function mask_national_id(string $nid): string
    {
        if (strlen($nid) !== 14) {
            return $nid;
        }
        return substr($nid, 0, 3) . str_repeat('*', 9) . substr($nid, 12);
    }
}

if (!function_exists('financial_year')) {
    function financial_year(?string $date = null): string
    {
        $dt = $date ? new \DateTime($date) : new \DateTime();
        $month = (int) $dt->format('n');
        $year = (int) $dt->format('Y');
        $startMonth = (int) config('app.financial_year_start_month', 7);

        if ($month >= $startMonth) {
            return $year . '/' . ($year + 1);
        }
        return ($year - 1) . '/' . $year;
    }
}

if (!function_exists('number_to_arabic_words')) {
    function number_to_arabic_words($number): string
    {
        $number = (float) $number;
        $whole = (int) floor($number);
        $fraction = (int) round(($number - $whole) * 100);

        if ($whole === 0 && $fraction === 0) {
            return 'صفر جنيه';
        }

        $result = '';
        if ($whole > 0) {
            $result = _arabic_number_convert($whole) . ' جنيه';
        }

        if ($fraction > 0) {
            if ($result !== '') {
                $result .= ' و';
            }
            $result .= _arabic_number_convert($fraction) . ' قرش';
        }

        return $result;
    }
}

if (!function_exists('_arabic_number_convert')) {
    function _arabic_number_convert(int $number): string
    {
        if ($number === 0) {
            return 'صفر';
        }

        $ones = ['', 'واحد', 'اثنان', 'ثلاثة', 'أربعة', 'خمسة', 'ستة', 'سبعة', 'ثمانية', 'تسعة',
                 'عشرة', 'أحد عشر', 'اثنا عشر', 'ثلاثة عشر', 'أربعة عشر', 'خمسة عشر',
                 'ستة عشر', 'سبعة عشر', 'ثمانية عشر', 'تسعة عشر'];
        $tens = ['', '', 'عشرون', 'ثلاثون', 'أربعون', 'خمسون', 'ستون', 'سبعون', 'ثمانون', 'تسعون'];
        $hundreds = ['', 'مائة', 'مائتان', 'ثلاثمائة', 'أربعمائة', 'خمسمائة', 'ستمائة', 'سبعمائة', 'ثمانمائة', 'تسعمائة'];

        $parts = [];

        if ($number >= 1000000) {
            $millions = (int) floor($number / 1000000);
            if ($millions === 1) {
                $parts[] = 'مليون';
            } elseif ($millions === 2) {
                $parts[] = 'مليونان';
            } elseif ($millions <= 10) {
                $parts[] = $ones[$millions] . ' ملايين';
            } else {
                $parts[] = _arabic_number_convert($millions) . ' مليون';
            }
            $number %= 1000000;
        }

        if ($number >= 1000) {
            $th = (int) floor($number / 1000);
            if ($th === 1) {
                $parts[] = 'ألف';
            } elseif ($th === 2) {
                $parts[] = 'ألفان';
            } elseif ($th <= 10) {
                $parts[] = $ones[$th] . ' آلاف';
            } else {
                $parts[] = _arabic_number_convert($th) . ' ألف';
            }
            $number %= 1000;
        }

        if ($number >= 100) {
            $h = (int) floor($number / 100);
            $parts[] = $hundreds[$h];
            $number %= 100;
        }

        if ($number >= 20) {
            $o = $number % 10;
            $t = (int) floor($number / 10);
            if ($o > 0) {
                $parts[] = $ones[$o] . ' و' . $tens[$t];
            } else {
                $parts[] = $tens[$t];
            }
        } elseif ($number > 0) {
            $parts[] = $ones[$number];
        }

        return implode(' و', $parts);
    }
}

if (!function_exists('branch_scope')) {
    function branch_scope(string $alias, string $column = 'branch_id'): string
    {
        return \App\Shared\Services\BranchScopeService::scopeQuery($alias, $column);
    }
}

if (!function_exists('branch_params')) {
    function branch_params(): array
    {
        return \App\Shared\Services\BranchScopeService::scopeParams();
    }
}

if (!function_exists('can')) {
    function can(string $permission): bool
    {
        $employee = \App\Core\App::getInstance()->currentEmployee();
        if (!$employee) {
            return false;
        }
        return $employee->hasPermission($permission);
    }
}

if (!function_exists('canAny')) {
    function canAny(array $permissions): bool
    {
        $employee = \App\Core\App::getInstance()->currentEmployee();
        if (!$employee) {
            return false;
        }
        return $employee->hasAnyPermission($permissions);
    }
}

if (!function_exists('flash_success')) {
    function flash_success(string $message): void
    {
        $session = \App\Core\App::getInstance()->session();
        $alerts = $session->get('_alerts', []);
        $alerts[] = ['type' => 'success', 'message' => $message];
        $session->flash('_alerts', $alerts);
    }
}

if (!function_exists('flash_error')) {
    function flash_error(string $message): void
    {
        $session = \App\Core\App::getInstance()->session();
        $alerts = $session->get('_alerts', []);
        $alerts[] = ['type' => 'error', 'message' => $message];
        $session->flash('_alerts', $alerts);
    }
}

if (!function_exists('flash_warning')) {
    function flash_warning(string $message): void
    {
        $session = \App\Core\App::getInstance()->session();
        $alerts = $session->get('_alerts', []);
        $alerts[] = ['type' => 'warning', 'message' => $message];
        $session->flash('_alerts', $alerts);
    }
}