<?php

namespace Webkul\Admin\Http\Controllers\Settings;

use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Event;
use Illuminate\View\View;
use Webkul\Admin\DataGrids\Settings\ExchangeRatesDataGrid;
use Webkul\Admin\Http\Controllers\Controller;
use Webkul\Core\Helpers\Exchange\ExchangeRate;
use Webkul\Core\Repositories\CurrencyRepository;
use Webkul\Core\Repositories\ExchangeRateRepository;

class ExchangeRateController extends Controller
{
    /**
     * Create a new controller instance.
     */
    public function __construct(
        protected ExchangeRateRepository $exchangeRateRepository,
        protected CurrencyRepository $currencyRepository
    ) {}

    /**
     * Display a listing of the resource.
     */
    public function index(): View|JsonResponse
    {
        if (request()->ajax()) {
            return datagrid(ExchangeRatesDataGrid::class)->process();
        }

        $baseCurrency = core()->getBaseCurrency();

        $currencies = $this->currencyRepository->with('exchange_rate')
            ->where('id', '!=', $baseCurrency->id)
            ->get();

        return view('admin::settings.exchange-rates.index', compact('currencies'));
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(): JsonResponse
    {
        $baseCurrency = core()->getBaseCurrency();

        $this->validate(request(), [
            'target_currency' => ['required', 'unique:currency_exchange_rates,target_currency', 'not_in:'.$baseCurrency->id],
            'rate' => 'required|numeric',
        ]);

        Event::dispatch('core.exchange_rate.create.before');

        $exchangeRate = $this->exchangeRateRepository->create(request()->only([
            'target_currency',
            'rate',
        ]));

        Event::dispatch('core.exchange_rate.create.after', $exchangeRate);

        return new JsonResponse([
            'message' => trans('admin::app.settings.exchange-rates.index.create-success'),
        ]);
    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit(int $id): JsonResponse
    {
        $baseCurrency = core()->getBaseCurrency();

        $currencies = $this->currencyRepository->with('exchange_rate')
            ->where('id', '!=', $baseCurrency->id)
            ->get();

        $exchangeRate = $this->exchangeRateRepository->findOrFail($id);

        return new JsonResponse([
            'data' => [
                'currencies' => $currencies,
                'exchangeRate' => $exchangeRate,
            ],
        ]);
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(): JsonResponse
    {
        $baseCurrency = core()->getBaseCurrency();

        $this->validate(request(), [
            'target_currency' => ['required', 'unique:currency_exchange_rates,target_currency,'.request()->id, 'not_in:'.$baseCurrency->id],
            'rate' => 'required|numeric',
        ]);

        Event::dispatch('core.exchange_rate.update.before', request()->id);

        $exchangeRate = $this->exchangeRateRepository->update(request()->only([
            'target_currency',
            'rate',
        ]), request()->id);

        Event::dispatch('core.exchange_rate.update.after', $exchangeRate);

        return new JsonResponse([
            'message' => trans('admin::app.settings.exchange-rates.index.update-success'),
        ]);
    }

    /**
     * Update rates using the configured exchange rate API service.
     */
    public function updateRates()
    {
        try {
            ExchangeRate::resolve()->updateRates();

            session()->flash('success', trans('admin::app.settings.exchange-rates.index.update-success'));
        } catch (\Exception $e) {
            session()->flash('error', $e->getMessage());
        }

        return redirect()->route('admin.settings.exchange_rates.index');
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(int $id): JsonResponse
    {
        try {
            $this->exchangeRateRepository->findOrFail($id);

            Event::dispatch('core.exchange_rate.delete.before', $id);

            $this->exchangeRateRepository->delete($id);

            Event::dispatch('core.exchange_rate.delete.after', $id);

            return new JsonResponse([
                'message' => trans('admin::app.settings.exchange-rates.index.delete-success'),
            ], 200);
        } catch (\Exception $e) {
            report($e);
        }

        return new JsonResponse([
            'message' => trans('admin::app.settings.exchange-rates.index.delete-error'),
        ], 500);
    }
}
