<?php

namespace App\Http\Controllers;

use App\Helpers\TenantHelper;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
use App\Models\VendorUsers;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;

class FoodController extends Controller
{
    public function __construct()
    {
        // $this->middleware('auth');
    }

    public function index()
    {
        $conn   = $this->vendorConnection();
        $vendor = $this->authVendorRow($conn);

        // Active currency from public schema
        $currency = DB::table('currencies')->where('isActive', 'true')->first();

        // All subcategories for this vendor
        $subcategories = $conn->table('vendor_subcategories')
            ->where('vendor_id', $vendor->id)
            ->get();

        // Map id → subcategory row for O(1) lookup
        $categoryMap = $subcategories->keyBy('id');

        // Published categories sorted by display_order
        $publishedCategories = $subcategories
            ->where('publish', true)
            ->sortBy('display_order')
            ->values();

        $categoryOrderMap = [];
        foreach ($publishedCategories as $index => $cat) {
            $categoryOrderMap[(string) $cat->name] = $index;
        }

        $categories = $publishedCategories->pluck('name')->unique()->values();

        // id → name map used on the frontend when changing a product's category
        $subcategoryMap = $subcategories->mapWithKeys(fn ($c) => [(string) $c->id => $c->name]);

        // Products with optional bundle-price calculation
        $rawProducts = $conn->table('vendor_products')
            ->where('vendor_id', $vendor->id)
            ->get();

        $products = $rawProducts->map(function ($p) use ($categoryMap) {
            $category = $categoryMap->get($p->subcategory_id);
            $price    = (float) ($p->price ?? 0);
            $isBundle = false;

            if ($price == 0 && !empty($p->options_id)) {
                $options = is_string($p->options_id)
                    ? json_decode($p->options_id, true)
                    : (array) $p->options_id;

                if (is_array($options)) {
                    $optionsArray = array_is_list($options) ? $options : array_values($options);
                    $bundlePrice  = 0;

                    foreach ($optionsArray as $group) {
                        if (
                            isset($group['selectionType']) &&
                            $group['selectionType'] === 'multiple' &&
                            !empty($group['isPreselected']) &&
                            isset($group['elements'])
                        ) {
                            $elements = is_array($group['elements'])
                                ? array_values($group['elements'])
                                : [];
                            foreach ($elements as $element) {
                                $bundlePrice += (float) ($element['price'] ?? 0);
                            }
                        }
                    }

                    if ($bundlePrice > 0) {
                        $price = $bundlePrice;
                    }
                }

                $isBundle = true;
            }

            return [
                'id'            => $p->id,
                'name'          => $p->name,
                'photo'         => TenantHelper::storagePublicUrl($p->photo),
                'price'         => $price,
                'disPrice'      => (float) ($p->dis_price ?? 0),
                'publish'       => (bool) $p->publish,
                'category'      => $category ? $category->name : 'Brak',
                'subcategoryId' => (string) $p->subcategory_id,
                'order'         => $p->display_order ?? 0,
                'isBundle'      => $isBundle,
            ];
        });

        return view('foods.index', [
            'products'         => $products,
            'categories'       => $categories,
            'categoryOrderMap' => $categoryOrderMap,
            'subcategoryMap'   => $subcategoryMap,
            'currency'         => [
                'symbol'        => $currency->symbol        ?? '€',
                'symbolAtRight' => ($currency->symbolAtRight ?? 'false') === 'true',
                'decimalDigits' => (int) ($currency->decimal_degits ?? 2),
            ],
            'placeholderImage' => asset('images/placeholder.png'),
        ]);
    }

    public function edit($id)
    {
        $conn      = $this->vendorConnection();
        $vendor    = $this->authVendorRow($conn);

        $vendorUser = VendorUsers::where('user_id', Auth::guard('admin')->id() ?? Auth::id())->first();
        $country    = ucfirst(explode('_', $vendorUser->schema_name)[0]);

        $taxRates = DB::table('tax')
            ->where('enable', 1)
            ->where('country', $country)
            ->orderBy('tax')
            ->get();

        $subcategories = $conn->table('vendor_subcategories')
            ->where('vendor_id', $vendor->id)
            ->where('publish', true)
            ->orderBy('display_order')
            ->get();

        $allergens = $conn->table('allergens')
            ->where('enabled', 1)
            ->get();

        $placeholderImage = asset('images/placeholder.png');

        return view('foods.edit', compact('id', 'taxRates', 'subcategories', 'allergens', 'placeholderImage'));
    }

