<?php

namespace App\Console\Commands;

use App\Models\Association;
use App\Models\Order;
use App\Models\ResidentialGathering;
use App\Models\StationLicense;
use App\Models\WellLicense;
use Illuminate\Console\Command;

class LinkResidentialGatheringsCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'residential:link
                            {--dry-run : Preview changes without applying them}
                            {--orders : Link only orders}
                            {--associations : Link only associations}
                            {--well-licenses : Link only well licenses}
                            {--station-licenses : Link only station licenses}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Link residential gatherings to orders, associations, and licenses based on their center_id';

    /**
     * Execute the console command.
     */
    public function handle(): int
    {
        $isDryRun = $this->option('dry-run');
        $linkOrders = $this->option('orders');
        $linkAssociations = $this->option('associations');
        $linkWellLicenses = $this->option('well-licenses');
        $linkStationLicenses = $this->option('station-licenses');

        // If no specific option is set, link all
        $linkAll = ! ($linkOrders || $linkAssociations || $linkWellLicenses || $linkStationLicenses);

        if ($isDryRun) {
            $this->warn('🔍 DRY RUN MODE - No changes will be made');
            $this->newLine();
        }

        $stats = [
            'orders' => ['linked' => 0, 'skipped' => 0],
            'associations' => ['linked' => 0, 'skipped' => 0],
            'well_licenses' => ['linked' => 0, 'skipped' => 0],
            'station_licenses' => ['linked' => 0, 'skipped' => 0],
        ];

        if ($linkAll || $linkOrders) {
            $this->info('📦 Linking Orders to Residential Gatherings...');
            $stats['orders'] = $this->linkOrders($isDryRun);
            $this->newLine();
        }

        if ($linkAll || $linkAssociations) {
            $this->info('🏢 Linking Associations to Residential Gatherings...');
            $stats['associations'] = $this->linkAssociations($isDryRun);
            $this->newLine();
        }

        if ($linkAll || $linkWellLicenses) {
            $this->info('🚰 Linking Well Licenses to Residential Gatherings...');
            $stats['well_licenses'] = $this->linkWellLicenses($isDryRun);
            $this->newLine();
        }

        if ($linkAll || $linkStationLicenses) {
            $this->info('🏭 Linking Station Licenses to Residential Gatherings...');
            $stats['station_licenses'] = $this->linkStationLicenses($isDryRun);
            $this->newLine();
        }

        $this->displaySummary($stats, $isDryRun);

        return Command::SUCCESS;
    }

    /**
     * Link orders to residential gatherings based on center_id
     */
    protected function linkOrders(bool $isDryRun): array
    {
        $linked = 0;
        $skipped = 0;

        // Get all orders that have a center relationship through center_order pivot
        $orders = Order::with('centers')->get();

        $progressBar = $this->output->createProgressBar($orders->count());
        $progressBar->start();

        foreach ($orders as $order) {
            foreach ($order->centers as $center) {
                // Get all residential gatherings for this center
                $residentialGatherings = ResidentialGathering::where('center_id', $center->id)->get();

                if ($residentialGatherings->isEmpty()) {
                    $skipped++;

                    continue;
                }

                if (! $isDryRun) {
                    // Get IDs of residential gatherings to attach
                    $rgIds = $residentialGatherings->pluck('id')->toArray();

                    // Sync without detaching existing ones
                    $order->residentialGatherings()->syncWithoutDetaching($rgIds);
                }

                $linked += $residentialGatherings->count();
            }

            $progressBar->advance();
        }

        $progressBar->finish();
        $this->newLine();

        return ['linked' => $linked, 'skipped' => $skipped];
    }

    /**
     * Link associations to residential gatherings based on center_id
     */
    protected function linkAssociations(bool $isDryRun): array
    {
        $linked = 0;
        $skipped = 0;

        // Get all associations that have a center relationship through association_center pivot
        $associations = Association::with('centers')->get();

        $progressBar = $this->output->createProgressBar($associations->count());
        $progressBar->start();

        foreach ($associations as $association) {
            foreach ($association->centers as $center) {
                // Get all residential gatherings for this center
                $residentialGatherings = ResidentialGathering::where('center_id', $center->id)->get();

                if ($residentialGatherings->isEmpty()) {
                    $skipped++;

                    continue;
                }

                if (! $isDryRun) {
                    // Get IDs of residential gatherings to attach
                    $rgIds = $residentialGatherings->pluck('id')->toArray();

                    // Sync without detaching existing ones
                    $association->residentialGatherings()->syncWithoutDetaching($rgIds);
                }

                $linked += $residentialGatherings->count();
            }

            $progressBar->advance();
        }

        $progressBar->finish();
        $this->newLine();

        return ['linked' => $linked, 'skipped' => $skipped];
    }

    /**
     * Link well licenses to residential gatherings based on center_id
     */
    protected function linkWellLicenses(bool $isDryRun): array
    {
        $linked = 0;
        $skipped = 0;

        $wellLicenses = WellLicense::with('center')->get();

        $progressBar = $this->output->createProgressBar($wellLicenses->count());
        $progressBar->start();

        foreach ($wellLicenses as $wellLicense) {
            if (! $wellLicense->center_id) {
                $skipped++;
                $progressBar->advance();

                continue;
            }

            // Get all residential gatherings for this center
            $residentialGatherings = ResidentialGathering::where('center_id', $wellLicense->center_id)->get();

            if ($residentialGatherings->isEmpty()) {
                $skipped++;
                $progressBar->advance();

                continue;
            }

            if (! $isDryRun) {
                // Get IDs of residential gatherings to attach
                $rgIds = $residentialGatherings->pluck('id')->toArray();

                // Sync without detaching existing ones
                $wellLicense->residentialGatherings()->syncWithoutDetaching($rgIds);
            }

            $linked += $residentialGatherings->count();
            $progressBar->advance();
        }

        $progressBar->finish();
        $this->newLine();

        return ['linked' => $linked, 'skipped' => $skipped];
    }

    /**
     * Link station licenses to residential gatherings based on center_id
     */
    protected function linkStationLicenses(bool $isDryRun): array
    {
        $linked = 0;
        $skipped = 0;

        $stationLicenses = StationLicense::with('center')->get();

        $progressBar = $this->output->createProgressBar($stationLicenses->count());
        $progressBar->start();

        foreach ($stationLicenses as $stationLicense) {
            if (! $stationLicense->center_id) {
                $skipped++;
                $progressBar->advance();

                continue;
            }

            // Get all residential gatherings for this center
            $residentialGatherings = ResidentialGathering::where('center_id', $stationLicense->center_id)->get();

            if ($residentialGatherings->isEmpty()) {
                $skipped++;
                $progressBar->advance();

                continue;
            }

            if (! $isDryRun) {
                // Get IDs of residential gatherings to attach
                $rgIds = $residentialGatherings->pluck('id')->toArray();

                // Sync without detaching existing ones
                $stationLicense->residentialGatherings()->syncWithoutDetaching($rgIds);
            }

            $linked += $residentialGatherings->count();
            $progressBar->advance();
        }

        $progressBar->finish();
        $this->newLine();

        return ['linked' => $linked, 'skipped' => $skipped];
    }

    /**
     * Display summary of linking operations
     */
    protected function displaySummary(array $stats, bool $isDryRun): void
    {
        $this->newLine();
        $this->line(str_repeat('═', 70));
        $this->line('          '.($isDryRun ? 'DRY RUN ' : '').'Link Summary');
        $this->line(str_repeat('═', 70));

        foreach ($stats as $model => $data) {
            $modelName = str_replace('_', ' ', ucwords($model, '_'));
            $this->line(sprintf(
                '%-30s ✓ Linked: %5d | ⊗ Skipped: %5d',
                $modelName.':',
                $data['linked'],
                $data['skipped']
            ));
        }

        $totalLinked = array_sum(array_column($stats, 'linked'));
        $totalSkipped = array_sum(array_column($stats, 'skipped'));

        $this->line(str_repeat('─', 70));
        $this->line(sprintf(
            '%-30s ✓ Linked: %5d | ⊗ Skipped: %5d',
            'TOTAL:',
            $totalLinked,
            $totalSkipped
        ));
        $this->line(str_repeat('═', 70));

        if ($isDryRun) {
            $this->newLine();
            $this->warn('⚠️  This was a dry run. Run without --dry-run to apply changes.');
        }
    }
}
