<?php

namespace App\Http\Controllers;

use App\Models\MexcoOrganisation;
use App\Models\MexcoPlan;
use App\Services\CampusService;
use App\Services\CustomerAuthService;
use App\Services\CheckoutService;
use App\Services\DemoService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Illuminate\View\View;

class MexcoPortalAuthController extends Controller
{
    public function __construct(
        private CustomerAuthService $auth,
        private CheckoutService $checkout,
        private DemoService $demo,
        private CampusService $campus,
    ) {}

    public function showLogin(): View|RedirectResponse
    {
        if (session('mexco_portal_authenticated')) {
            return redirect()->route('mexco.portal.dashboard');
        }

        return view('portal.auth.login');
    }

    public function login(Request $request): RedirectResponse
    {
        $data = $request->validate([
            'email' => 'required|email',
            'password' => 'required|string',
        ]);

        try {
            $user = $this->auth->attempt($data['email'], $data['password']);
        } catch (ValidationException $e) {
            return back()->withInput()->with('error', collect($e->errors())->flatten()->first() ?: 'Unable to sign in.');
        }

        if (! $user) {
            return back()->withInput()->with('error', 'Invalid email or password.');
        }

        $this->auth->loginSession($request, $user);

        $planCode = $request->session()->get('mexco_selected_plan_code');
        if ($planCode === 'demo') {
            $request->session()->forget('mexco_selected_plan_code');
            if ($this->demo->canStart($user)) {
                $demo = $this->demo->start($user);

                return redirect()->route('mexco.portal.dashboard')
                    ->with('success', 'Welcome back. Your demo event “'.$demo['event']->name.'” is ready.')
                    ->with('demo_organiser_username', $demo['event']->organiser_username)
                    ->with('demo_organiser_password', $demo['organiser_password']);
            }

            return redirect()->route('mexco.portal.dashboard')
                ->with('success', 'Welcome back.');
        }

        if ($planCode === 'campus') {
            $request->session()->forget('mexco_selected_plan_code');

            return redirect()->route('mexco.portal.campus.apply')
                ->with('success', 'Welcome back. Submit your Campus Plan application for review.');
        }

        if ($planCode) {
            $plan = MexcoPlan::query()->where('code', $planCode)->where('is_active', true)->first();
            if ($plan && ! $plan->is_custom_pricing && ! in_array($plan->code, ['campus', 'demo'], true)) {
                $order = $this->checkout->startOrder($plan, $user);
                $request->session()->put('mexco_checkout_order_id', $order->id);

                return redirect()->route('mexco.checkout.event')
                    ->with('success', 'Welcome back. Continue creating your event.');
            }
        }

        return redirect()->route('mexco.portal.dashboard')
            ->with('success', 'Welcome to My MeXCo.');
    }

    public function showRegister(Request $request): View|RedirectResponse
    {
        if (session('mexco_portal_authenticated')) {
            $planCode = $request->query('plan') ?: $request->session()->get('mexco_selected_plan_code');
            if ($planCode === 'demo') {
                return redirect()->route('mexco.portal.demo.start');
            }
            if ($planCode === 'campus') {
                return redirect()->route('mexco.portal.campus.apply');
            }
            if ($planCode) {
                return redirect()->route('mexco.checkout.start', ['plan' => $planCode]);
            }

            return redirect()->route('mexco.portal.dashboard');
        }

        $planCode = $request->query('plan') ?: $request->session()->get('mexco_selected_plan_code');
        $plan = $planCode
            ? MexcoPlan::query()->where('code', $planCode)->where('is_active', true)->first()
            : null;

        if ($planCode) {
            $request->session()->put('mexco_selected_plan_code', $planCode);
        }

        return view('portal.auth.register', [
            'plan' => $plan,
            'orgTypes' => MexcoOrganisation::types(),
        ]);
    }

