<?php

namespace App\Http\Controllers;

use App\Models\Tenant\Client;
use App\Models\Tenant\ShopCustomer;
use App\Tenancy\TenantManager;
use Illuminate\Auth\Events\PasswordReset;
use Illuminate\Auth\Events\Registered;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Password;
use Illuminate\Support\Str;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

class ShopAuthController extends Controller
{
    private function tenantOrFail()
    {
        $tenant = app(TenantManager::class)->current();
        if (! $tenant || ! data_get($tenant->settings, 'shop.enabled')) {
            throw new NotFoundHttpException('Magazinul online nu este activ.');
        }
        return $tenant;
    }

    public function showRegister()
    {
        $tenant = $this->tenantOrFail();
        if (Auth::guard('shop')->check()) return redirect('/shop/account');
        return view('shop.auth.register', ['tenant' => $tenant, 'cartCount' => $this->cartCount()]);
    }

    public function register(Request $request)
    {
        $tenant = $this->tenantOrFail();
        $data = $request->validate([
            'name' => 'required|string|max:160',
            'phone' => 'required|string|max:40',
            'email' => 'nullable|email|max:160',
            'password' => 'required|string|min:6|confirmed',
        ]);

        // Unique per tenant (handled by composite index, but check for nicer error).
        if (ShopCustomer::where('phone', $data['phone'])->exists()) {
            return back()->withErrors(['phone' => 'Există deja un cont cu acest telefon.'])->withInput();
        }

        // Auto-link to existing Client by phone if present.
        $client = Client::where('phone', $data['phone'])->first();

        $customer = ShopCustomer::create([
            'client_id' => $client?->id,
            'name' => $data['name'],
            'phone' => $data['phone'],
            'email' => $data['email'] ?? null,
            'password' => $data['password'],   // hashed by cast
        ]);

        event(new Registered($customer));
        Auth::guard('shop')->login($customer, remember: true);
        $customer->forceFill(['last_login_at' => now()])->save();

        return redirect('/shop/account');
    }

    public function showLogin()
    {
        $tenant = $this->tenantOrFail();
        if (Auth::guard('shop')->check()) return redirect('/shop/account');
        return view('shop.auth.login', ['tenant' => $tenant, 'cartCount' => $this->cartCount()]);
    }

    public function login(Request $request)
    {
        $tenant = $this->tenantOrFail();
        $data = $request->validate([
            'phone' => 'required|string|max:40',
            'password' => 'required|string',
        ]);

        $ok = Auth::guard('shop')->attempt(
            ['phone' => $data['phone'], 'password' => $data['password']],
            remember: true
        );
        if (! $ok) {
            return back()->withErrors(['phone' => 'Telefon sau parolă incorecte.'])->withInput();
        }

        $request->session()->regenerate();
        Auth::guard('shop')->user()?->forceFill(['last_login_at' => now()])->save();
        return redirect()->intended('/shop/account');
    }

    public function logout(Request $request)
    {
        Auth::guard('shop')->logout();
        $request->session()->invalidate();
        $request->session()->regenerateToken();
        return redirect('/shop');
    }

    public function account()
    {
        $tenant = $this->tenantOrFail();
        $customer = Auth::guard('shop')->user();
        if (! $customer) return redirect('/shop/login');

        $orders = $customer->orders()
            ->latest('created_at')
            ->limit(50)
            ->get();

        return view('shop.account', [
            'tenant' => $tenant,
            'customer' => $customer,
            'orders' => $orders,
            'cartCount' => $this->cartCount(),
        ]);
    }

    public function showForgotPassword()
    {
        $tenant = $this->tenantOrFail();
        return view('shop.auth.forgot', ['tenant' => $tenant, 'cartCount' => $this->cartCount()]);
    }

    public function sendResetLink(Request $request)
    {
        $this->tenantOrFail();
        $data = $request->validate(['email' => 'required|email']);

        // Send (always returns generic "sent" message — don't disclose if email exists).
        Password::broker('shop_customers')->sendResetLink(['email' => $data['email']]);

        return back()->with('status', 'Dacă există un cont cu acest email, am trimis un link de resetare.');
    }

    public function showResetPassword(string $token, Request $request)
    {
        $tenant = $this->tenantOrFail();
        return view('shop.auth.reset', [
            'tenant' => $tenant,
            'token' => $token,
            'email' => $request->query('email'),
            'cartCount' => $this->cartCount(),
        ]);
    }

    public function resetPassword(Request $request)
    {
        $this->tenantOrFail();
        $data = $request->validate([
            'token' => 'required|string',
            'email' => 'required|email',
            'password' => 'required|string|min:6|confirmed',
        ]);

        $status = Password::broker('shop_customers')->reset(
            $data,
            function (ShopCustomer $customer, string $password) {
                $customer->forceFill([
                    'password' => Hash::make($password),
                    'remember_token' => Str::random(60),
                ])->save();
                event(new PasswordReset($customer));
            }
        );

        if ($status === Password::PASSWORD_RESET) {
            return redirect('/shop/login')->with('status', 'Parola a fost resetată. Te poți loga acum.');
        }

        return back()->withErrors(['email' => 'Link invalid sau expirat. Cere unul nou.'])->withInput();
    }

    private function cartCount(): int
    {
        $tenant = app(TenantManager::class)->current();
        $cart = (array) session('shop_cart_' . ($tenant?->id ?? '0'), []);
        return (int) collect($cart)->sum('qty');
    }
}
