<?php

namespace Inside\DESK\Console;

use Inside\Console\Command;
use Inside\Content\Models\Contents\Forms;
use Inside\Form\Models\FormAnswer;
use Inside\Form\Models\FormSubmission;

class FixMissingFormAnswersCommand extends Command
{
    /**
     * @var string
     */
    protected $name = 'desk:fix-missing-form-answers';

    /*
   * @var string
   */
    protected $signature = 'desk:fix-missing-form-answers';

    /**
     * @var string
     */
    protected $description = 'Fix missing form answers';

    public function __construct()
    {
        parent::__construct();
    }

    public function handle(): void
    {
        FormSubmission::unsetEventDispatcher();
        FormAnswer::unsetEventDispatcher();

        $result = FormSubmission::query()
            ->selectRaw('GROUP_CONCAT(fs.id) as ids, GROUP_CONCAT(form_answers_counts.answers_count) as answers_counts')
            ->from('inside_forms_submissions as fs')
            ->leftJoinSub(
                FormAnswer::query()
                    ->selectRaw('submission_id, COUNT(id) as answers_count')
                    ->groupBy('submission_id'),
                'form_answers_counts',
                'fs.id',
                '=',
                'form_answers_counts.submission_id'
            )
            ->groupBy(['fs.user_uuid', 'fs.status', 'fs.created_at'])
            ->get();

        $alones = [];
        $incompletes = [];
        $empties = [];

        $result->chunk(20)->each(function ($submissions) use (&$alones, &$incompletes, &$empties) {
            $submissions->each(function ($submission) use (&$alones, &$incompletes, &$empties) {
                $ids = explode(',', $submission->ids);

                if (count($ids) === 1) {
                    $alones[] = $submission;
                } elseif ($submission->answers_counts === null) {
                    $empties[] = $submission;
                } elseif (!str_contains($submission->answers_counts, ',')) {
                    $incompletes[] = $submission;
                } else {
                    $answersCounts = explode(',', $submission->answers_counts ?? '');
                    if (count(array_unique($answersCounts)) > 1) {
                        $incompletes[] = $submission;
                    }
                }
            });
        });

        $this->info('Alones: ' . count($alones));
        $this->info('Incompletes: ' . count($incompletes));
        $this->info('Empties: ' . count($empties));

        foreach ($alones as $alone) {
            $ids = explode(',', $alone->ids);

            /** @var FormSubmission $submission */
            $submission = FormSubmission::query()->find($ids[0]);

            $form = $submission->answerable;

            $langcode = $form->langcode === 'en' ? 'fr' : 'en';

            $form = $form->getTranslationIfExists($langcode);

            if ($form->langcode !== $langcode) {
                $this->info('Skip alone ' . $submission->id . ' because no translation available for the form');
            }

            $formSubmission = FormSubmission::create([
                "answerable_uuid" => $form->uuid,
                "answerable_type" => Forms::class,
                "user_uuid" => $submission->user_uuid,
                "created_at" => date('Y-m-d H:i:s', $submission->created_at),
                "edited_at" => date('Y-m-d H:i:s', $submission->edited_at),
                "editor_uuid" => $submission->editor_uuid,
                "status" => $submission->status,
                "comment" => $submission->comment,
                "code" => $submission->code,
            ]);

            $formAnswers = FormAnswer::where('submission_id', $submission->id)->get()->map(
                fn (FormAnswer $formAnswer) => [
                    'field_id' => $formAnswer->field_id,
                    'answer' => $formAnswer->answer
                ]
            );

            $this->info('Fix alone ' . $submission->id . ', add ' . count($formAnswers) . ' answers to new submission ' . $formSubmission->id);

            $formSubmission->answers()->delete();
            $formSubmission->answers()->createMany($formAnswers);
            $formSubmission->save();
        }

        foreach ($incompletes as $incomplete) {
            [$original, $duplicate] = explode(',', $incomplete->ids);

            /** @var FormSubmission $originalSubmission */
            $originalSubmission = FormSubmission::query()->find($original);
            /** @var FormSubmission $duplicateSubmission */
            $duplicateSubmission = FormSubmission::query()->find($duplicate);

            $formAnswers = FormAnswer::where('submission_id', $originalSubmission->id)->get()->map(
                fn (FormAnswer $formAnswer) => [
                    'field_id' => $formAnswer->field_id,
                    'answer' => $formAnswer->answer
                ]
            );

            $this->info('Fix incomplete submissions ' . $duplicateSubmission->id . ', add ' . count($formAnswers) . ' answers');

            $duplicateSubmission->answers()->delete();
            $duplicateSubmission->answers()->createMany($formAnswers);
            $duplicateSubmission->save();
        }
    }
}
