<?php

namespace App\Console\Commands\Migrations;

use App\Models\Order;
use App\Models\OrderRequirement;
use App\Models\User;
use Illuminate\Support\Facades\DB;

class OrderRequirementMigration extends BaseMigration
{
    protected string $oldTableName = 'sek_requirements';

    protected string $modelName = 'Order Requirements';

    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 Requirements';
    }

    protected function getModelClass(): string
    {
        return 'App\\Models\\OrderRequirement';
    }

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

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

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

        if ($totalCount === 0) {
            $this->warn('⚠️  No order requirements 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) {
                    try {
                        $mappedData = $this->mapData($oldRecord);

                        if ($this->validateData($mappedData)) {
                            if (! $dryRun) {
                                $this->createModel($mappedData);
                                $this->stats['migrated']++;
                            } else {
                                $this->info("🔍 [DRY RUN] Would migrate requirement: {$mappedData['name']} for order {$mappedData['order_id']} - {$mappedData['status']}");
                            }
                        } else {
                            $this->stats['skipped']++;
                        }
                    } catch (\Exception $e) {
                        $this->stats['errors']++;
                        $requirementId = $oldRecord->id ?? 'unknown';
                        $this->error("❌ Error migrating requirement ID {$requirementId}: ".$e->getMessage());
                    }

                    $processed++;
                    $bar->advance();
                }
            });

        $bar->finish();
        $this->command->info('');
    }

    protected function mapData(object $oldRecord): array
    {
        return [
            'name' => $oldRecord->requirement_name ?? 'Unknown Requirement', // Note: typo in old DB field name
            'status' => $this->mapRequirementStatus($oldRecord->status ?? 'PENDING'),
            'order_id' => ! empty($oldRecord->request_id) ? (int) $oldRecord->request_id : null,
            'created_by' => $this->mapUserId($oldRecord->created_by ?? null),
            'created_at' => $this->parseDateTime($oldRecord->created_at ?? $oldRecord->uploaded_datetime),
            'updated_at' => $this->parseDateTime($oldRecord->modified_at ?? $oldRecord->created_at ?? $oldRecord->uploaded_datetime),

            // Store old record data for reference
            'old_record' => $oldRecord,
        ];
    }

    protected function validateData(array $data): bool
    {
        // Must have order_id and it must exist
        if (empty($data['order_id'])) {
            $this->warn('⚠️  Skipping requirement: missing order_id');

            return false;
        }

        // Check if the order exists
        if (! Order::find($data['order_id'])) {
            $this->warn("⚠️  Skipping requirement: Order {$data['order_id']} not found");

            return false;
        }

        // Must have a name
        if (empty($data['name'])) {
            $this->warn("⚠️  Skipping requirement for order {$data['order_id']}: missing name");

            return false;
        }

        return true;
    }

    protected function createModel(array $data): void
    {
        $oldRecord = $data['old_record'];
        unset($data['old_record']);

        // Create the order requirement
        $orderRequirement = OrderRequirement::create($data);

        // Log activity for status if it's not pending
        if ($data['status'] !== OrderRequirement::STATUS_PENDING) {
            $this->createActivityLog($orderRequirement, $oldRecord);
        }

        $this->info("📝 Migrated requirement '{$orderRequirement->name}' for order {$orderRequirement->order_id} - {$orderRequirement->status}");
    }

    private function createActivityLog(OrderRequirement $orderRequirement, object $oldRecord): void
    {
        $action = strtolower($orderRequirement->status);
        $eventMap = [
            OrderRequirement::STATUS_ACCEPTED => 'accepted',
            OrderRequirement::STATUS_REJECTED => 'rejected',
            OrderRequirement::STATUS_ASK_MODIFICATION => 'ask_modification',
        ];

        $event = $eventMap[$orderRequirement->status] ?? $action;
        $causerId = null;

        // Try to determine who performed the action based on modified_by or created_by
        if (! empty($oldRecord->modified_by)) {
            $causerId = $this->mapUserId($oldRecord->modified_by);
        } elseif (! empty($oldRecord->created_by)) {
            $causerId = $this->mapUserId($oldRecord->created_by);
        }

        if (empty($causerId)) {
            return; // Can't create activity log without a causer
        }

        $activityDateTime = $this->parseDateTime($oldRecord->modified_at ?? $oldRecord->created_at ?? $oldRecord->uploaded_datetime);
        if (! $activityDateTime) {
            return; // Can't create activity log without a timestamp
        }

        DB::table('activity_log')->insert([
            'log_name' => 'order_requirement',
            'description' => "Order requirement {$action}",
            'subject_type' => 'App\\Models\\OrderRequirement',
            'subject_id' => $orderRequirement->getKey(),
            'causer_type' => 'App\\Models\\User',
            'causer_id' => $causerId,
            'properties' => json_encode([
                'old_status' => OrderRequirement::STATUS_PENDING,
                'new_status' => $orderRequirement->status,
                'action' => $action,
                'migrated_from_old_system' => true,
            ]),
            'event' => $event,
            'batch_uuid' => null,
            'created_at' => $activityDateTime,
            'updated_at' => $activityDateTime,
        ]);

        $this->info("📋 Created activity log for requirement {$orderRequirement->getKey()}");
    }

    private function mapRequirementStatus(string $oldStatus): string
    {
        $statusMap = [
            'PENDING' => OrderRequirement::STATUS_PENDING,
            'ACCEPTED' => OrderRequirement::STATUS_ACCEPTED,
            'REJECTED' => OrderRequirement::STATUS_REJECTED,
            'ASK_MODIFICATION' => OrderRequirement::STATUS_ASK_MODIFICATION,
        ];

        return $statusMap[$oldStatus] ?? OrderRequirement::STATUS_PENDING;
    }

    private function mapUserId(?int $oldUserId): ?int
    {
        if (empty($oldUserId)) {
            return null;
        }

        $user = User::find($oldUserId);

        return $user ? $user->getKey() : null;
    }
}
