<?php

namespace App\Services;

use Carbon\CarbonInterface;
use Illuminate\Support\Carbon;

/**
 * Money, dates and numbers for the central panel.
 *
 * Simpler than the product-side formatter on purpose: this panel bills in one
 * currency and has no per-tenant preferences to honour.
 */
class Formatter
{
    public function symbol(): string
    {
        return (string) config('thinkrax.defaults.currency.symbol', 'Rs');
    }

    public function currencyCode(): string
    {
        return (string) config('thinkrax.defaults.currency.code', 'PKR');
    }

    public function money(float|int|string|null $amount, bool $withSymbol = true): string
    {
        $formatted = number_format((float) ($amount ?? 0), (int) config('thinkrax.defaults.decimals', 2));

        return $withSymbol ? $this->symbol().' '.$formatted : $formatted;
    }

    public function accounting(float|int|null $amount, bool $withSymbol = true): string
    {
        $value = (float) ($amount ?? 0);

        return $value < 0
            ? '('.$this->money(abs($value), $withSymbol).')'
            : $this->money($value, $withSymbol);
    }

    public function quantity(float|int|string|null $quantity, ?string $unit = null): string
    {
        $formatted = number_format((float) ($quantity ?? 0), 2);

        if (str_contains($formatted, '.')) {
            $formatted = rtrim(rtrim($formatted, '0'), '.');
        }

        return $unit ? "{$formatted} {$unit}" : $formatted;
    }

    public function percent(float|int|null $value, int $decimals = 1): string
    {
        return number_format((float) ($value ?? 0), $decimals).'%';
    }

    /** Large figures on dashboard tiles: 1.2M, 350K. */
    public function compact(float|int|null $value): string
    {
        $value = (float) ($value ?? 0);
        $abs = abs($value);

        return match (true) {
            $abs >= 1_000_000_000 => round($value / 1_000_000_000, 2).'B',
            $abs >= 1_000_000 => round($value / 1_000_000, 2).'M',
            $abs >= 1_000 => round($value / 1_000, 1).'K',
            default => (string) round($value, 2),
        };
    }

    public function dateFormat(): string
    {
        return (string) config('thinkrax.defaults.date_format', 'd-m-Y');
    }

    public function timeFormat(): string
    {
        return (string) config('thinkrax.defaults.time_format', 'h:i A');
    }

    public function date(CarbonInterface|string|null $date): string
    {
        return $date ? Carbon::parse($date)->format($this->dateFormat()) : '—';
    }

    public function dateTime(CarbonInterface|string|null $date): string
    {
        return $date ? Carbon::parse($date)->format($this->dateFormat().' '.$this->timeFormat()) : '—';
    }

    public function time(CarbonInterface|string|null $date): string
    {
        return $date ? Carbon::parse($date)->format($this->timeFormat()) : '—';
    }

    public function ago(CarbonInterface|string|null $date): string
    {
        return $date ? Carbon::parse($date)->diffForHumans() : '—';
    }
}
