<?php

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Chill\Migrations\Activity;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

/**
 * Migrate schema to allow multiple or empty reasons on an activity.
 *
 * The relation between the activity and reason **was** oneToMany. After this
 * migration, the relation will be manyToMany.
 */
class Version20160222103457 extends AbstractMigration
{
    public function down(Schema $schema): void
    {
        $this->abortIf(
            'postgresql' !== $this->connection->getDatabasePlatform()->getName(),
            'Migration can only be executed safely on \'postgresql\'.'
        );

        $this->addSql('ALTER TABLE Activity ADD reason_id INT DEFAULT NULL');
        $this->addSql('ALTER TABLE Activity ADD CONSTRAINT '
                .'fk_55026b0c59bb1592 FOREIGN KEY (reason_id) '
                .'REFERENCES activityreason (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
        $this->addSql('CREATE INDEX idx_55026b0c59bb1592 ON Activity (reason_id)');

        // try to keep at least on activity reason...
        $this->addSql(
            'UPDATE activity
            SET reason_id=rid
            FROM (
                    SELECT activity_id AS aid, MIN(activityreason_id) AS rid
                    FROM activity_activityreason
                    GROUP BY activity_id ) AS sb
            WHERE sb.aid = activity.id'
        );

        $this->addSql('DROP TABLE activity_activityreason');
    }

    public function up(Schema $schema): void
    {
        $this->abortIf(
            'postgresql' !== $this->connection->getDatabasePlatform()->getName(),
            'Migration can only be executed safely on \'postgresql\'.'
        );

        // create the new table activity reason
        $this->addSql(
            'CREATE TABLE activity_activityreason ('
                .'activity_id INT NOT NULL, '
                .'activityreason_id INT NOT NULL, '
                .'PRIMARY KEY(activity_id, activityreason_id))'
        );
        $this->addSql('CREATE INDEX IDX_338A864381C06096 ON activity_activityreason (activity_id)');
        $this->addSql('CREATE INDEX IDX_338A8643D771E0FC ON activity_activityreason (activityreason_id)');
        $this->addSql('ALTER TABLE activity_activityreason '
                .'ADD CONSTRAINT FK_338A864381C06096 FOREIGN KEY (activity_id) '
                .'REFERENCES Activity (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
        $this->addSql('ALTER TABLE activity_activityreason '
                .'ADD CONSTRAINT FK_338A8643D771E0FC FOREIGN KEY (activityreason_id) '
                .'REFERENCES ActivityReason (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');

        // migrate old data to new table
        $this->addSql('INSERT INTO activity_activityreason (activity_id, activityreason_id) '
                .'SELECT id, reason_id FROM activity WHERE reason_id IS NOT NULL');

        // remove old column
        $this->addSql('ALTER TABLE activity DROP CONSTRAINT fk_55026b0c59bb1592');
        $this->addSql('DROP INDEX idx_55026b0c59bb1592');
        $this->addSql('ALTER TABLE activity DROP reason_id');
    }
}
