<?php

namespace App\Console\Commands\Migrations;

use App\Models\Order;
use App\Models\SekayaValue;
use Illuminate\Support\Facades\DB;

class OrderDevelopmentImpactMigration extends BaseMigration
{
    protected string $oldTableName = 'sek_request_impact_reasons';

    protected string $modelName = 'Order Development Impacts';

    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 'Order Development Impact';
    }

    protected function getModelClass(): string
    {
        return 'Relationship';
    }

    protected function processData($oldDb, bool $dryRun = false, int $startFrom = 0, int $batchSize = 1000): void
    {
        $query = $oldDb->table($this->oldTableName)
            ->whereNotNull('request_id')
            ->whereNotNull('value_id')
            ->orderBy('request_id')
            ->orderBy('value_id');

        $totalCount = $query->count();
        $this->stats['total'] = $totalCount;

        $this->info("📊 Found {$totalCount} order development impact relationships to migrate");

        if ($totalCount === 0) {
            $this->warn('⚠️  No order development impact relationships found to migrate');

            return;
        }

        $processed = 0;
        $bar = $this->command->getOutput()->createProgressBar($totalCount);

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

                    try {
                        $relationshipData = $this->mapData($oldRecord);
                        if ($this->validateData($relationshipData)) {
                            if (! $dryRun) {
                                $this->createRelationship($oldRecord);
                            }
                            $this->stats['migrated']++;
                            $this->info("✅ Created order development impact relationship: Order ID {$oldRecord->request_id} -> SekayaValue ID {$oldRecord->value_id}");
                        } else {
                            $this->stats['skipped']++;
                            $this->warn("⚠️  Skipped order development impact relationship: Order ID {$oldRecord->request_id} -> SekayaValue ID {$oldRecord->value_id} (validation failed)");
                        }
                    } catch (\Exception $e) {
                        $this->stats['errors']++;
                        $this->error("❌ Error creating order development impact relationship for Order ID {$oldRecord->request_id} -> SekayaValue ID {$oldRecord->value_id}: {$e->getMessage()}");
                    }
                }
            });

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

    protected function validateData(array $data): bool
    {
        // Check if the order exists in the new system
        $orderExists = Order::where('id', $data['order_id'])->exists();
        if (! $orderExists) {
            $this->warn("⚠️  Order with ID {$data['order_id']} does not exist in new system");

            return false;
        }

        // Check if the sekaya value exists in the new system
        $sekayaValueExists = SekayaValue::where('id', $data['sekaya_value_id'])->exists();
        if (! $sekayaValueExists) {
            $this->warn("⚠️  SekayaValue with ID {$data['sekaya_value_id']} does not exist in new system");

            return false;
        }

        // Check if the relationship already exists
        $relationshipExists = DB::table('order_sekaya_value')
            ->where('order_id', $data['order_id'])
            ->where('sekaya_value_id', $data['sekaya_value_id'])
            ->exists();

        if ($relationshipExists) {
            $this->warn("⚠️  Relationship already exists: Order {$data['order_id']} -> SekayaValue {$data['sekaya_value_id']}");

            return false;
        }

        return true;
    }

    protected function createRelationship($oldRecord): void
    {
        // Use DB transaction for each relationship creation
        DB::transaction(function () use ($oldRecord) {
            // Create the relationship using raw database insertion
            // Note: order_sekaya_value is a pivot table without timestamps
            DB::table('order_sekaya_value')->insert([
                'order_id' => $oldRecord->request_id,
                'sekaya_value_id' => $oldRecord->value_id,
            ]);
        });
    }

    public function rollback(): void
    {
        $this->info('🔄 Rolling back Order Development Impact migration...');

        // Get the count before deletion for reporting
        $count = DB::table('order_sekaya_value')->count();

        // Delete all migrated relationships
        DB::table('order_sekaya_value')->truncate();

        $this->info("✅ Rolled back {$count} order development impact relationships");
    }

    protected function mapData($oldRecord): array
    {
        // This method is not used for relationship migrations
        // but included for interface compatibility
        return [
            'order_id' => $oldRecord->request_id,
            'sekaya_value_id' => $oldRecord->value_id,
        ];
    }

    protected function createModel(array $data): void
    {
        // This method is not used for relationship migrations
        // The actual creation is handled in createRelationship method
        // But we need to implement it to satisfy the BaseMigration interface
    }
}
