<?php

namespace App\Services\Care;

use App\Models\AssessmentTemplate;
use App\Models\ClinicalPathway;
use App\Models\Organization;
use Database\Seeders\AssessmentTemplateSeeder;
use Database\Seeders\ClinicalPathwaySeeder;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Schema;
use Throwable;

/**
 * Product rollout flags stored under organization settings.rollout.*
 * Distinct from PlanService entitlements (lab/pharmacy/billing plan features).
 */
class CareFeatures
{
    public const ASSESSMENTS_ENGINE = 'assessments_engine';

    public const PATHWAY_SUGGESTIONS = 'pathway_suggestions';

    public const ASSESSMENT_REQUIRED_ON_COMPLETE = 'assessment_required_on_complete';

    /** Workflow-centric patient journey + financial gates (opt-in). */
    public const WORKFLOW_ENGINE = 'workflow_engine';

    /** Enforce financial gates (block gated stages until obligations clear). */
    public const FINANCIAL_GATES = 'financial_gates';

    /**
     * Flags that default ON when unset (opt-out). Others default OFF (opt-in).
     *
     * @var list<string>
     */
    protected array $defaultOn = [
        self::ASSESSMENTS_ENGINE,
    ];

    public function enabled(Organization $organization, string $flag): bool
    {
        $settings = $organization->settings ?? [];
        $rollout = is_array($settings['rollout'] ?? null) ? $settings['rollout'] : [];

        if (array_key_exists($flag, $rollout)) {
            return (bool) $rollout[$flag];
        }

        return in_array($flag, $this->defaultOn, true);
    }

    /**
     * @param  array<string, mixed>  $flags
     */
    public function setFlags(Organization $organization, array $flags): Organization
    {
        $settings = $organization->settings ?? [];
        $rollout = is_array($settings['rollout'] ?? null) ? $settings['rollout'] : [];
        $settings['rollout'] = array_merge($rollout, $flags);
        $organization->settings = $settings;
        $organization->save();

        return $organization->fresh();
    }

    /**
     * Ensure platform assessment/pathway catalog exists (idempotent seed).
     * Call when the engine is enabled so consult/patient UI has templates.
     * Never throws — web requests must not 500 if catalog seed races with live answers.
     */
    public function ensureAssessmentCatalog(): void
    {
        try {
            $this->seedAssessmentCatalogIfNeeded();
        } catch (Throwable $e) {
            Log::warning('ensureAssessmentCatalog failed', [
                'message' => $e->getMessage(),
                'exception' => $e::class,
            ]);
        }
    }

    protected function seedAssessmentCatalogIfNeeded(): void
    {
        if (! Schema::hasTable('care_assessment_templates')) {
            return;
        }

        $nursingCodes = ['news2', 'braden', 'morse', 'pain_nrs'];
        $haveNursing = AssessmentTemplate::query()
            ->whereNull('organization_id')
            ->whereIn('code', $nursingCodes)
            ->where('is_current', true)
            ->count();

        $empty = ! AssessmentTemplate::query()->whereNull('organization_id')->exists();

        if ($empty || $haveNursing < count($nursingCodes)) {
            Artisan::call('db:seed', [
                '--class' => AssessmentTemplateSeeder::class,
                '--force' => true,
            ]);
        }

        if (Schema::hasTable('care_clinical_pathways')
            && ! ClinicalPathway::query()->whereNull('organization_id')->exists()) {
            Artisan::call('db:seed', [
                '--class' => ClinicalPathwaySeeder::class,
                '--force' => true,
            ]);
        }
    }
}
