<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
use Mtc\MercuryDataModels\Enquiry;
use Mtc\MercuryDataModels\FormQuestion;

class MigrateEnquiryDetailsToAnswers extends Command
{
    protected $signature = 'enquiries:migrate-details-to-answers
        {--tenant= : Run for a specific tenant ID}
        {--dry-run : Preview changes without writing}';

    protected $description = 'Migrate enquiry details JSON to enquiry_answers table and encrypt sensitive fields';

    private int $migratedCount = 0;
    private int $skippedCount = 0;

    public function handle(): int
    {
        $tenantId = $this->option('tenant') ?: null;
        $isDryRun = $this->option('dry-run');

        if ($isDryRun) {
            $this->info('Running in dry-run mode — no changes will be made.');
        }

        tenancy()->runForMultiple($tenantId, function ($tenant) use ($isDryRun) {
            $this->info("Processing tenant: {$tenant->id}");
            $this->processTenant($isDryRun);
        });

        $this->newLine();
        $this->info("Completed. Migrated: {$this->migratedCount}, Skipped: {$this->skippedCount}");

        return self::SUCCESS;
    }

    private function processTenant(bool $isDryRun): void
    {
        $enquiryModel = Config::get('crm.enquiry_model', Enquiry::class);

        $query = $enquiryModel::query()
            ->whereNotNull('details')
            ->where('details', '!=', '[]')
            ->where('details', '!=', 'null');

        $total = $query->count();

        if ($total === 0) {
            $this->info('  No enquiries with details to migrate.');
            return;
        }

        $this->info("  Found {$total} enquiries to process.");
        $bar = $this->output->createProgressBar($total);

        $query->chunkById(100, function ($enquiries) use ($isDryRun, $bar) {
            foreach ($enquiries as $enquiry) {
                $this->processEnquiry($enquiry, $isDryRun);
                $bar->advance();
            }
        });

        $bar->finish();
        $this->newLine();
    }

    private function processEnquiry($enquiry, bool $isDryRun): void
    {
        $details = $enquiry->details;

        if (empty($details) || !is_array($details)) {
            $this->skippedCount++;
            return;
        }

        if (!$isDryRun) {
            DB::beginTransaction();
        }

        try {
            foreach ($details as $entry) {
                $questionId = $entry['id'] ?? null;

                if (!$questionId) {
                    continue;
                }

                // Skip if answer already exists for this enquiry+question
                $exists = $enquiry->answers()
                    ->where('question_id', $questionId)
                    ->exists();

                if ($exists) {
                    continue;
                }

                $question = FormQuestion::withTrashed()
                    ->find($questionId);

                $isSensitive = (bool) ($question?->is_sensitive ?? false);
                $answer = $entry['answer'] ?? null;
                $answerValue = is_array($answer) ? null : (string) ($answer ?? '');
                $answerArray = is_array($answer) ? $answer : null;

                $answerType = 'text';
                if ($question?->type === 'file_upload') {
                    $answerType = 'file';
                } elseif (is_array($answer)) {
                    $answerType = 'array';
                } elseif ($question && str_ends_with($question->type, '_id')) {
                    $answerType = $question->type;
                }

                if (!$isDryRun) {
                    $enquiry->answers()->create([
                        'question_id' => (int) $questionId,
                        'question_name' => $entry['question'] ?? $question?->name ?? '',
                        'answer_value' => $isSensitive && $answerValue
                            ? encrypt($answerValue)
                            : $answerValue,
                        'answer_array' => $answerArray,
                        'answer_type' => $answerType,
                        'sensitive_info' => $isSensitive,
                    ]);
                }
            }

            if (!$isDryRun) {
                $enquiry->update(['details' => null]);
                DB::commit();
            }

            $this->migratedCount++;
        } catch (\Exception $e) {
            if (!$isDryRun) {
                DB::rollBack();
            }

            $this->error("  Failed to migrate enquiry #{$enquiry->id}: {$e->getMessage()}");
            $this->skippedCount++;
        }
    }
}
