<?php

namespace App\Console\Commands\Migrations;

use Illuminate\Support\Facades\DB;

class InitiativeResultPcrMigration extends BaseMigration
{
    protected string $oldTableName = 'sek_initiative_result_result_links';

    protected string $modelName = 'Initiative Result PCR Links';

    public function migrate(bool $dryRun = false, int $batchSize = 1000, int $startFrom = 0): void
    {
        $oldDb = DB::connection($this->connection);
        $this->processData($oldDb, $dryRun, $startFrom, $batchSize);
    }

    protected function getModelName(): string
    {
        return 'Initiative Result PCR Link';
    }

    protected function getModelClass(): string
    {
        return 'initiative_result_pcr'; // This is a pivot table, not a model
    }

    protected function createModel(array $data): void
    {
        // Insert into initiative_result_pcr table using raw DB query to preserve ID
        DB::table('initiative_result_pcr')->insert($data);
    }

    protected function processData($oldDb, bool $dryRun, int $startFrom, int $batchSize): void
    {
        $query = $oldDb->table($this->oldTableName)
            ->orderBy('id')
            ->offset($startFrom);

        $totalRecords = $oldDb->table($this->oldTableName)->count();
        $this->info("📊 Found {$totalRecords} initiative result PCR links to migrate");

        if ($totalRecords === 0) {
            $this->info('✅ No records to migrate');

            return;
        }

        $bar = $this->command->getOutput()->createProgressBar($totalRecords);
        $bar->start();

        $query->chunk($batchSize, function ($oldRecords) use ($dryRun, $bar) {
            foreach ($oldRecords as $oldRecord) {
                $bar->advance();

                $data = $this->mapData($oldRecord);

                if ($this->validateData($data)) {
                    try {
                        if (! $dryRun) {
                            $this->createModel($data);
                        }
                        $this->stats['migrated']++;
                        $this->info("✅ Created initiative result PCR link: {$data['id']} - IR {$data['initiative_result_id']} -> PCR {$data['performance_card_result_id']}");
                    } catch (\Exception $e) {
                        $this->stats['errors']++;
                        $this->error("❌ Error creating initiative result PCR link ID {$oldRecord->id}: {$e->getMessage()}");
                    }
                } else {
                    $this->stats['skipped']++;
                    $this->warn("⚠️  Skipped initiative result PCR link ID {$oldRecord->id} (validation failed)");
                }
            }
        });

        $bar->finish();
        $this->info('');  // Add newline
    }

    protected function mapData($oldRecord): array
    {
        return [
            'id' => $oldRecord->id,
            'initiative_result_id' => $oldRecord->initiative_result_id,
            'performance_card_result_id' => $oldRecord->result_id,
            'created_at' => $oldRecord->created_at,
            'updated_at' => $oldRecord->modified_at ?: $oldRecord->created_at, // Use created_at if modified_at is null
        ];
    }

    protected function validateData(array $data): bool
    {
        // Check if initiative result exists
        if (! DB::table('initiative_results')->where('id', $data['initiative_result_id'])->exists()) {
            $this->warn("⚠️  Initiative result with ID {$data['initiative_result_id']} does not exist");

            return false;
        }

        // Check if performance card result exists
        if (! DB::table('performance_card_results')->where('id', $data['performance_card_result_id'])->exists()) {
            $this->warn("⚠️  Performance card result with ID {$data['performance_card_result_id']} does not exist");

            return false;
        }

        // Check if link already exists
        $exists = DB::table('initiative_result_pcr')
            ->where('id', $data['id'])
            ->exists();

        if ($exists) {
            $this->warn("⚠️  Initiative result PCR link with ID {$data['id']} already exists");

            return false;
        }

        // Check for duplicate relationship (unique constraint)
        $duplicateRelation = DB::table('initiative_result_pcr')
            ->where('initiative_result_id', $data['initiative_result_id'])
            ->where('performance_card_result_id', $data['performance_card_result_id'])
            ->exists();

        if ($duplicateRelation) {
            $this->warn("⚠️  Relationship between Initiative Result {$data['initiative_result_id']} and Performance Card Result {$data['performance_card_result_id']} already exists");

            return false;
        }

        return true;
    }

    protected function getStatsSummary(): array
    {
        return [
            'Initiative-result-pcr-links' => [
                'Total' => $this->stats['total'] ?? 0,
                'Migrated' => $this->stats['migrated'] ?? 0,
                'Skipped' => $this->stats['skipped'] ?? 0,
                'Errors' => $this->stats['errors'] ?? 0,
            ],
        ];
    }
}
