<?php

declare(strict_types=1);

namespace Database\Seeders;

use App\Models\InvestmentDistribution;
use App\Models\InvestmentProperty;
use App\Models\PartnerDistribution;
use App\Models\PartnerInvestment;
use App\Models\User;
use Illuminate\Database\Seeder;

final class PartnerInvestmentSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        // Get all partners and investment properties
        $partners = User::role('partner')->get();
        $properties = InvestmentProperty::active()->get();

        if ($partners->isEmpty() || $properties->isEmpty()) {
            $this->command->warn('No partners or investment properties found. Skipping investment seeding.');

            return;
        }

        // Create investments for each partner
        foreach ($partners as $partner) {
            // Each partner invests in 1-3 random properties
            $numInvestments = rand(1, min(3, $properties->count()));
            $selectedProperties = $properties->random($numInvestments);

            foreach ($selectedProperties as $property) {
                $sharesPurchased = rand(
                    $property->minimum_shares,
                    min(10, $property->shares_available)
                );

                if ($sharesPurchased <= 0) {
                    continue;
                }

                $totalInvestment = $sharesPurchased * $property->price_per_share;

                // Create investment
                $investment = PartnerInvestment::create([
                    'partner_id' => $partner->id,
                    'investment_property_id' => $property->id,
                    'shares_purchased' => $sharesPurchased,
                    'total_investment' => $totalInvestment,
                    'purchase_date' => now()->subDays(rand(30, 90)),
                    'status' => 'active',
                ]);

                // Update property shares available
                $property->decrement('shares_available', $sharesPurchased);

                // Create 1-3 past distributions for this investment
                $numDistributions = rand(1, 3);

                for ($i = 0; $i < $numDistributions; $i++) {
                    $distributionPeriod = now()->subMonths($i + 1)->startOfMonth();

                    // Check if distribution exists for this property and period
                    $distribution = InvestmentDistribution::firstOrCreate(
                        [
                            'investment_property_id' => $property->id,
                            'distribution_period' => $distributionPeriod,
                        ],
                        [
                            'total_rental_income' => rand(8000, 15000),
                            'management_fee' => rand(800, 1500),
                            'maintenance_reserve' => rand(500, 1000),
                            'net_distributable' => 0,
                            'distribution_per_share' => 0,
                            'status' => 'distributed',
                            'distributed_at' => $distributionPeriod->addDays(5),
                        ]
                    );

                    // Calculate net distributable and per share
                    $netDistributable = $distribution->total_rental_income
                        - $distribution->management_fee
                        - $distribution->maintenance_reserve;

                    $distributionPerShare = $netDistributable / $property->total_shares;

                    $distribution->update([
                        'net_distributable' => $netDistributable,
                        'distribution_per_share' => $distributionPerShare,
                    ]);

                    // Create partner distribution
                    PartnerDistribution::create([
                        'partner_id' => $partner->id,
                        'investment_id' => $investment->id,
                        'distribution_id' => $distribution->id,
                        'shares_owned' => $sharesPurchased,
                        'distribution_amount' => $sharesPurchased * $distributionPerShare,
                        'payment_method' => ['bank_transfer', 'paypal', 'crypto'][rand(0, 2)],
                        'payment_status' => 'processed',
                        'payment_reference' => 'REF-'.strtoupper(substr(md5((string) rand()), 0, 10)),
                        'processed_at' => $distributionPeriod->addDays(7),
                    ]);
                }
            }
        }
    }
}
