<?php

namespace App\Http\Controllers\Admin\Withdraw;

use App\Enums\CoinMatterEnum;
use App\Enums\NotificationType;
use App\Enums\TransactionMatterEnum;
use App\Enums\TransactionStatusEnum;
use App\Enums\WithdrawStatusEnum;
use App\Events\CoinLogEvent;
use App\Exceptions\CustomWebException;
use App\Http\Controllers\Controller;
use App\Models\Currency;
use App\Models\Withdraw;
use App\Notifications\UserAutoNotification;
use App\Services\ModalIndexQuey;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class WithdrawalController extends Controller
{
    public function index(Request $request)
    {
        adminUserHasPermission(permission: 'read');

        $tab_buttons = [
            [
                'label' => __('All Withdraws'),
                'link' => route('admin.withdrawals.index'),
            ],
            [
                'label' => __('Pending'),
                'link' => route('admin.withdrawals.index', ['status' => WithdrawStatusEnum::PENDING]),
            ],
            [
                'label' => __('Approved'),
                'link' => route('admin.withdrawals.index', ['status' => WithdrawStatusEnum::APPROVED]),
            ],
            [
                'label' => __('Rejected'),
                'link' => route('admin.withdrawals.index', ['status' => WithdrawStatusEnum::REJECTED]),
            ],
        ];

        $withdraws = ModalIndexQuey::get(
            Withdraw::query()->when(
                $request->status,
                fn ($query, $status) => $query->where('status', $status)),
            ['user:id,first_name,last_name,email,phone', 'withdrawMethod:id,name']
        );

        $defaultCurrency = Currency::getDefaultCurrency();

        $columns = [
            [
                'label' => __('Name'),
                'key' => 'first_name',
                'header_class' => 'lg:w-[350px]',
                'render' => function ($withdraw) {
                    return '<a href="'.route('admin.users.edit', $withdraw->user->id).'" class="flex max-lg:justify-end items-center gap-3">
                                <img src="'.placeAvatar($withdraw->user->avatar, $withdraw->user->full_name).'" width="32" height="32"
                                    class="rounded-full max-md:hidden" alt="'.$withdraw->user->full_name.'" />
                                <div>
                                    <p class="s-text mb-1 font-medium">'.$withdraw->user->full_name.'</p>
                                    <span class="text-xs">'.$withdraw->user->email.'</span>
                                </div>
                            </a>';
                },
            ],
            [
                'label' => __('Gateway|Transaction'),
                'key' => 'track',
                'header_class' => 'lg:w-[200px]',
                'render' => function ($withdraw) {
                    return '<div>
                                <p class="s-text mb-1 font-medium">'.$withdraw->withdrawMethod->name.'</p>
                                <span class="text-xs">@'.$withdraw->track.'</span>
                            </div>';
                },
            ],
            [
                'label' => __('Amount|Charge'),
                'key' => 'amount',
                'is_sortable' => true,
                'render' => function ($withdraw) {
                    return '<p class="s-text font-medium">'.amountWithSymbol($withdraw->total).'</p>
                            <span class="text-xs">'.amountWithSymbol($withdraw->amount).' + '.amountWithSymbol($withdraw->charge).'</span>';
                },
            ],
            [
                'label' => __('Date'),
                'key' => 'created_at',
                'is_sortable' => true,
                'render' => function ($withdraw) {
                    return '<p class="s-text font-medium">'.$withdraw->created_at->format('Y-m-d H:i A').'</p>
                            <span class="text-xs">'.Carbon::parse($withdraw->created_at)->diffForHumans().'</span>';
                },
            ],

            [
                'label' => __('Conversion'),
                'key' => 'amount',
                'is_sortable' => true,
                'render' => function ($withdraw) use ($defaultCurrency) {
                    return '<p class="s-text font-medium">'.$defaultCurrency->rate.$defaultCurrency->code.' = '.currencyRate($withdraw->currency, $defaultCurrency->code).currencySymbol($withdraw->currency).'</p>
                            <span class="text-xs">'.amountWithSymbol($defaultCurrency->rate).' * '.amountWithSymbol($withdraw->amount).' = '.amountWithSymbol($withdraw->converted_amount).'</span>
                        ';
                },
            ],
            [
                'label' => __('Status'),
                'key' => 'status',
                'is_sortable' => true,
                'render' => function ($withdraw) {
                    return '<span class="status '.$withdraw->status->color().' capitalize">'.$withdraw->status->label().'</span>';
                },
            ],
            [
                'label' => __('Action'),
                'render' => function ($withdraw) {
                    return '<a href="'.route('admin.withdrawals.show', $withdraw->id).'" class="btn-primary outlined !py-1.5 !px-4" >
                    <i class="ph ph-eye"></i> Details</a>';
                },
            ],
        ];

        return view('admin.pages.withdrawals.index', compact('withdraws', 'columns', 'tab_buttons'));
    }

    public function show(Request $request, Withdraw $withdrawal)
    {
        adminUserHasPermission(permission: 'read');

        $buttons = [
            [
                'label' => 'Back',
                'link' => route('admin.withdrawals.index'),
                'type' => 'link',
                'icon' => 'ph ph-arrow-left',
            ],
        ];

        $withdrawal->load(['user:id,first_name,last_name,email,phone', 'withdrawMethod:id,name,fields']);

        return view('admin.pages.withdrawals.details', compact('withdrawal', 'buttons'));
    }

    public function update(Request $request, Withdraw $withdrawal)
    {
        adminUserHasPermission(permission: 'create');
        $validated = $request->validate([
            'status' => 'required|in:'.implode(',', WithdrawStatusEnum::values()),
        ]);

        try {
            DB::beginTransaction();

            if ($withdrawal->status == WithdrawStatusEnum::APPROVED) {
                throw new CustomWebException(__('Withdrawal request already approved'));
            }

            if ($withdrawal->status == WithdrawStatusEnum::REJECTED) {
                throw new CustomWebException(__('Withdrawal request already rejected'));
            }

            if ($validated['status'] == 'approved') {
                $user = $withdrawal?->user;

                $coins = $withdrawal->coins;

                if ($coins < $withdrawal->amount) {
                    throw new CustomWebException(__('Insufficient balance'));
                }

                $user->decrement('coins', $coins);

                $withdrawal->user->transactions()->create([
                    'track' => $withdrawal->track,
                    'title' => 'Withdrawal request from '.$withdrawal->user->full_name,
                    'amount' => $withdrawal->amount,
                    'type' => 'debit',
                    'ref_id' => $withdrawal->id,
                    'charge' => $withdrawal->charge,
                    'ref_type' => get_class($withdrawal),
                    'notes' => 'Withdrawal request for '.$withdrawal->user->full_name,
                    'matter' => TransactionMatterEnum::WITHDRAW,
                    'status' => TransactionStatusEnum::PAID,
                ]);

                event(new CoinLogEvent($user, CoinMatterEnum::BALANCE_DEDUCT, $coins, '-'));
            }

            $withdrawal->update([
                'status' => $validated['status'],
            ]);

            $withdrawal->user->notify(new UserAutoNotification(
                $validated['status'] == 'approved' ? NotificationType::WITHDRAWAL_REQUEST_APPROVED : NotificationType::WITHDRAWAL_REQUEST_REJECTED,
                [
                    'track' => $withdrawal->track,
                    'amount' => amountWithSymbol($withdrawal->amount),
                ]
            ));

            DB::commit();
        } catch (\Throwable $th) {
            DB::rollBack();

            return response()->json(['message' => $th->getMessage()], 400);
        }

        return response()->json(['message' => __("Withdrawal request {$validated['status']} successfully")]);
    }
}
