<?php

namespace App\Http\Controllers\Admin\User;

use App\Enums\KycStatusEnum;
use App\Enums\NotificationType;
use App\Enums\UserStatusEnum;
use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\UserRequest;
use App\Models\User;
use App\Notifications\UserAutoNotification;
use App\Services\ModalIndexQuey;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class UserController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index()
    {
        adminUserHasPermission(permission: 'read');

        $tab_buttons = [
            [
                'label' => __('All Users'),
                'link' => route('admin.users.index'),
            ],
            [
                'label' => __('Active Users'),
                'count' => User::where('status', UserStatusEnum::ACTIVE->value)->count(),
                'link' => route('admin.users.index', ['type' => 'active']),
            ],
            [
                'label' => __('Inactive Users'),
                'count' => User::where('status', UserStatusEnum::INACTIVE->value)->count(),
                'link' => route('admin.users.index', ['type' => 'inactive']),
            ],
            [
                'label' => __('Banned Users'),
                'count' => User::where('status', UserStatusEnum::BANNED->value)->count(),
                'link' => route('admin.users.index', ['type' => 'banned']),
            ],
            [
                'label' => __('Email Verified'),
                'count' => User::whereNotNull('email_verified_at')->count(),
                'link' => route('admin.users.index', ['type' => 'email_verified']),
            ],
            [
                'label' => __('Phone Verified'),
                'count' => User::whereNotNull('phone_verified_at')->count(),
                'link' => route('admin.users.index', ['type' => 'phone_verified']),
            ],
            [
                'label' => __('KYC UnVerified'),
                'count' => User::where('is_kyc_verified', false)->count(),
                'link' => route('admin.users.index', ['type' => 'kyc_unverified']),
            ],
            [
                'label' => __('KYC Verified'),
                'count' => User::where('is_kyc_verified', true)->count(),
                'link' => route('admin.users.index', ['type' => 'kyc_verified']),
            ],
        ];

        $users = ModalIndexQuey::get(User::query()->when(request('type'), function ($query, $type) {
            if ($type === 'active') {
                $query->where('status', UserStatusEnum::ACTIVE->value);
            } elseif ($type === 'inactive') {
                $query->where('status', UserStatusEnum::INACTIVE->value);
            } elseif ($type === 'email_verified') {
                $query->whereNotNull('email_verified_at');
            } elseif ($type === 'phone_verified') {
                $query->whereNotNull('phone_verified_at');
            } elseif ($type === 'kyc_unverified') {
                $query->where('is_kyc_verified', false);
            } elseif ($type === 'kyc_verified') {
                $query->where('is_kyc_verified', true);
            } elseif ($type === 'banned') {
                $query->where('status', UserStatusEnum::BANNED->value);
            }
        }));

        $columns = [
            [
                'label' => __('Name'),
                'key' => 'first_name',
                'header_class' => 'lg:w-[350px]',
                'render' => function ($user) {
                    return '<a href="'.route('admin.users.edit', $user->id).'" class="flex max-lg:justify-end items-center gap-3">
                                <img src="'.placeAvatar($user->avatar, $user->full_name).'" width="32" height="32"
                                    class="rounded-full max-md:hidden" alt="'.$user->full_name.'" />
                                <div>
                                    <p class="s-text mb-1 font-medium">'.$user->full_name.'</p>
                                    <span class="text-xs">@'.$user->username.'</span>
                                </div>
                            </a>';
                },
            ],
            [
                'label' => __('Email-Mobile'),
                'key' => 'email',
                'header_class' => 'lg:w-[200px]',
                'render' => function ($user) {
                    return '<p class="s-text font-medium">'.protectOnDemo($user->email).'</p>
                            <span class="text-xs">'.protectOnDemo($user->phone).'</span>';
                },
            ],
            [
                'label' => __('Joined At'),
                'key' => 'created_at',
                'is_sortable' => true,
                'render' => function ($user) {
                    return '<p class="s-text font-medium">'.$user->created_at->format('Y-m-d H:i A').'</p>
                            <span class="text-xs">'.Carbon::parse($user->created_at)->diffForHumans().'</span>';
                },
            ],
            [
                'label' => __('Coins'),
                'key' => 'Coins',
                'is_sortable' => true,
                'render' => function ($user) {
                    return $user?->coins ? '<p class="s-text font-medium">'.$user?->coins.'</p>' : '-';
                },
            ],
            [
                'label' => __('Score'),
                'key' => 'Score',
                'is_sortable' => true,
                'render' => function ($user) {
                    return $user?->score ? '<p class="s-text font-medium">'.$user?->score.'</p>' : '-';
                },
            ],
            [
                'label' => __('Status'),
                'key' => 'status',
                'is_sortable' => true,
                'render' => function ($user) {
                    $status = $user->status;
                    if ($status instanceof UserStatusEnum) {
                        return '<span class="status '.$status->color().' capitalize">'.__($status->label()).'</span>';
                    }

                    return '<span class="status text-gray-400 capitalize">'.__('Unknown').'</span>';
                },
            ],
            [
                'label' => __('Action'),
                'render' => function ($user) {
                    $action_buttons = [
                        [
                            'label' => __('Details'),
                            'icon' => 'ph ph-eye',
                            'type' => 'link',
                            'href' => route('admin.users.edit', $user->id),
                        ],
                        [
                            'label' => __('Delete'),
                            'icon' => 'ph ph-trash',
                            'type' => 'delete',
                            'href' => route('admin.users.destroy', $user->id),
                        ],
                    ];
                    if (! $user->is_kyc_verified && $user?->kyc?->status == KycStatusEnum::PENDING) {
                        $action_buttons[] = [
                            'label' => __('Verify KYC'),
                            'icon' => 'ph ph-shield-check',
                            'type' => 'link',
                            'href' => route('admin.users.kyc-verify', $user->id),
                        ];
                    }

                    return view('admin.components.table-action', compact('action_buttons'))->render();
                },
            ],
        ];

        return view('admin.pages.user-manage.users', compact('tab_buttons', 'users', 'columns'));
    }

    public function edit(User $user)
    {
        $total_withdraw_amount = $user->withdraws()->where('status', 'approved')->sum('amount') ?? 0;
        $overviews = [
            [
                'title' => __('Total Score'),
                'amount' => $user?->score ?? 0,
                'icon' => 'ph ph-piggy-bank text-xl text-white',
            ],
            [
                'title' => __('Total Withdrawal Amount'),
                'amount' => amountWithSymbol($total_withdraw_amount ?? 0),
                'icon' => 'ph ph-wallet text-xl text-white',
                'link' => route('admin.withdrawals.index', ['user_id' => $user->id]),
            ],
            [
                'title' => __('Total Transactions'),
                'amount' => $user->transactions()->where('status', ['paid'])->count(),
                'icon' => 'ph ph-arrows-left-right text-xl text-white',
                'link' => route('admin.reports.transactions', ['user_id' => $user->id]),
            ],
        ];

        return view('admin.pages.user-manage.user-details', compact('user', 'overviews'));
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(UserRequest $request, User $user)
    {

        try {
            DB::beginTransaction();

            $user->update($request->validated());

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

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

        return response()->json([
            'message' => __('User updated successfully'),
        ]);
    }

    public function destroy(User $user)
    {
        $user->delete();

        return redirect()->back()->withSuccess(__('User deleted successfully'));
    }

    public function addBalance(Request $request, User $user)
    {
        $request->validate([
            'coins' => 'required|numeric|min:1',
        ]);

        try {
            DB::beginTransaction();

            $coins = $request->coins;

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

            $user->notify(new UserAutoNotification(
                NotificationType::COIN_ADD,
                [
                    'coins' => amountWithSymbol($coins),
                ]
            ));

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

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

        return response()->json([
            'message' => __('Coins added successfully'),
            'reload' => true,
        ]);
    }

    public function subtractBalance(Request $request, User $user)
    {
        $request->validate([
            'coins' => 'required|numeric|min:1',
        ]);

        if ($user->coins < $request->coins) {
            return response()->json(['message' => __('Insufficient coins')], 400);
        }

        try {
            DB::beginTransaction();

            $coins = $request->coins;

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

            $user->notify(new UserAutoNotification(
                NotificationType::COIN_SUBTRACT,
                [
                    'coins' => amountWithSymbol($coins),
                ]
            ));

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

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

        return response()->json([
            'message' => __('Coins subtracted successfully'),
            'reload' => true,
        ]);
    }

    public function banAccount(Request $request, User $user)
    {
        try {
            DB::beginTransaction();
            $user->status = $user->status == UserStatusEnum::BANNED ? UserStatusEnum::ACTIVE : UserStatusEnum::BANNED;
            $user->save();

            $user->notify(new UserAutoNotification(
                $user->status === UserStatusEnum::ACTIVE ? NotificationType::ACCOUNT_BANNED : NotificationType::ACCOUNT_ACTIVE,
            ));

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

            return redirect()->back()->with('error', $th->getMessage());
        }

        return redirect()->back()->withSuccess(__('User '.$user->status->value.' successfully'));
    }

    public function signInUser(User $user)
    {
        $token = $user->createToken(self::TOKEN_NAME)->plainTextToken;

        return redirect()->away(config('application_info.frontend_url').'?token='.$token);
    }

    public function kycForms(User $user)
    {
        $buttons = [
            [
                'label' => __('Back'),
                'icon' => 'ph ph-arrow-clockwise',
                'type' => 'link',
                'link' => route('admin.users.index'),
            ],
        ];

        $user->load([
            'kyc' => function ($q) {
                $q->with(['forms' => fn ($q) => $q->with('kycForm')]);
            },
        ]);

        return view('admin.pages.user-manage.kyc-verify', compact('user', 'buttons'));
    }

    public function kycVerifyAccept(User $user)
    {
        try {
            DB::beginTransaction();
            $user->is_kyc_verified = 1;
            $user->save();

            $user->kyc()->update([
                'status' => KycStatusEnum::APPROVED,
            ]);

            $user->notifyNow(new UserAutoNotification(NotificationType::KYC_VERIFICATION_ACCEPTED));

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

            return redirect()->back()->withError($th->getMessage());
        }

        return redirect()->back()->withSuccess(__('User account accepted.'));
    }

    public function kycVerifyReject(User $user)
    {
        try {
            DB::beginTransaction();

            $user->is_kyc_verified = 0;
            $user->save();

            $user->kyc()->update([
                'status' => KycStatusEnum::REJECTED,
            ]);

            $user->notifyNow(new UserAutoNotification(NotificationType::KYC_VERIFICATION_REJECTED));

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

            return redirect()->back()->withError($th->getMessage());
        }

        return redirect()->back()->withSuccess(__('User account rejected.'));
    }
}
