<?php

declare(strict_types=1);

namespace MauticPlugin\DealFlowBundle\Migrations;

use Doctrine\DBAL\Schema\Schema;
use Mautic\IntegrationsBundle\Migration\AbstractMigration;
use MauticPlugin\DealFlowBundle\Entity\DealStage;

final class Version_0_4_0 extends AbstractMigration
{
    /**
     * @var array<string, int>
     */
    private const DEFAULT_PROBABILITIES = [
        'identified'  => 10,
        'prospect'    => 30,
        'opportunity' => 60,
        'closed-won'  => 100,
        'closed-lost' => 0,
    ];

    protected function isApplicable(Schema $schema): bool
    {
        $tableName = $this->concatPrefix(DealStage::TABLE_NAME);

        return $schema->hasTable($tableName) && !$schema->getTable($tableName)->hasColumn('probability');
    }

    protected function up(): void
    {
        $connection = $this->entityManager->getConnection();
        $tableName  = $this->concatPrefix(DealStage::TABLE_NAME);

        $connection->executeStatement(sprintf(
            'ALTER TABLE `%s` ADD `probability` INT NOT NULL DEFAULT 0',
            $tableName
        ));

        $stagesByPipeline = [];
        foreach ($connection->fetchAllAssociative(
            sprintf('SELECT id, pipeline_id, slug, stage_type FROM `%s` ORDER BY pipeline_id ASC, sort_order ASC, id ASC', $tableName)
        ) as $row) {
            $pipelineId = (int) $row['pipeline_id'];
            $stagesByPipeline[$pipelineId][] = $row;
        }

        foreach ($stagesByPipeline as $rows) {
            $openIndex = 0;

            foreach ($rows as $row) {
                $slug        = (string) $row['slug'];
                $stageType   = (string) $row['stage_type'];
                $probability = self::DEFAULT_PROBABILITIES[$slug] ?? null;

                if (null === $probability) {
                    $probability = match ($stageType) {
                        'won' => 100,
                        'lost' => 0,
                        default => min(90, 10 + ($openIndex * 20)),
                    };
                }

                if ('open' === $stageType) {
                    ++$openIndex;
                }

                $connection->update(
                    $tableName,
                    ['probability' => $probability],
                    ['id' => (int) $row['id']]
                );
            }
        }
    }
}
