<?php

namespace App\Http\Controllers\Medicine;

use App\Helpers\ValidationHelper;
use App\Http\Controllers\Controller;
use App\Models\Customer;
use App\Models\Medicine;
use App\Models\Order;
use App\Models\SoldOutMedicine;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\Validator;
use Mockery\Exception;

class OrderController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index()
    {
        try {
            return successResponseWithData(Order::query()->with('medicines')->where('staff_id', '=', Auth::id())->orderBy('id', 'DESC')->paginate(10), 'success', 200);
        } catch (Exception $exception) {
            return errorResponse($exception, 500);
        }
    }

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

    public function search_customer(Request $request): JsonResponse
    {
        try {
            $customers = Customer::query()
                ->where('user_id', Auth::user()->create_by)
                ->where('name', 'LIKE', "%$request->name%")
                ->orderBy('id', 'DESC')
                ->with(['orders.medicines.medicine:id,medicine_name,qty,box_mrp,sell_price'])
                ->get(['id', 'name', 'phone', 'address', 'customer_type']);

            $customers->transform(function ($customer) {
                if ($customer->customer_type === 'fixed') {
                    // collect all medicines across all orders
                    $medicines = $customer->orders->flatMap(function ($order) {
                        return $order->medicines->map(function ($sold) {
                            return [
                                'id'   => $sold->medicine->id,
                                'name' => $sold->medicine->name,
                            ];
                        });
                    });

                    // filter only unique medicines
                    $uniqueMedicines = $medicines->unique('id')->values();

                    // push medicines key
                    $customer->setAttribute('medicines', $uniqueMedicines);
                } else {
                    $customer->setAttribute('medicines', []);
                }

                // remove orders from response (optional, keep clean)
                unset($customer->orders);

                return $customer;
            });

            return successResponseWithData([
                'customers' => $customers,
            ], 'success', 200);
        } catch (Exception $exception) {
            return errorResponse($exception, 500);
        }
    }


    public function search_medicine(Request $request): JsonResponse
    {
        try {
            return successResponseWithData([
                'medicines' => Medicine::query()->where(function ($query){
                    $query->where('user_id', Auth::id())->orWhere('user_id', Auth::user()->create_by);
                })->where(['status' => '1'])->where('medicine_name', 'LIKE', "%$request->medicine_name%")->orderBy('id', 'DESC')->get(['id', 'medicine_name', 'qty', 'box_mrp', 'sell_price']),
            ], 'success', 200);
        } catch (Exception $exception) {
            return errorResponse($exception, 500);
        }
    }

    public function validation($request, $additionalRules = []): Validator
    {
        // Default validation rules
        $rules = [
            'customer_id' => 'required|integer|exists:customers,id',
            'data.*.medicine_id' => 'required|exists:medicines,id',
            'data.*.sku_qty' => 'required',
            'data.*.sell_price' => 'required|numeric|min:1',
            'data.*.discount' => 'required|numeric|min:0',
            'data.*.total_sell_price' => 'required|numeric|min:1',
//            'date' => 'required',
            'subtotal' => 'required',
            'discount' => 'required',
            'grand_total' => 'required',
        ];

        // Merge the additional rules dynamically
        $rules = array_merge($rules, $additionalRules);

        // Return the validator with combined rules
        return ValidationHelper::validator($request, $rules);
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request): JsonResponse
    {
        $validator = $this->validation($request);
        if ($validator->fails()) {
            return validationErrorResponse($validator);
        }
        try {
            DB::beginTransaction();
            try {
                $order = Order::newOrder($request);
                SoldOutMedicine::newSold($request, $order);
                $data = Order::query()->with('medicines')->find($order->id);
            } catch (Exception $exception) {
                DB::rollBack();

                return errorResponse($exception, 500);
            }
            DB::commit();

            return successResponseWithData($data, 'Create successfully', 201);
        } catch (Exception $exception) {
            return errorResponse($exception, 500);
        }
    }

    /**
     * Display the specified resource.
     */
    public function show(string $id): JsonResponse
    {
        try {
            return successResponseWithData([
                'Order' => Order::query()->with('medicines')->where(['staff_id' => Auth::id(), 'id' => $id])->first(),
            ], 'success', 200);
        } catch (Exception $exception) {
            return errorResponse($exception, 500);
        }
    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit(string $id): JsonResponse
    {
        try {
            return successResponseWithData([
                'purchase' => Order::query()->with('medicines')->where(['staff_id' => Auth::id(), 'id' => $id])->first(),
            ], 'success', 200);
        } catch (Exception $exception) {
            return errorResponse($exception, 500);
        }
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, string $id): JsonResponse
    {
        $validator = $this->validation($request, [
            'id' => 'required|integer|exists:orders,id',
            'data.*.id' => 'required|exists:sold_out_medicines,id',
        ]);
        if ($validator->fails()) {
            return validationErrorResponse($validator);
        }

        try {
            $order = Order::query()->where(['staff_id' => Auth::id()])->find($id);
            DB::beginTransaction();
            try {
                $updateOrder = Order::updateOrder($request, $order);
                SoldOutMedicine::updateSold($request, $updateOrder);
                $data = Order::query()->with('medicines')->find($updateOrder->id);
            } catch (Exception $exception) {
                DB::rollBack();

                return errorResponse($exception, 500);
            }
            DB::commit();

            return successResponseWithData($data, 'Update successfully', 200);
        } catch (Exception $exception) {
            return errorResponse($exception, 500);
        }
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(string $id)
    {
        //
    }
}
