<?php

namespace Database\Seeders;

use App\Models\Requirement;
use App\Models\NonFunctionalRequirement;
use App\Models\User;
use App\Models\UserOperationFinal;
use App\Models\Project;
use App\Services\IUSPACalculator;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;

class CalculateFinalWeightsSeeder extends Seeder
{
    private $targetProjectId = 1; // Change this to your specific project ID

    public function run(): void
    {
        $this->command->info("🚀 Starting i-USPA Final Weights Calculation...");
        $this->command->info("📋 Steps 7, 8, and 9: TFN, Alpha-Cut, and Stakeholder Aggregation");

        // Check if the target project exists
        $project = Project::find($this->targetProjectId);
        
        if (!$project) {
            $this->command->error("❌ Project with ID {$this->targetProjectId} not found");
            return;
        }

        $this->command->info("🎯 Target Project: {$project->name} (ID: {$project->id})");

        // Check if we have requirement operations with status 'done' for this project
        $operationCount = DB::table('requirement_operations')
            ->where('project_id', $this->targetProjectId)
            ->where('status', 'done')
            ->count();
        
        if ($operationCount === 0) {
            $this->command->error("❌ No requirement operations found with status 'done' for project {$this->targetProjectId}");
            $this->command->info("💡 Please run RequirementOperationSeeder first");
            return;
        }

        $this->command->info("📊 Found {$operationCount} requirement operations with status 'done'");

        // Check if we have stakeholder weights
        $stakeholderCount = UserOperationFinal::count();
        $this->command->info("👥 Found {$stakeholderCount} stakeholder weight records");

        // Initialize calculator
        $calculator = new IUSPACalculator();

        try {
            // Validate that all votes are done for this project
            $requirements = Requirement::with('nonFunctionalRequirements')
                ->where('project_id', $this->targetProjectId)
                ->get();

            $totalExpectedVotes = $requirements->sum(function ($fu) {
                return $fu->nonFunctionalRequirements->count();
            });

            if ($operationCount < $totalExpectedVotes) {
                $this->command->error("❌ Not all votes are completed for project {$this->targetProjectId}");
                $this->command->info("💡 Expected: {$totalExpectedVotes}, Submitted: {$operationCount}");
                return;
            }

            // Perform calculation for the specific project
            $results = $calculator->calculateFinalWeightsForProject($this->targetProjectId);

            // Update database with final weights
            $calculator->updateDatabaseWeights($results['step9']);

            // Display results
            $this->displayResults($project, $results, $calculator->getStakeholderWeights());

            $this->command->info("✅ i-USPA Final Weights Calculation completed successfully!");
            $this->command->info("📈 Database updated with final weights for Project {$project->name}");

        } catch (\Exception $e) {
            $this->command->error("❌ Error during calculation: " . $e->getMessage());
            $this->command->error("📋 Stack trace: " . $e->getTraceAsString());
        }
    }

    private function displayResults($project, $results, $stakeholderWeights)
    {
        $finalFUWeights = $results['step9']['final_fu_weights'];
        $finalNFRWeights = $results['step9']['final_nfr_weights'];

        $this->command->info("\n🎯 FINAL REQUIREMENTS (FUs) RANKING for {$project->name}:");
        $this->command->info(str_repeat("-", 60));
        
        $rank = 1;
        foreach ($finalFUWeights as $rId => $weight) {
            $requirement = Requirement::find($rId);
            $name = $requirement ? $requirement->name : "Requirement {$rId}";
            $this->command->info(sprintf("Rank %2d: %s (ID: %d) - Weight: %.4f", 
                $rank, $name, $rId, $weight));
            $rank++;
        }

        $this->command->info("\n🎯 FINAL NON-FUNCTIONAL REQUIREMENTS (NFRs) RANKING:");
        $this->command->info(str_repeat("-", 60));
        
        $rank = 1;
        foreach ($finalNFRWeights as $nfrId => $weight) {
            $nfr = NonFunctionalRequirement::find($nfrId);
            $name = $nfr ? $nfr->name : "NFR {$nfrId}";
            $this->command->info(sprintf("Rank %2d: %s (ID: %d) - Weight: %.4f", 
                $rank, $name, $nfrId, $weight));
            $rank++;
        }

        // Display stakeholder weights from database
        $this->command->info("\n👥 STAKEHOLDER WEIGHTS (from user_operation_finals):");
        $this->command->info(str_repeat("-", 50));
        
        foreach ($stakeholderWeights as $userId => $weight) {
            $user = User::find($userId);
            $userName = $user ? $user->name : "User {$userId}";
            $this->command->info(sprintf("%s (ID: %d): %.4f", $userName, $userId, $weight));
        }

        // Display calculation parameters
        $this->command->info("\n⚙️  CALCULATION PARAMETERS:");
        $this->command->info(str_repeat("-", 30));
        $this->command->info("Alpha (α): 0.5");
        $this->command->info("Beta (β): 0.5");
        $this->command->info("Total stakeholders: " . count($stakeholderWeights));
    }
}