    public function create()
    {
        $conn      = $this->vendorConnection();
        $vendor    = $this->authVendorRow($conn);

        $vendorUser = VendorUsers::where('user_id', Auth::guard('admin')->id() ?? Auth::id())->first();
        $country    = ucfirst(explode('_', $vendorUser->schema_name)[0]);

        $taxRates = DB::table('tax')
            ->where('enable', 1)
            ->where('country', $country)
            ->orderBy('tax')
            ->get();

        $subcategories = $conn->table('vendor_subcategories')
            ->where('vendor_id', $vendor->id)
            ->where('publish', true)
            ->orderBy('display_order')
            ->get();

        $allergens = $conn->table('allergens')
            ->where('enabled', 1)
            ->get();

        $placeholderImage = asset('images/placeholder.png');

        return view('foods.create', compact('taxRates', 'subcategories', 'allergens', 'placeholderImage'));
    }

    // ── API: store new product ────────────────────────────────────────────────

    public function apiStore(Request $request)
    {
        $data = $request->validate([
            'name'                => 'required|string|max:255',
            'description'         => 'nullable|string',
            'price'               => 'required|numeric|min:0',
            'dis_price'           => 'nullable|numeric|min:0',
            'subcategory_id'      => 'required|integer',
            'tax_id'              => 'nullable|integer',
            'photo'               => 'nullable|string',
            'publish'             => 'required|boolean',
            'age_restriction'     => 'required|boolean',
            'printer_destination' => 'nullable|string',
            'options_id'          => 'nullable',
            'allergen_ids'        => 'nullable|array',
        ]);

        $conn   = $this->vendorConnection();
        $vendor = $this->authVendorRow($conn);

        $categoryId = $conn->table('vendor_categories')->value('id');

        $displayOrder = $conn->table('vendor_products')->where('vendor_id', $vendor->id)->count();

        $id = $conn->table('vendor_products')->insertGetId([
            'name'                => $data['name'],
            'description'         => $data['description'] ?? null,
            'price'               => $data['price'],
            'dis_price'           => $data['dis_price'] ?? 0,
            'vendor_id'           => $vendor->id,
            'subcategory_id'      => $data['subcategory_id'],
            'category_id'         => $categoryId,
            'tax_id'              => $data['tax_id'] ?? null,
            'photo'               => $data['photo'] ?? null,
            'publish'             => $data['publish'],
            'age_restriction'     => $data['age_restriction'],
            'printer_destination' => $data['printer_destination'] ?? 'Kitchen',
            'options_id'          => isset($data['options_id']) ? json_encode($data['options_id']) : null,
            'allergen_ids'        => isset($data['allergen_ids']) ? json_encode($data['allergen_ids']) : json_encode([]),
            'stock'               => -1,
            'table_service'       => true,
            'display_order'       => $displayOrder,
            'created_at'          => now(),
            'updated_at'          => now(),
        ]);

        return response()->json(['success' => true, 'id' => $id]);
    }

    // ── API: upload product photo ─────────────────────────────────────────────

    public function apiUploadPhoto(Request $request)
    {
        $request->validate(['photo' => 'required|image|max:10240']);

        $path = $request->file('photo')->store('products', 'public');
        $url  = Storage::disk('public')->url($path);

        return response()->json(['success' => true, 'url' => $url]);
    }

    // ── API: get single product (for template loading) ────────────────────────

    public function apiGet($id)
    {
        $conn   = $this->vendorConnection();
        $vendor = $this->authVendorRow($conn);

        $product = $conn->table('vendor_products')
            ->where('id', (int) $id)
            ->where('vendor_id', $vendor->id)
            ->first();

        if (!$product) {
            return response()->json(['success' => false, 'message' => 'Product not found'], 404);
        }

        $productData = (array) $product;
        $productData['photo'] = TenantHelper::storagePublicUrl($product->photo ?? null);

        return response()->json(['success' => true, 'product' => $productData]);
    }

    // ── API: toggle publish ───────────────────────────────────────────────────

    public function apiTogglePublish(Request $request, $id)
    {
        $request->validate(['publish' => 'required|boolean']);

        $conn   = $this->vendorConnection();
        $vendor = $this->authVendorRow($conn);

        $updated = $conn->table('vendor_products')
            ->where('id', (int) $id)
            ->where('vendor_id', $vendor->id)
            ->update(['publish' => $request->boolean('publish'), 'updated_at' => now()]);

        if (!$updated) {
            return response()->json(['success' => false, 'message' => 'Product not found'], 404);
        }

        return response()->json(['success' => true]);
    }

    // ── API: delete product ───────────────────────────────────────────────────

    public function apiDelete($id)
    {
        $conn   = $this->vendorConnection();
        $vendor = $this->authVendorRow($conn);

        $deleted = $conn->table('vendor_products')
            ->where('id', (int) $id)
            ->where('vendor_id', $vendor->id)
            ->delete();

        if (!$deleted) {
            return response()->json(['success' => false, 'message' => 'Product not found'], 404);
        }

        return response()->json(['success' => true]);
    }

