<?php

namespace Tests\Feature;

use App\Models\Account;
use App\Models\Currency;
use App\Models\Transaction;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class SellCurrencyTest extends TestCase
{
    use RefreshDatabase;

    public function test_sell_currency_updates_stock_account_and_profit(): void
    {
        $lkr = Currency::create(['code' => 'LKR', 'name' => 'Sri Lankan Rupee']);
        $usd = Currency::create(['code' => 'USD', 'name' => 'US Dollar']);

        // Account that receives LKR payment (starting balance 10,000 LKR)
        $account = Account::create([
            'name' => 'Main Cash',
            'currency_id' => $lkr->id,
            'type' => 'cash',
            'balance' => 10000,
        ]);

        // Account holding USD stock (starting balance 100 USD)
        $usdAccount = Account::create([
            'name' => 'USD Cash',
            'currency_id' => $usd->id,
            'type' => 'cash',
            'balance' => 100,
        ]);

        // Create a purchase transaction to define average buy rate of 300
        Transaction::create([
            'type' => 'buy',
            'currency_id' => $usd->id,
            'quantity' => 100,
            'rate' => 300,
            'payment_amount' => 30000,
            'payment_currency_id' => $lkr->id,
            'payment_account_id' => $account->id,
            'account_id' => $usdAccount->id,
        ]);

        $response = $this
            ->withSession(['admin_logged_in' => true])
            ->post(route('transactions.sell.store'), [
                'currency_id' => $usd->id,
                'source_account_id' => $usdAccount->id,
                'target_account_id' => $account->id,
                'quantity' => 40,
                'payment_amount' => 13000, // 40 USD sold at 325 rate
                'handling_fee' => 500,
                'is_pending' => 0,
            ]);

        $response->assertRedirect(route('transactions.sell.create'));

        $usdAccount->refresh();
        $account->refresh();
        
        // The last transaction should be our Sell transaction
        $transaction = Transaction::where('type', 'sell')->first();

        $this->assertEquals(60.0000, (float) $usdAccount->balance);
        $this->assertEquals(23500.0000, (float) $account->balance);
        $this->assertSame('sell', $transaction->type);
        $this->assertEquals(40.0000, (float) $transaction->quantity);
        $this->assertEquals(13000.0000, (float) $transaction->payment_amount);
        $this->assertEquals(1000.0000, (float) $transaction->exchange_profit);
        $this->assertEquals(1000.0000, (float) $transaction->total_profit);
    }

    public function test_sell_currency_rejects_insufficient_stock(): void
    {
        $lkr = Currency::create(['code' => 'LKR', 'name' => 'Sri Lankan Rupee']);
        $usd = Currency::create(['code' => 'USD', 'name' => 'US Dollar']);

        $account = Account::create([
            'name' => 'Main Cash',
            'currency_id' => $lkr->id,
            'type' => 'cash',
            'balance' => 10000,
        ]);

        $usdAccount = Account::create([
            'name' => 'USD Cash',
            'currency_id' => $usd->id,
            'type' => 'cash',
            'balance' => 10,
        ]);

        Transaction::create([
            'type' => 'buy',
            'currency_id' => $usd->id,
            'quantity' => 10,
            'rate' => 300,
            'payment_amount' => 3000,
            'payment_currency_id' => $lkr->id,
            'payment_account_id' => $account->id,
            'account_id' => $usdAccount->id,
        ]);

        $response = $this
            ->withSession(['admin_logged_in' => true])
            ->from(route('transactions.sell.create'))
            ->post(route('transactions.sell.store'), [
                'currency_id' => $usd->id,
                'source_account_id' => $usdAccount->id,
                'target_account_id' => $account->id,
                'quantity' => 20,
                'payment_amount' => 6500,
                'handling_fee' => 0,
            ]);

        $response
            ->assertRedirect(route('transactions.sell.create'))
            ->assertSessionHasErrors('source_account_id');

        // We only have the 1 buy transaction, no sells should have been created
        $this->assertDatabaseCount('transactions', 1);
    }
}