    public function register(Request $request): RedirectResponse
    {
        $planCode = $request->input('plan') ?: $request->session()->get('mexco_selected_plan_code');
        $isCampus = $planCode === 'campus';

        $rules = [
            'name' => 'required|string|max:255',
            'email' => 'required|email|max:255',
            'phone' => $isCampus ? 'required|string|max:50' : 'nullable|string|max:50',
            'password' => 'required|string|min:8|confirmed',
            'organisation_name' => 'required|string|max:255',
            'organisation_type' => 'required|string|in:'.implode(',', array_keys(MexcoOrganisation::types())),
            'plan' => 'nullable|string|exists:mexco_plans,code',
        ];

        if ($isCampus) {
            $rules = array_merge($rules, [
                'faculty' => 'required|string|max:255',
                'student_organisation' => 'required|string|max:255',
                'event_name' => 'required|string|max:255',
                'event_date' => 'required|date|after_or_equal:today',
                'expected_participants' => 'required|integer|min:1|max:100000',
                'sessions_count' => 'required|integer|min:0|max:10000',
                'booths_count' => 'required|integer|min:0|max:10000',
                'event_objective' => 'required|string|max:5000',
                'promotional_exposure' => 'required|string|max:5000',
                'sponsorship_letter' => 'required|file|mimes:pdf,doc,docx,jpg,jpeg,png|max:10240',
            ]);
        }

        $data = $request->validate($rules);

        if ($isCampus) {
            $data['organisation_status'] = 'pending';
            $data['user_status'] = 'pending';
        }

        $user = $this->auth->register($data);

        $planCode = $data['plan'] ?? $request->session()->get('mexco_selected_plan_code');
        $request->session()->forget('mexco_selected_plan_code');

        if ($planCode === 'campus') {
            $letter = $request->file('sponsorship_letter');
            $letterPath = $letter->store('campus/sponsorship-letters', 'local');

            $application = $this->campus->submitForOrganisationUser($user->loadMissing('organisation'), [
                'institution' => $data['organisation_name'],
                'faculty' => $data['faculty'],
                'student_organisation' => $data['student_organisation'],
                'event_name' => $data['event_name'],
                'event_date' => $data['event_date'],
                'expected_participants' => $data['expected_participants'],
                'sessions_count' => $data['sessions_count'],
                'booths_count' => $data['booths_count'],
                'event_objective' => $data['event_objective'],
                'promotional_exposure' => $data['promotional_exposure'],
                'contact_person' => $data['name'],
                'contact_email' => $data['email'],
                'applicant_phone' => $data['phone'],
                'sponsorship_letter_path' => $letterPath,
                'sponsorship_letter_name' => $letter->getClientOriginalName(),
            ]);

            return redirect()->route('mexco.campus.pending', ['ref' => $application->reference_no])
                ->with('success', 'Application submitted. Please wait for Super Admin approval before signing in.');
        }

        $this->auth->loginSession($request, $user);

        if ($planCode === 'demo') {
            $demo = $this->demo->start($user);

            return redirect()->route('mexco.portal.dashboard')
                ->with('success', 'Account created. Your free demo event is ready - full features with limits.')
                ->with('demo_organiser_username', $demo['event']->organiser_username)
                ->with('demo_organiser_password', $demo['organiser_password']);
        }

        if ($planCode) {
            $plan = MexcoPlan::query()->where('code', $planCode)->where('is_active', true)->first();
            if ($plan && ! $plan->is_custom_pricing && ! in_array($plan->code, ['campus', 'demo'], true)) {
                $order = $this->checkout->startOrder($plan, $user);
                $request->session()->put('mexco_checkout_order_id', $order->id);
                $request->session()->put('mexco_selected_plan_code', $plan->code);

                return redirect()->route('mexco.checkout.event')
                    ->with('success', 'Account created. Now set up your event.');
            }
        }

        return redirect()->route('mexco.portal.dashboard')
            ->with('success', 'Welcome to My MeXCo. Your organisation is ready.');
    }

    public function logout(Request $request): RedirectResponse
    {
        $this->auth->logoutSession($request);

        return redirect()->route('mexco.home')
            ->with('success', 'You have been signed out.');
    }
}
