<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\Order\BulkDestroyOrder;
use App\Http\Requests\Admin\Order\DestroyOrder;
use App\Http\Requests\Admin\Order\IndexOrder;
use App\Http\Requests\Admin\Order\StoreOrder;
use App\Http\Requests\Admin\Order\UpdateOrder;
use App\Models\Order;
use Brackets\AdminListing\Facades\AdminListing;
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Contracts\Routing\ResponseFactory;
use Illuminate\Contracts\View\Factory;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Response;
use Illuminate\Routing\Redirector;
use Illuminate\Support\Facades\DB;
use Illuminate\View\View;
use App\Models\ProductType;
use App\Models\PolishType;
use App\Models\MetalType;
use App\Models\ProngsType;
use App\Models\MetalTone;
use App\Models\RingSize;
use App\Models\Closure;
use App\Models\WristSize;
use App\Models\LockType;
use App\Models\BaleType;
use App\Models\Customer;
use App\Models\Priority;
use App\Models\DiamondType;
use App\Models\DiamondOrder;
use App\Models\DiamondShape;
use App\Models\CaratWeight;
use App\Models\StoneColor;
use App\Models\MetalPurity;

class OrdersController extends Controller
{

    /**
     * Display a listing of the resource.
     *
     * @param IndexOrder $request
     * @return array|Factory|View
     */
    public function index(IndexOrder $request)
    {
        // create and AdminListing instance for a specific model and
        $data = AdminListing::create(Order::class)->processRequestAndGet(
            // pass the request with params
            $request,

            // set columns to query
            ['id', 'customer_id','purity','amount','payment_type','paid_amount','jewellery_certificate_req','order_type', 'product_type', 'polish_type', 'metal_type', 'prongs_type', 'metal_tone', 'ring_size', 'closure', 'wrist_size', 'lock_type', 'bale_type', 'necklace_length', 'length', 'width', 'height', 'order_date', 'due_date', 'difficulty_level', 'priority', 'engraving', 'gift_wrap', 'express_shipping', 'status', 'current_process'],

            // set columns to searchIn
            ['id', 'comment', 'engraving_text','amount','paid_amount', 'engraving_note', 'engraving_example', 'status', 'current_process']
        );
  
        $data->load(['customer', 'productType', 'metalType', 'priority']);
        if ($request->ajax()) {
            if ($request->has('bulk')) {
                return [
                    'bulkItems' => $data->pluck('id')
                ];
            }
            return ['data' => $data];
        }
  

        return view('admin.order.index', ['data' => $data]);
    }

    /**
     * Show the form for creating a new resource.
     *
     * @throws AuthorizationException
     * @return Factory|View
     */
    public function create()
    {
        $this->authorize('admin.order.create');
        $Customer = Customer::where('status',1)->get();
        $ProductType = ProductType::where('status',1)->get();
        $PolishType = PolishType::where('status',1)->get();
        $MetalType = MetalType::where('status',1)->get();
        $ProngsType = ProngsType::where('status',1)->get();
        $MetalTone = MetalTone::where('status',1)->get();
        $RingSize = RingSize::where('status',1)->get();
        $Closure = Closure::where('status',1)->get();
        $WristSize = WristSize::where('status',1)->get();
        $LockType = LockType::where('status',1)->get();
        $BaleType = BaleType::where('status',1)->get();
        $Priority = Priority::where('status',1)->get();

   
        $order_type = collect([
            (object)['id' => '0', 'type' => 'Old'],
            (object)['id' => '1', 'type' => 'New'],
            (object)['id' => '2', 'type' => 'Re-make'],
        ]);

        $difficulty_level = collect([
            (object)['id' => '0', 'type' => 'Easy'],
            (object)['id' => '1', 'type' => 'Medium'],
            (object)['id' => '2', 'type' => 'Hard'],
        ]);

        
        $jewellery_certificate_req = collect([
            (object)['id' => '0', 'type' => 'No'],
            (object)['id' => '1', 'type' => 'Yes'],
            (object)['id' => '2', 'type' => 'Decide Later'],
        ]);
            
        $DiamondType = DiamondType::where('status',1)->get();
        $DiamondShape = DiamondShape::where('status',1)->get();
        $CaratWeight = CaratWeight::where('status',1)->get();
        $StoneColor = StoneColor::where('status',1)->get();
        $MetalPurity = MetalPurity::where('status',1)->get();
        $DiamondStockType = collect([
            (object)['id' => '0', 'type' => 'Custom'],
            (object)['id' => '1', 'type' => 'In Stock'],
            (object)['id' => '2', 'type' => 'Purchase'],
        ]);

        return view('admin.order.create',[
            'Customer' => $Customer,
            'ProductType' => $ProductType,
            'PolishType'=>$PolishType,
            'MetalType'=>$MetalType,
            'ProngsType'=>$ProngsType,
            'MetalTone' => $MetalTone,
            'RingSize'=>$RingSize,
            'Closure'=>$Closure,
            'WristSize'=>$WristSize,
            'LockType' => $LockType,
            'BaleType'=>$BaleType,
            'order_type'=>$order_type,
            'difficulty_level'=>$difficulty_level,
            'jewellery_certificate_req'=>$jewellery_certificate_req,
            'Priority'=>$Priority,
            'DiamondType' => $DiamondType,
            'DiamondShape' => $DiamondShape,
            'CaratWeight'=>$CaratWeight,
            'StoneColor'=>$StoneColor,
            'MetalPurity'=>$MetalPurity,
            'DiamondStockType'=>$DiamondStockType,
            'diamondorder'=>null,
            
        ]);
    }

