<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Currency;
use App\Models\Product;
use App\Models\Setting;
use App\Services\ExchangeRateService;
use Illuminate\Http\Request;

class CurrencyController extends Controller
{
    public function index()
    {
        $currencies = Currency::orderByDesc('is_base')->orderByDesc('is_default')->orderBy('code')->get();

        $stats = [
            'total'  => $currencies->count(),
            'active' => $currencies->where('is_active', true)->count(),
            'base'   => $currencies->firstWhere('is_base', true)?->code ?? '—',
        ];

        return view('admin.currencies.index', compact('currencies', 'stats'));
    }

    public function store(Request $request)
    {
        $data = $request->validate([
            'code'          => 'required|string|size:3|uppercase|unique:currencies,code',
            'name'          => 'required|string|max:100',
            'symbol'        => 'required|string|max:10',
            'exchange_rate' => 'required|numeric|min:0.000001',
        ]);

        Currency::create([
            'code'          => strtoupper($data['code']),
            'name'          => $data['name'],
            'symbol'        => $data['symbol'],
            'exchange_rate' => $data['exchange_rate'],
            'is_active'     => true,
            'is_base'       => false,
            'is_default'    => false,
        ]);

        return back()->with('success', "Currency {$data['code']} added successfully.");
    }

    public function updateRate(Request $request, Currency $currency)
    {
        $data = $request->validate([
            'exchange_rate' => 'required|numeric|min:0.000001',
        ]);

        if ($currency->is_base) {
            return back()->with('error', 'Cannot change the rate of the base currency.');
        }

        $currency->update(['exchange_rate' => round((float) $data['exchange_rate'], 6)]);
        return back()->with('success', "{$currency->code} rate updated.");
    }

    public function setDefault(Currency $currency)
    {
        Currency::where('is_default', true)->update(['is_default' => false]);
        $currency->update(['is_default' => true, 'is_active' => true]);

        // Sync global settings
        Setting::set('default_currency', $currency->code);
        Setting::set('currency_symbol',  $currency->symbol);

        return back()->with('success', "{$currency->code} set as default currency.");
    }

    public function setBase(Currency $currency)
    {
        Currency::where('is_base', true)->update(['is_base' => false]);
        $currency->update(['is_base' => true, 'is_active' => true, 'exchange_rate' => 1.000000]);

        return back()->with('success', "{$currency->code} set as base currency. Re-run Update Live Rates to recalculate all rates.");
    }

    public function toggle(Currency $currency)
    {
        if ($currency->is_base || $currency->is_default) {
            return back()->with('error', 'Cannot disable the base or default currency.');
        }

        $currency->update(['is_active' => ! $currency->is_active]);
        $state = $currency->is_active ? 'enabled' : 'disabled';
        return back()->with('success', "{$currency->code} {$state}.");
    }

    public function destroy(Currency $currency)
    {
        if ($currency->is_base || $currency->is_default) {
            return back()->with('error', 'Cannot delete the base or default currency.');
        }

        $currency->delete();
        return back()->with('success', "{$currency->code} removed.");
    }

    public function updateLiveRates(ExchangeRateService $service)
    {
        $result = $service->updateAll();

        if ($result['updated'] === 0) {
            return back()->with('error', "Rate update failed: {$result['source']}.");
        }

        return back()->with('success', "Live rates updated for {$result['updated']} currencies.");
    }

    public function recalculatePricing(Request $request)
    {
        $fromCode = $request->input('from_currency');
        $toCode   = $request->input('to_currency');

        if ($fromCode === $toCode) {
            return back()->with('error', 'Source and target currencies are the same.');
        }

        $from = Currency::where('code', $fromCode)->first();
        $to   = Currency::where('code', $toCode)->first();

        if (! $from || ! $to) {
            return back()->with('error', 'Invalid currency selection.');
        }

        // Convert: price_in_to = price_in_from * from_rate / to_rate
        // Both rates are stored as "how many base units = 1 unit of that currency"
        // price_in_base = price_in_from * from_rate
        // price_in_to   = price_in_base / to_rate
        $factor = $from->is_base
            ? (1 / $to->exchange_rate)
            : ($from->exchange_rate / ($to->is_base ? 1 : $to->exchange_rate));

        $count = 0;
        foreach (Product::all() as $product) {
            $product->update(['price' => round($product->price * $factor, 2)]);
            $count++;
        }

        return back()->with('success', "Recalculated prices for {$count} products from {$from->code} to {$to->code}.");
    }
}