    // ── API: update display order ─────────────────────────────────────────────

    public function apiUpdateOrder(Request $request)
    {
        $request->validate([
            'subcategoryId' => 'required',
            'productIds'    => 'required|array',
            'productIds.*'  => 'required',
        ]);

        $conn   = $this->vendorConnection();
        $vendor = $this->authVendorRow($conn);

        foreach ($request->productIds as $index => $productId) {
            $conn->table('vendor_products')
                ->where('id', (int) $productId)
                ->where('vendor_id', $vendor->id)
                ->update(['display_order' => $index + 1, 'updated_at' => now()]);
        }

        return response()->json(['success' => true]);
    }

    // ── API: change subcategory ───────────────────────────────────────────────

    public function apiChangeCategory(Request $request, $id)
    {
        $request->validate(['newCategoryId' => 'required']);

        $conn   = $this->vendorConnection();
        $vendor = $this->authVendorRow($conn);

        $conn->table('vendor_products')
            ->where('id', (int) $id)
            ->where('vendor_id', $vendor->id)
            ->update([
                'subcategory_id' => (int) $request->newCategoryId,
                'display_order'  => 0,
                'updated_at'     => now(),
            ]);

        return response()->json(['success' => true]);
    }

    // ── API: update product ───────────────────────────────────────────────────

    public function apiUpdate(Request $request, $id)
    {
        $data = $request->validate([
            'name'                => 'sometimes|required|string|max:255',
            'description'         => 'nullable|string',
            'price'               => 'sometimes|required|numeric|min:0',
            'dis_price'           => 'nullable|numeric|min:0',
            'subcategory_id'      => 'sometimes|required|integer',
            'tax_id'              => 'nullable|integer',
            'photo'               => 'nullable|string',
            'publish'             => 'sometimes|boolean',
            'age_restriction'     => 'sometimes|boolean',
            'printer_destination' => 'nullable|string',
            'options_id'          => 'nullable',
            'allergen_ids'        => 'nullable|array',
        ]);

        $conn   = $this->vendorConnection();
        $vendor = $this->authVendorRow($conn);

        $fields = [];
        if (array_key_exists('name', $data))                $fields['name']                = $data['name'];
        if (array_key_exists('description', $data))         $fields['description']         = $data['description'] ?? null;
        if (array_key_exists('price', $data))               $fields['price']               = $data['price'];
        if (array_key_exists('dis_price', $data))           $fields['dis_price']           = $data['dis_price'] ?? 0;
        if (array_key_exists('subcategory_id', $data))      $fields['subcategory_id']      = $data['subcategory_id'];
        if (array_key_exists('tax_id', $data))              $fields['tax_id']              = $data['tax_id'] ?? null;
        if (array_key_exists('photo', $data))               $fields['photo']               = $data['photo'] ?? null;
        if (array_key_exists('publish', $data))             $fields['publish']             = $data['publish'];
        if (array_key_exists('age_restriction', $data))     $fields['age_restriction']     = $data['age_restriction'];
        if (array_key_exists('printer_destination', $data)) $fields['printer_destination'] = $data['printer_destination'] ?? 'Kitchen';
        if (array_key_exists('options_id', $data))          $fields['options_id']          = isset($data['options_id']) ? json_encode($data['options_id']) : null;
        if (array_key_exists('allergen_ids', $data))        $fields['allergen_ids']        = json_encode($data['allergen_ids'] ?? []);

        if (empty($fields)) {
            return response()->json(['success' => false, 'message' => 'No fields to update'], 400);
        }

        $fields['updated_at'] = now();

        $updated = $conn->table('vendor_products')
            ->where('id', (int) $id)
            ->where('vendor_id', $vendor->id)
            ->update($fields);

        if (!$updated) {
            return response()->json(['success' => false, 'message' => 'Product not found'], 404);
        }

        return response()->json(['success' => true]);
    }

    // ── Private helpers ───────────────────────────────────────────────────────

    private function vendorConnection()
    {
        $userId     = Auth::guard('admin')->id() ?? Auth::id();
        $vendorUser = VendorUsers::where('user_id', $userId)->firstOrFail();

        if (!$vendorUser->schema_name) {
            abort(500, 'Vendor schema not configured.');
        }

        TenantHelper::setSchema($vendorUser->schema_name);
        return DB::connection('pgsql_country');
    }

    private function authVendorRow($conn)
    {
        $userId = Auth::guard('admin')->id() ?? Auth::id();
        $vendor = $conn->table('vendors')->where('owner_id', $userId)->first();

        if (!$vendor) {
            abort(404, 'Vendor not found.');
        }

        return $vendor;
    }
}