    public function view($id)
    {
        $order = Order::findOrFail($id);
        $order->load(['customer', 'productType', 'metalType', 'priority','polishType']);
        // echo '<pre>';
        // print_r($order);
        // die(); 
        return view('admin.order.view', compact('order'));
    }
    


    /**
     * Store a newly created resource in storage.
     *
     * @param StoreOrder $request
     * @return array|RedirectResponse|Redirector
     */
    // public function store(StoreOrder $request)
    // {
    //     dd($request->all());
    //     // Sanitize input
    //     $sanitized = $request->getSanitized();

    //     // Store the Order
    //     $order = Order::create($sanitized);

    //     if ($request->ajax()) {
    //         return ['redirect' => url('admin/orders'), 'message' => trans('brackets/admin-ui::admin.operation.succeeded')];
    //     }

    //     return redirect('admin/orders');
    // }

    public function store(StoreOrder $request)
    {
        // dd($request->all());
        // Sanitize input
        $sanitized = $request->getSanitized();
        $sanitized['status'] = 'received';
        $sanitized['current_process'] = 'received';

        // Store the Order
        $order = Order::create($sanitized);
 
        // Retrieve dynamicFields from the request
        $dynamicFields = $request->input('dynamicFields', []);

        // Insert each dynamicField into the diamond_order table
        foreach ($dynamicFields as $dynamicField) {
            $dynamicField['order_id'] = $order->id; // Ensure order_id is set
            // $dynamicField['length'] = $dynamicField->diamond_length;
            // $dynamicField['width'] = $dynamicField->diamond_width;
            // $dynamicField['height'] = $dynamicField->diamond_height;
         
            DiamondOrder::create($dynamicField);
        }
        if ($request->ajax()) {
            return ['redirect' => url('admin/orders'), 'message' => trans('brackets/admin-ui::admin.operation.succeeded')];
        }

        return redirect('admin/orders');
    }


