<?php

namespace App\Http\Controllers;

use App\Models\Tenant\OnlineOrder;
use App\Models\Tenant\OnlineOrderItem;
use App\Models\Tenant\Part;
use App\Services\Ai\VinDecoder;
use App\Tenancy\TenantManager;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

class ShopController extends Controller
{
    private function tenantOrFail()
    {
        $tenant = app(TenantManager::class)->current();
        if (! $tenant) {
            throw new NotFoundHttpException('Magazinul e disponibil doar pe subdomeniul service-ului.');
        }
        if (! data_get($tenant->settings, 'shop.enabled')) {
            throw new NotFoundHttpException('Magazinul online nu este activ.');
        }
        return $tenant;
    }

    public function catalog(Request $request)
    {
        $tenant = $this->tenantOrFail();

        $term = $request->query('q');
        $category = $request->query('cat');
        $inStock = $request->boolean('in_stock');

        $query = Part::searchPublished($term);
        if ($category) $query->where('category', $category);
        if ($inStock) $query->where('qty', '>', 0);

        $parts = $query->orderBy('name')->paginate(24)->withQueryString();
        $categories = Part::published()->distinct()->pluck('category')->filter()->sort()->values();

        return view('shop.catalog', [
            'tenant' => $tenant,
            'parts' => $parts,
            'categories' => $categories,
            'term' => $term,
            'category' => $category,
            'inStock' => $inStock,
            'cartCount' => $this->cartCount(),
        ]);
    }

    public function part(Request $request, int $id)
    {
        $tenant = $this->tenantOrFail();
        $part = Part::published()->with('crossRefs')->find($id);
        if (! $part) throw new NotFoundHttpException('Piesa nu există sau nu e publicată.');

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

    public function vin(Request $request)
    {
        $tenant = $this->tenantOrFail();
        $vin = strtoupper(trim((string) $request->query('vin', '')));
        $decoded = null;
        if ($vin !== '') {
            $decoded = app(VinDecoder::class)->decode($vin);
        }

        return view('shop.vin', [
            'tenant' => $tenant,
            'vin' => $vin,
            'decoded' => $decoded,
            'cartCount' => $this->cartCount(),
        ]);
    }

    // ─── Cart (session) ───────────────────────────────────────────

    private function cartKey(): string
    {
        $tenant = app(TenantManager::class)->current();
        return 'shop_cart_' . ($tenant?->id ?? '0');
    }

    private function cart(): array
    {
        return (array) session($this->cartKey(), []);
    }

    private function cartCount(): int
    {
        return (int) collect($this->cart())->sum('qty');
    }

    public function addToCart(Request $request, int $id)
    {
        $this->tenantOrFail();
        $part = Part::published()->findOrFail($id);
        $qty = max(1, (int) $request->input('qty', 1));

        $cart = $this->cart();
        $cart[$id] = [
            'part_id' => $part->id,
            'name' => $part->name,
            'article' => $part->article,
            'price' => (float) $part->sell_price,
            'qty' => ($cart[$id]['qty'] ?? 0) + $qty,
        ];
        session([$this->cartKey() => $cart]);

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

    public function updateCart(Request $request)
    {
        $this->tenantOrFail();
        $cart = $this->cart();
        foreach ((array) $request->input('qty', []) as $id => $qty) {
            $qty = (int) $qty;
            if ($qty <= 0) {
                unset($cart[$id]);
            } elseif (isset($cart[$id])) {
                $cart[$id]['qty'] = $qty;
            }
        }
        session([$this->cartKey() => $cart]);
        return redirect('/shop/cart');
    }

    public function showCart()
    {
        $tenant = $this->tenantOrFail();
        $cart = $this->cart();
        $subtotal = collect($cart)->sum(fn ($i) => $i['price'] * $i['qty']);

        return view('shop.cart', [
            'tenant' => $tenant,
            'cart' => $cart,
            'subtotal' => $subtotal,
            'cartCount' => $this->cartCount(),
        ]);
    }

    public function checkout()
    {
        $tenant = $this->tenantOrFail();
        $cart = $this->cart();
        if (empty($cart)) return redirect('/shop');

        $subtotal = collect($cart)->sum(fn ($i) => $i['price'] * $i['qty']);
        $customer = \Illuminate\Support\Facades\Auth::guard('shop')->user();

        return view('shop.checkout', [
            'tenant' => $tenant,
            'cart' => $cart,
            'subtotal' => $subtotal,
            'customer' => $customer,
            'deliveryOptions' => (array) data_get($tenant->settings, 'shop.delivery_methods', ['pickup']),
            'cartCount' => $this->cartCount(),
        ]);
    }

    public function placeOrder(Request $request)
    {
        $tenant = $this->tenantOrFail();
        $cart = $this->cart();
        if (empty($cart)) return redirect('/shop');

        $data = $request->validate([
            'customer_name' => 'required|string|max:160',
            'customer_phone' => 'required|string|max:40',
            'customer_email' => 'nullable|email|max:160',
            'delivery_method' => 'required|in:pickup,courier,post',
            'address' => 'nullable|string|max:255',
            'notes' => 'nullable|string|max:1000',
        ]);

        $deliveryFee = 0.0;
        $subtotal = collect($cart)->sum(fn ($i) => $i['price'] * $i['qty']);
        if ($data['delivery_method'] !== 'pickup') {
            $fee = (float) data_get($tenant->settings, 'shop.delivery_fee', 0);
            $freeOver = (float) data_get($tenant->settings, 'shop.free_delivery_over', 0);
            $deliveryFee = ($freeOver > 0 && $subtotal >= $freeOver) ? 0.0 : $fee;
        }

        $shopCustomer = \Illuminate\Support\Facades\Auth::guard('shop')->user();

        $order = DB::transaction(function () use ($tenant, $cart, $data, $deliveryFee, $shopCustomer) {
            $order = OnlineOrder::create([
                'number' => OnlineOrder::generateNumber($tenant->id),
                'shop_customer_id' => $shopCustomer?->id,
                'client_id' => $shopCustomer?->client_id,
                'customer_name' => $data['customer_name'],
                'customer_phone' => $data['customer_phone'],
                'customer_email' => $data['customer_email'] ?? null,
                'delivery_method' => $data['delivery_method'],
                'address' => $data['address'] ?? null,
                'notes' => $data['notes'] ?? null,
                'status' => 'new',
                'delivery_fee' => $deliveryFee,
            ]);

            foreach ($cart as $item) {
                OnlineOrderItem::create([
                    'online_order_id' => $order->id,
                    'part_id' => $item['part_id'] ?? null,
                    'name' => $item['name'],
                    'article' => $item['article'] ?? null,
                    'qty' => $item['qty'],
                    'price' => $item['price'],
                ]);
            }
            $order->refresh()->recalcTotal();
            return $order;
        });

        session()->forget($this->cartKey());

        // Notify (best-effort): customer + shop staff.
        try {
            app(\App\Services\Notifications\ShopOrderNotifier::class)->placed($order);
        } catch (\Throwable $e) {
            \Illuminate\Support\Facades\Log::debug('shop order notify skipped: ' . $e->getMessage());
        }

        return redirect('/shop/order/' . $order->tracking_token);
    }

    public function orderStatus(Request $request, string $token)
    {
        $tenant = $this->tenantOrFail();
        $order = OnlineOrder::with('items')->where('tracking_token', $token)->first();
        if (! $order) throw new NotFoundHttpException('Comanda nu a fost găsită.');

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