<?php

namespace App\Http\Controllers;

use App\Models\rate;
use Illuminate\Http\Request;
use App\Services\RateService;
use App\Services\SalesService;
use App\Traits\GetModelsPaginated;
use Illuminate\Support\Facades\DB;
use Throwable;

class rateController extends Controller
{
    use GetModelsPaginated;

    protected $rateService;
    protected $salesService;

    public function __construct(RateService $rateService, SalesService $salesService)
    {
        $this->rateService = $rateService;
        $this->salesService = $salesService;
    }

    public function index()
    {
        return view('admin.rate.index');
    }

    public function ratePaginatedJson(Request $request)
    {
        return $this->paginateFromService(
            $request,
            function (int $page, int $length, ?string $searchValue, ?string $status) {
                return $this->rateService->getRateData($page, $length, $searchValue, $status);
            }
        );
    }

    public function create()
    {
        return view('admin.rate.create', [
            'returnTo' => request()->query('return_to'),
        ]);
    }

    public function store(Request $request)
    {
        $request->merge([
            'usd_rate' => $this->normalizeRateInput($request->input('usd_rate')),
        ]);

        $validated = $request->validate([
            'usd_rate' => ['required', 'regex:/^\d+(\.\d{1,4})?$/', 'numeric', 'gt:0'],
            'is_active' => ['nullable', 'boolean'],
            'return_to' => ['nullable', 'url'],
        ], [
            'usd_rate.required' => 'La tasa USD es obligatoria.',
            'usd_rate.regex' => 'El formato de la tasa no es válido. Puede usar coma o punto para decimales.',
            'usd_rate.numeric' => 'La tasa USD debe ser numérica.',
            'usd_rate.gt' => 'La tasa USD debe ser mayor a 0.',
        ]);

        $isActive = $request->boolean('is_active', true);
        $returnTo = $validated['return_to'] ?? null;

        try {
            $this->persistRate((string) $validated['usd_rate'], $isActive);

            if (! empty($returnTo)) {
                return redirect()->to($returnTo)->with('success', 'Tasa registrada correctamente.');
            }

            return redirect()->back()->with('success', 'Tasa registrada correctamente.');
        } catch (Throwable $exception) {
            return redirect()->back()->withErrors([
                'error' => 'Error al registrar la tasa: ' . $exception->getMessage(),
            ])->withInput();
        }
    }

    public function quickStore(Request $request)
    {
        $request->merge([
            'usd_rate' => $this->normalizeRateInput($request->input('usd_rate')),
        ]);

        $validated = $request->validate([
            'usd_rate' => ['required', 'regex:/^\d+(\.\d{1,4})?$/', 'numeric', 'gt:0'],
            'return_to' => ['nullable', 'url'],
        ], [
            'usd_rate.required' => 'La tasa USD es obligatoria.',
            'usd_rate.regex' => 'El formato de la tasa no es válido. Puede usar coma o punto para decimales.',
            'usd_rate.numeric' => 'La tasa USD debe ser numérica.',
            'usd_rate.gt' => 'La tasa USD debe ser mayor a 0.',
        ]);

        $returnTo = $validated['return_to'] ?? url()->previous();

        try {
            $this->persistRate((string) $validated['usd_rate'], true);

            return redirect()->to((string) $returnTo)->with('success', 'Tasa registrada correctamente desde acceso rápido.');
        } catch (Throwable $exception) {
            return redirect()->to((string) $returnTo)
                ->withErrors(['error' => 'Error al registrar la tasa rápida: ' . $exception->getMessage()])
                ->withInput();
        }
    }

    private function persistRate(string $usdRate, bool $isActive): void
    {
        DB::transaction(function () use ($usdRate, $isActive): void {
            if ($isActive) {
                rate::query()->where('is_active', true)->update(['is_active' => false]);
            }

            rate::create([
                'usd_rate' => $usdRate,
                'is_active' => $isActive,
            ]);

            if ($isActive) {
                $this->salesService->setNewRateToDebtSales();
            }
        });
    }

    private function normalizeRateInput($value): ?string
    {
        if ($value === null) {
            return null;
        }

        $normalized = trim((string) $value);
        if ($normalized === '') {
            return null;
        }

        $normalized = preg_replace('/\s+/', '', $normalized) ?? '';
        $normalized = preg_replace('/[^0-9.,]/', '', $normalized) ?? '';

        if ($normalized === '') {
            return null;
        }

        // Use the last separator as decimal mark and strip the rest as thousands separators.
        $lastDot = strrpos($normalized, '.');
        $lastComma = strrpos($normalized, ',');

        $separatorPosition = false;
        if ($lastDot !== false && $lastComma !== false) {
            $separatorPosition = max($lastDot, $lastComma);
        } elseif ($lastDot !== false) {
            $separatorPosition = $lastDot;
        } elseif ($lastComma !== false) {
            $separatorPosition = $lastComma;
        }

        if ($separatorPosition !== false) {
            $integerPart = substr($normalized, 0, $separatorPosition);
            $decimalPart = substr($normalized, $separatorPosition + 1);

            $integerPart = preg_replace('/[^0-9]/', '', $integerPart) ?? '';
            $decimalPart = preg_replace('/[^0-9]/', '', $decimalPart) ?? '';

            return $decimalPart === '' ? $integerPart : $integerPart . '.' . $decimalPart;
        }

        return preg_replace('/[^0-9]/', '', $normalized) ?? null;
    }
}