    /**
     * Display the specified resource.
     *
     * @param Order $order
     * @throws AuthorizationException
     * @return void
     */
    public function show(Order $order)
    {
        $this->authorize('admin.order.show', $order);

        // TODO your code goes here
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param Order $order
     * @throws AuthorizationException
     * @return Factory|View
     */
    public function edit(Order $order)
    {
        $this->authorize('admin.order.edit', $order);
        $Customer = Customer::where('status',1)->get();
        $ProductType = ProductType::where('status',1)->get();
        $PolishType = PolishType::where('status',1)->get();
        $MetalType = MetalType::where('status',1)->get();
        $ProngsType = ProngsType::where('status',1)->get();
        $MetalTone = MetalTone::where('status',1)->get();
        $RingSize = RingSize::where('status',1)->get();
        $Closure = Closure::where('status',1)->get();
        $WristSize = WristSize::where('status',1)->get();
        $LockType = LockType::where('status',1)->get();
        $BaleType = BaleType::where('status',1)->get();
        $Priority = Priority::where('status',1)->get();
        $DiamondType = DiamondType::where('status',1)->get();
        $DiamondShape = DiamondShape::where('status',1)->get();
        $CaratWeight = CaratWeight::where('status',1)->get();
        $StoneColor = StoneColor::where('status',1)->get();
        $DiamondStockType = collect([
            (object)['id' => '0', 'type' => 'Custom'],
            (object)['id' => '1', 'type' => 'In Stock'],
            (object)['id' => '2', 'type' => 'Purchase'],
        ]);

        $order_type = collect([
            (object)['id' => '0', 'type' => 'Old'],
            (object)['id' => '1', 'type' => 'New'],
            (object)['id' => '2', 'type' => 'Re-make'],
        ]);

        $difficulty_level = collect([
            (object)['id' => '0', 'type' => 'Easy'],
            (object)['id' => '1', 'type' => 'Medium'],
            (object)['id' => '2', 'type' => 'Hard'],
        ]);
        $jewellery_certificate_req = collect([
            (object)['id' => '0', 'type' => 'No'],
            (object)['id' => '1', 'type' => 'Yes'],
            (object)['id' => '2', 'type' => 'Decide Later'],
        ]);
            
        $MetalPurity = MetalPurity::where('status',1)->get();
        $diamondorder=DiamondOrder::where('order_id',$order->id)->get();

        return view('admin.order.edit', [
            'order' => $order,
            'Customer' => $Customer,
            'ProductType' => $ProductType,
            'PolishType'=>$PolishType,
            'MetalType'=>$MetalType,
            'ProngsType'=>$ProngsType,
            'MetalTone' => $MetalTone,
            'RingSize'=>$RingSize,
            'Closure'=>$Closure,
            'WristSize'=>$WristSize,
            'LockType' => $LockType,
            'BaleType'=>$BaleType,
            'order_type'=>$order_type,
            'difficulty_level'=>$difficulty_level,
            'jewellery_certificate_req'=>$jewellery_certificate_req,
            'Priority'=>$Priority,
            'DiamondType' => $DiamondType,
            'DiamondShape' => $DiamondShape,
            'CaratWeight'=>$CaratWeight,
            'StoneColor'=>$StoneColor,
            'MetalPurity'=>$MetalPurity,
            'DiamondStockType'=>$DiamondStockType,
            'diamondorder'=>$diamondorder,
        ]);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param UpdateOrder $request
     * @param Order $order
     * @return array|RedirectResponse|Redirector
     */
    // public function update(UpdateOrder $request, Order $order)
    // {
    //     // Sanitize input
    //     $sanitized = $request->getSanitized();

    //     // Update changed values Order
    //     $order->update($sanitized);

    //     if ($request->ajax()) {
    //         return [
    //             'redirect' => url('admin/orders'),
    //             'message' => trans('brackets/admin-ui::admin.operation.succeeded'),
    //         ];
    //     }

    //     return redirect('admin/orders');
    // }

    // public function update(UpdateOrder $request, Order $order)
    // {

    //     dd($request->all());
    //     // Sanitize input
    //     $sanitized = $request->getSanitized();

    //     // Update changed values in Order
    //     $order->update($sanitized);

    //     // Retrieve dynamicFields from the request
    //     $dynamicFields = $request->input('dynamicFields', []);

    //     // Sync the dynamicFields with the diamond_order table
    //     // First, delete old dynamic fields that are not in the new request
    //     $existingDynamicFields = DiamondOrder::where('order_id', $order->id)->pluck('id')->toArray();
    //     $newDynamicFields = [];

    //     foreach ($dynamicFields as $dynamicField) {
    //         $dynamicField['order_id'] = $order->id; // Ensure order_id is set

    //         if (isset($dynamicField['id'])) {
    //             // Update existing dynamic field
    //             DiamondOrder::where('id', $dynamicField['id'])->update($dynamicField);
    //             // Remove from existing list since it's updated
    //             $existingDynamicFields = array_diff($existingDynamicFields, [$dynamicField['id']]);
    //         } else {
    //             // Create new dynamic field
    //             DiamondOrder::create($dynamicField);
    //         }
    //     }

    //     // Delete dynamic fields that are no longer present
    //     if (!empty($existingDynamicFields)) {
    //         DiamondOrder::whereIn('id', $existingDynamicFields)->delete();
    //     }

    //     if ($request->ajax()) {
    //         return [
    //             'redirect' => url('admin/orders'),
    //             'message' => trans('brackets/admin-ui::admin.operation.succeeded'),
    //         ];
    //     }

    //     return redirect('admin/orders');
    // }

    public function update(UpdateOrder $request, Order $order)
{
    // Debug request data
    // dd($request->all());

    // Sanitize input
    $sanitized = $request->getSanitized();

    // Remove fields that should not be updated
    unset($sanitized['created_at']); // Exclude created_at from update
    unset($sanitized['created_by']); // If you have this field and it should not be updated

    // Convert datetime fields to a valid format
    if (isset($sanitized['updated_at'])) {
        $sanitized['updated_at'] = $this->formatDatetime($sanitized['updated_at']);
    }

    // Update changed values in Order
    $order->update($sanitized);

    // Retrieve dynamicFields from the request
    $dynamicFields = $request->input('dynamicFields', []);



    // Sync the dynamicFields with the diamond_order table
    // First, delete old dynamic fields that are not in the new request
    $existingDynamicFields = DiamondOrder::where('order_id', $order->id)->pluck('id')->toArray();


    foreach ($dynamicFields as $dynamicField) {

        unset($dynamicField['resource_url']);
        if (isset($dynamicField['updated_at'])) {
            $dynamicField['updated_at'] = $this->formatDatetime($dynamicField['updated_at']);
        }
        if (isset($dynamicField['created_at'])) {
            unset($dynamicField['created_at']); // Exclude created_at from dynamic field update
        }


        $dynamicField['order_id'] = $order->id; // Ensure order_id is set

     
        if (isset($dynamicField['id'])) {
      
            // Update existing dynamic field
            DiamondOrder::where('id', $dynamicField['id'])->update($dynamicField);
            // Remove from existing list since it's updated
            $existingDynamicFields = array_diff($existingDynamicFields, [$dynamicField['id']]);
        } else {
    
            // Create new dynamic field
            DiamondOrder::create($dynamicField);
        }
    }

    // Delete dynamic fields that are no longer present
    if (!empty($existingDynamicFields)) {
        DiamondOrder::whereIn('id', $existingDynamicFields)->delete();
    }


    if ($request->ajax()) {
        return [
            'redirect' => url('admin/orders'),
            'message' => trans('brackets/admin-ui::admin.operation.succeeded'),
        ];
    }

    return redirect('admin/orders');
}

// Helper function to format datetime
protected function formatDatetime($datetime)
{
    return \Carbon\Carbon::parse($datetime)->format('Y-m-d H:i:s');
}

    




    /**
     * Remove the specified resource from storage.
     *
     * @param DestroyOrder $request
     * @param Order $order
     * @throws Exception
     * @return ResponseFactory|RedirectResponse|Response
     */
    public function destroy(DestroyOrder $request, Order $order)
    {
        $order->delete();

        if ($request->ajax()) {
            return response(['message' => trans('brackets/admin-ui::admin.operation.succeeded')]);
        }

        return redirect()->back();
    }

    /**
     * Remove the specified resources from storage.
     *
     * @param BulkDestroyOrder $request
     * @throws Exception
     * @return Response|bool
     */
    public function bulkDestroy(BulkDestroyOrder $request) : Response
    {
        DB::transaction(static function () use ($request) {
            collect($request->data['ids'])
                ->chunk(1000)
                ->each(static function ($bulkChunk) {
                    Order::whereIn('id', $bulkChunk)->delete();

                    // TODO your code goes here
                });
        });

        return response(['message' => trans('brackets/admin-ui::admin.operation.succeeded')]);
    }
}
