<?php

namespace App\Http\Controllers\Api\V1\Backend\Catalog;

use App\Http\Controllers\Api\V1\Backend\ResponseController;
use App\Models\Backend\Catalog\Manufacturer;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;

class ManufacturerController extends ResponseController
{
    /**
     * Display a listing of the resource.
     */
    public function index(Request $request)
    {
        try {
            $query = Manufacturer::query();

            if($request->has('filter_name') && $request->filled('filter_name')) {
                $query->where('name', 'like', '%' . $request->filter_name . '%');
            }

            if($request->has('sort_by') && $request->filled('sort_by')) {
                $sort_by = $request->sort_by;
                $order = $request->has('order') && in_array(strtolower($request->order), ['asc', 'desc']) ? strtolower($request->order) : 'asc';
                $query->orderBy($sort_by, $order);
            } else {
                $query->orderBy('name', 'asc');
            }

            if($request->has('limit') && is_numeric($request->limit) && $request->limit > 0) {
                $query->limit($request->limit);
            }
            
            $manufacturers = $query->get();

            if ($manufacturers->isEmpty()) {
                return $this->sendError('No manufacturers found!', code:404);
            }

            return $this->sendResponse($manufacturers, 'All manufacturers fetched successfully!');
        } catch (Exception $err) {
            return $this->sendError(errorMessages: $err->getMessage(), code:500);
        }
    }

    /**
     * Show the form for creating a new resource.
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'name' => 'required|string|max:255',
            'keyword' => 'nullable|string|max:255',
            'store_id' => 'nullable|integer',
            'sort_order' => 'nullable|integer',
            'quantity_stock' => 'required|string',
            'order_day' => 'nullable|string',
            'cut_off' => 'nullable|string',
            'day_numbers' => 'nullable|integer',
            'glass_restricted' => 'nullable|string',
            'image' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
        ]);

        if($validator->fails()) {
            return $this->sendError('Validation fails !', $validator->errors(), 422);
        }

        try {
            DB::beginTransaction();

            $manufacturer = new Manufacturer;

            $manufacturer->name = $request->name;
            $manufacturer->sort_order = $request->sort_order ?? 0;
            $manufacturer->quantity_stock = $request->quantity_stock;
            $manufacturer->order_day = $request->order_day ?? '';
            $manufacturer->cut_off = $request->cut_off ?? '';
            $manufacturer->day_numbers = $request->day_numbers ?? 0;
            $manufacturer->Glass_Restricted = $request->glass_restricted ?? '';

            if($request->hasFile('image')) {
                $path = $request->file('image')->store('catalog/manufacturers', 'public');
                $manufacturer->image = Storage::url($path);
            }

            if(!$manufacturer->save()) {
                throw new Exception('Failed to create manufacturer!');
            }

            $manufacturerId = $manufacturer->manufacturer_id;

            if($request->filled('keyword')) {
                DB::table('oc_url_alias')->insert([
                    'query' => 'manufacturer_id=' . $manufacturerId,
                    'keyword' => $request->keyword
                ]);
            }

            if($request->filled('store_id')) {
                DB::table('oc_manufacturer_to_store')->insert([
                    'manufacturer_id' => $manufacturerId,
                    'store_id' => $request->store_id
                ]);
            }

            DB::commit();
            return $this->sendResponse($manufacturer, 'Manufacturer created successfully!', 201);
        }
        catch(Exception $err) {
            DB::rollBack();
            return $this->sendError(errorMessages:$err->getMessage(), code:500);
        }
    }

    /**
     * Display the specified resource.
     */
    public function show(string $id)
    {
        try {
            $manufacturer = Manufacturer::findOrFail($id);

            return $this->sendResponse($manufacturer, 'Manufacturer fetched successfully!');
        } catch (Exception $err) {
            return $this->sendError(errorMessages: $err->getMessage(), code:404);
        }
    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit(string $id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, string $id)
    {
        $validator = Validator::make($request->all(), [
            'name' => 'required|string|max:255',
            'keyword' => 'nullable|string|max:255',
            'store_id' => 'nullable|integer',
            'sort_order' => 'nullable|integer',
            'quantity_stock' => 'required|string',
            'order_day' => 'nullable|string',
            'cut_off' => 'nullable|string',
            'day_numbers' => 'nullable|integer',
            'glass_restricted' => 'nullable|string',
            'image' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
            'uplift' => 'nullable|numeric|min:0',
        ]);

        if($validator->fails()) {
            return $this->sendError('Validation fails !', $validator->errors(), 422);
        }

        try {
            DB::beginTransaction();

            $manufacturer = Manufacturer::findOrFail($id);

            $manufacturer->name = $request->name;
            $manufacturer->sort_order = $request->sort_order ?? 0;
            $manufacturer->quantity_stock = $request->quantity_stock;
            $manufacturer->order_day = $request->order_day ?? '';
            $manufacturer->cut_off = $request->cut_off ?? '';
            $manufacturer->day_numbers = $request->day_numbers ?? 0;
            $manufacturer->Glass_Restricted = $request->glass_restricted ?? '';

            if($request->hasFile('image')) {
                // Delete old image if exists
                if ($manufacturer->image) {
                    Storage::disk('public')->delete(str_replace('/storage/', '', $manufacturer->image));
                }
                // Store new image
                $path = $request->file('image')->store('catalog/manufacturers', 'public');
                $manufacturer->image = Storage::url($path);
            }

            if(!$manufacturer->save()) {
                throw new Exception('Failed to update manufacturer!');
            }

            if($request->filled('keyword')) {
                DB::table('oc_url_alias')
                    ->updateOrInsert(['query' => 'manufacturer_id=' . $id], ['keyword' => $request->keyword]);
            }

            if($request->filled('store_id')) {
                DB::table('oc_manufacturer_to_store')
                    ->updateOrInsert(['manufacturer_id' => $id], ['store_id' => $request->store_id]);
            }

            if ($request->filled('uplift')) {
                $products = DB::table('oc_product')
                    ->where('manufacturer_id', $id)
                    ->pluck('product_id')
                    ->toArray();

                if (!empty($products)) {
                    DB::table('oc_product')
                        ->whereIn('product_id', $products)
                        ->update([
                            'price' => DB::raw('price + (price * ' . $request->uplift . ' / 100.0)')
                        ]);

                    DB::table('oc_product_option_value')
                        ->whereIn('product_id', $products)
                        ->update([
                            'price' => DB::raw('price + (price * ' . $request->uplift . ' / 100.0)')
                        ]);
                }
            }

            DB::commit();
            return $this->sendResponse($manufacturer, 'Manufacturer updated successfully!');
        } catch (Exception $err) {
            DB::rollBack();
            return $this->sendError(errorMessages: $err->getMessage(), code:500);
        }
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(string $id)
    {
        try {
            $manufacturer = Manufacturer::findOrFail($id);

            // Delete image if exists
            if ($manufacturer->image) {
                Storage::disk('public')->delete(str_replace('/storage/', '', $manufacturer->image));
            }

            $manufacturer->delete();

            DB::table('oc_url_alias')->where('query', 'manufacturer_id=' . $id)->delete();
            DB::table('oc_manufacturer_to_store')->where('manufacturer_id', $id)->delete();

            return $this->sendResponse([], 'Manufacturer deleted successfully!');
        } catch (Exception $err) {
            return $this->sendError(errorMessages: $err->getMessage(), code:500);
        }
    }
}
