<?php
/**
 * Concord CRM - https://www.concordcrm.com
 *
 * @version   1.4.1
 *
 * @link      Releases - https://www.concordcrm.com/releases
 * @link      Terms Of Service - https://www.concordcrm.com/terms
 *
 * @copyright Copyright (c) 2022-2024 KONKORD DIGITAL
 */

namespace App\Installer;

use App\Installer\Events\InstallationSucceeded;
use Exception;
use Modules\Core\App\Database\Migrator;
use Modules\Core\App\Environment;
use Modules\Core\App\Facades\Innoclapps;

trait FinishesInstallation
{
    /**
     * Finalize the installation.
     *
     * @throws \App\Installer\FailedToFinalizeInstallationException
     */
    protected function finalizeInstallation($currency, $country): void
    {
        $event = new InstallationSucceeded([]);

        $this->createStorageLink($event);

        if ($this->markAsInstalled($event)) {
            settings([
                'currency' => $currency,
                'company_country_id' => $country,
            ]);

            event($event);

            Environment::capture();
        }

        $this->failWithErrorMessageIfFailing($event);

        Innoclapps::optimize();
    }

    /**
     * Mark the installation as installed.
     */
    protected function markAsInstalled(InstallationSucceeded $event): bool
    {
        $success = Innoclapps::markAsInstalled();

        if (! $success) {
            $event->addError('Failed to create the installed file. ('.Innoclapps::installedFileLocation().').');
        }

        return $success;
    }

    /**
     * Display any errors occured during the installation.
     *
     * @throws FailedToFinalizeInstallationException
     */
    protected function failWithErrorMessageIfFailing(InstallationSucceeded $event): void
    {
        if ($event->hasErrors()) {
            throw new FailedToFinalizeInstallationException(
                implode(PHP_EOL, $event->getErrors())
            );
        }
    }

    /**
     * Create the storage link.
     */
    protected function createStorageLink(InstallationSucceeded $event): void
    {
        try {
            Innoclapps::createStorageLink();
        } catch (Exception) {
            $event->addError('Failed to create storage symlink.');
        }
    }

    /**
     * Migrate the database.
     */
    protected function migrateDatabase(): void
    {
        app(Migrator::class)->run();
    }
}
