<?php

namespace App\Http\Controllers\Admin;

use App\Enums\AccountStatus;
use App\Enums\AccountType;
use App\Enums\BrokerageAccountType;
use App\Enums\HoldingType;
use App\Enums\RequestStatus;
use App\Http\Controllers\Controller;
use App\Models\Account;
use App\Models\BrokerageHolding;
use App\Models\BrokerageRequest;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;

class AdminBrokerageController extends Controller
{
    public function requests()
    {
        try {
            $requests = BrokerageRequest::with(['user', 'account.holdings'])->latest()->paginate(20);

            $brokerageTypes = [
                AccountType::Retirement->value,
                AccountType::IRA->value,
                AccountType::FourOhOneK->value,
                AccountType::Investment->value,
            ];

            $accounts = Account::whereIn('account_type', $brokerageTypes)
                ->with(['user', 'holdings'])
                ->latest()
                ->get();

            return view('admin.brokerage.requests', compact('requests', 'accounts'));
        } catch (\Exception $e) {
            Log::error($e->getMessage());
            return back()->with('error', 'An error occurred.');
        }
    }

    public function approve(BrokerageRequest $brokerageRequest)
    {
        try {
            $brokerageRequest->update(['status' => RequestStatus::Approved]);

            $accountTypeMap = [
                BrokerageAccountType::Retirement->value => AccountType::Retirement,
                BrokerageAccountType::TraditionalIRA->value => AccountType::IRA,
                BrokerageAccountType::RothIRA->value => AccountType::IRA,
                BrokerageAccountType::FourOhOneK->value => AccountType::FourOhOneK,
            ];

            $accountType = $accountTypeMap[$brokerageRequest->brokerage_type->value] ?? AccountType::Investment;

            $account = Account::create([
                'user_id' => $brokerageRequest->user_id,
                'account_number' => Account::generateAccountNumber(),
                'account_type' => $accountType,
                'currency' => \App\Enums\Currency::USD,
                'balance' => 0,
                'status' => AccountStatus::Active,
            ]);

            $brokerageRequest->update(['account_id' => $account->id]);

            return back()->with('success', 'Brokerage request approved and account created.');
        } catch (\Exception $e) {
            Log::error($e->getMessage());
            return back()->with('error', 'An error occurred.');
        }
    }

    public function reject(Request $request, BrokerageRequest $brokerageRequest)
    {
        try {
            $brokerageRequest->update([
                'status' => RequestStatus::Rejected,
                'admin_note' => $request->admin_note,
            ]);

            return back()->with('success', 'Brokerage request rejected.');
        } catch (\Exception $e) {
            Log::error($e->getMessage());
            return back()->with('error', 'An error occurred.');
        }
    }

    public function accounts()
    {
        try {
            $brokerageTypes = [
                AccountType::Retirement->value,
                AccountType::IRA->value,
                AccountType::FourOhOneK->value,
                AccountType::Investment->value,
            ];

            $accounts = Account::whereIn('account_type', $brokerageTypes)
                ->with(['user', 'holdings'])
                ->latest()
                ->paginate(20);

            return view('admin.brokerage.accounts', compact('accounts'));
        } catch (\Exception $e) {
            Log::error($e->getMessage());
            return back()->with('error', 'An error occurred.');
        }
    }

    public function holdings(Account $account)
    {
        try {
            $account->load(['user', 'holdings']);
            $holdingTypes = HoldingType::cases();

            return view('admin.brokerage.holdings', compact('account', 'holdingTypes'));
        } catch (\Exception $e) {
            Log::error($e->getMessage());
            return back()->with('error', 'An error occurred.');
        }
    }

    public function storeHolding(Request $request, Account $account)
    {
        try {
            $request->validate([
                'name' => 'required|string|max:255',
                'type' => 'required|string|in:' . implode(',', array_column(HoldingType::cases(), 'value')),
                'quantity' => 'required|numeric|min:0',
                'purchase_price' => 'required|numeric|min:0',
                'current_price' => 'required|numeric|min:0',
            ]);

            BrokerageHolding::create([
                'account_id' => $account->id,
                'name' => $request->name,
                'type' => $request->type,
                'quantity' => $request->quantity,
                'purchase_price' => $request->purchase_price,
                'current_price' => $request->current_price,
                'profit_loss' => ($request->current_price - $request->purchase_price) * $request->quantity,
            ]);

            return back()->with('success', 'Holding added successfully.');
        } catch (\Exception $e) {
            Log::error($e->getMessage());
            return back()->with('error', 'An error occurred.');
        }
    }

    public function updateHolding(Request $request, BrokerageHolding $holding)
    {
        try {
            $request->validate([
                'name' => 'required|string|max:255',
                'type' => 'required|string',
                'quantity' => 'required|numeric|min:0',
                'purchase_price' => 'required|numeric|min:0',
                'current_price' => 'required|numeric|min:0',
            ]);

            $holding->update([
                'name' => $request->name,
                'type' => $request->type,
                'quantity' => $request->quantity,
                'purchase_price' => $request->purchase_price,
                'current_price' => $request->current_price,
                'profit_loss' => ($request->current_price - $request->purchase_price) * $request->quantity,
            ]);

            return back()->with('success', 'Holding updated.');
        } catch (\Exception $e) {
            Log::error($e->getMessage());
            return back()->with('error', 'An error occurred.');
        }
    }

    public function destroyHolding(BrokerageHolding $holding)
    {
        try {
            $holding->delete();
            return back()->with('success', 'Holding removed.');
        } catch (\Exception $e) {
            Log::error($e->getMessage());
            return back()->with('error', 'An error occurred.');
        }
    }
}
