<?php

namespace Modules\MedRegistry\Http\Controllers;

use Illuminate\Http\Request;
use Modules\MedRegistry\Entities\MedregBusinessType;
use Modules\MedRegistry\Entities\MedregModule;
use Modules\MedRegistry\Entities\MedregTenantSetup;
use Modules\MedRegistry\Services\ModuleLifecycleService;
use Modules\MedRegistry\Services\PresetService;

/**
 * P1-T6 — System Setup Wizard (Specs "System Setup Wizard (UI Flow)"):
 *   Step 1 GET  /med-setup          — choose business type (10 cards + Custom)
 *   Step 2 POST /med-setup/type → GET /med-setup/modules — confirm modules
 *          (defaults pre-checked & locked, optional toggleable; Custom = full
 *          medical catalog multi-select)
 *   Step 3 POST /med-setup/apply    — PresetService::apply → result report
 *
 * Gate: admin-only (ModuleUtil::is_admin) + `medreg_module` subscription.
 */
class SetupWizardController extends MedRegistryBaseController
{
    const SESSION_TYPE = 'medreg_wizard_type';

    /** @var PresetService */
    protected $presets;

    /** @var ModuleLifecycleService */
    protected $lifecycle;

    public function __construct(PresetService $presets, ModuleLifecycleService $lifecycle)
    {
        parent::__construct();
        $this->presets = $presets;
        $this->lifecycle = $lifecycle;
    }

    /** Step 1 — "What type of facility are you setting up?" */
    public function step1()
    {
        $this->guardAdmin();
        $this->guardSubscription();

        $types = MedregBusinessType::where('is_active', true)
            ->orderBy('sort_order')
            ->get();

        $setup = MedregTenantSetup::where('business_id', $this->businessId())->first();

        return view('medregistry::wizard.step1', [
            'types' => $types,
            'setup' => $setup,
        ]);
    }

    /** Step 1 → 2 — store the chosen type, redirect to confirmation. */
    public function chooseType(Request $request)
    {
        $this->guardAdmin();
        $this->guardSubscription();

        $data = $this->validate($request, [
            'type_key' => 'required|string|max:60',
        ]);

        $type = MedregBusinessType::where('type_key', $data['type_key'])
            ->where('is_active', true)
            ->firstOrFail();

        $request->session()->put(self::SESSION_TYPE, $type->type_key);

        return redirect()->route('medreg.wizard.step2');
    }

    /** Step 2 — pre-selected modules shown for confirmation. */
    public function step2(Request $request)
    {
        $this->guardAdmin();
        $this->guardSubscription();

        $typeKey = $request->session()->get(self::SESSION_TYPE);
        if (empty($typeKey)) {
            return redirect()->route('medreg.wizard.step1');
        }

        $type = MedregBusinessType::where('type_key', $typeKey)->where('is_active', true)->first();
        if (! $type) {
            return redirect()->route('medreg.wizard.step1');
        }

        $defaults = $type->default_modules ?: [];
        $optional = $type->optional_modules ?: [];

        // Resolution preview per default spec_key: which host modules serve it
        // (or empty = will be reported as skipped_missing).
        $resolution = [];
        foreach ($this->presets->expandMetaKeys($defaults) as $specKey) {
            $resolution[$specKey] = $this->lifecycle->resolveAllPresent($specKey)->pluck('module_key')->all();
        }

        // Concrete optional keys (minus meta placeholders).
        $optionalKeys = array_values(array_filter($optional, function ($key) {
            return $key !== MedregBusinessType::META_ALL_SPECIALTIES
                && $key !== MedregBusinessType::META_ONE_SPECIALTY;
        }));

        // Specialty choices when the preset allows them (or Custom).
        $specialties = collect();
        $specialtyMode = null; // 'multi' | 'single'
        if (in_array(MedregBusinessType::META_ALL_SPECIALTIES, $optional, true)) {
            $specialtyMode = 'multi';
        } elseif (in_array(MedregBusinessType::META_ONE_SPECIALTY, $optional, true)) {
            $specialtyMode = 'single';
        }
        if ($specialtyMode || $type->isCustom()) {
            $specialties = MedregModule::where('category', 'specialty')
                ->where('is_present', true)
                ->whereNotNull('spec_key')
                ->orderBy('module_key')
                ->get();
        }

        // Custom = full medical catalog multi-select.
        $catalog = collect();
        if ($type->isCustom()) {
            $catalog = MedregModule::whereIn('category', MedregModule::MEDICAL_CATEGORIES)
                ->where('is_present', true)
                ->orderByRaw("FIELD(category, 'medical', 'facility', 'specialty')")
                ->orderBy('sort_order')
                ->orderBy('module_key')
                ->get();
        }

        return view('medregistry::wizard.step2', [
            'type'          => $type,
            'defaults'      => $defaults,
            'resolution'    => $resolution,
            'optionalKeys'  => $optionalKeys,
            'specialties'   => $specialties,
            'specialtyMode' => $specialtyMode,
            'catalog'       => $catalog,
        ]);
    }

    /** Step 3 — Confirm & Install → PresetService → result screen. */
    public function apply(Request $request)
    {
        $this->guardAdmin();
        $this->guardSubscription();

        $typeKey = $request->session()->get(self::SESSION_TYPE);
        if (empty($typeKey)) {
            return redirect()->route('medreg.wizard.step1');
        }

        $selected = (array) $request->input('selected', []);
        $selected = array_values(array_filter(array_map('strval', $selected)));

        try {
            $report = $this->presets->apply(
                $this->businessId(),
                $typeKey,
                $selected,
                $this->userId()
            );
        } catch (\InvalidArgumentException $e) {
            return redirect()->route('medreg.wizard.step1')
                ->with('status', $this->fail($e->getMessage()));
        }

        $request->session()->forget(self::SESSION_TYPE);

        $type = MedregBusinessType::where('type_key', $typeKey)->first();

        return view('medregistry::wizard.result', [
            'type'   => $type,
            'report' => $report,
        ]);
    }
}
