<?php

namespace App\Http\Controllers\Medicine;

use App\Helpers\ValidationHelper;
use App\Http\Controllers\Controller;
use App\Mail\PurchaseMail;
use App\Models\LeafSetting;
use App\Models\Medicine;
use App\Models\MedicineCompany;
use App\Models\Purchase;
use App\Models\Stock;
use App\Models\Supplier;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
use Illuminate\Validation\Validator;
use Mockery\Exception;

class PurchaseController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index()
    {
        try {
            return successResponseWithData(Purchase::query()->with('stocks')->where('user_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 pre_required_data(): JsonResponse
    {
        try {
            return successResponseWithData([
                'suppliers' => Supplier::query()->with('medicineCompany:id,company_name')->where(['user_id' => Auth::id()])->orderBy('id', 'DESC')->get(['id', 'medicine_company_id', 'supplier_name', 'supplier_email']),
            ], 'success', 200);
        } catch (Exception $exception) {
            return errorResponse($exception, 500);
        }
    }

    public function search_medicine(Request $request): JsonResponse
    {
        $validator = ValidationHelper::validator($request, [
            'supplier_id' => 'required|integer|exists:suppliers,id',
        ]);
        if ($validator->fails()) {
            return validationErrorResponse($validator);
        }
        try {
            $supplier = Supplier::query()->find($request->supplier_id, ['medicine_company_id']);
            return successResponseWithData([
                'medicines' => Medicine::query()->where(function ($query){
                    $query->where('user_id', Auth::id())->orWhere('user_id', Auth::user()->create_by);
                })->where(['medicine_company_id' => $supplier->medicine_company_id, 'status' => '1'])->where('medicine_name', 'LIKE', "%$request->medicine_name%")->orderBy('id', 'DESC')->get(['id', 'leaf_setting_id', 'medicine_name', 'qty', 'box_mrp', 'supplier_price']),
            ], 'success', 200);
        } catch (Exception $exception) {
            return errorResponse($exception, 500);
        }
    }

    public function validation($request, $additionalRules = []): Validator
    {
        // Default validation rules
        $rules = [
            'supplier_id' => 'required|integer|exists:suppliers,id',
            'data.*.medicine_id' => 'required|exists:medicines,id',
            'data.*.leaf_qty' => 'required',
            'data.*.supplier_price' => 'required|numeric|min:1',
            'data.*.box_mrp' => 'required|numeric|min:1',
            'data.*.sell_price' => 'required|numeric|min:1',
            'vat' => 'required',
            'discount' => 'required',
            'status' => '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 {
                $purchase = Purchase::newPurchase($request);
                $stocks = Stock::newStock($request, $purchase);
                Purchase::updateFinancialInfo($purchase, $stocks);
                if ($purchase->status == '0') {
                    $supplier = Supplier::query()->with('medicineCompany:id,company_name')->findOrFail($request->supplier_id, ['id', 'medicine_company_id', 'supplier_name', 'supplier_email', 'supplier_phone']);
                    Mail::to($supplier->supplier_email ?? 'atikurrahman1587@gmail.com')->send(new PurchaseMail($stocks, ['company_name' => $supplier->medicineCompany->company_name, 'supplier_name' => $supplier->supplier_name, 'supplier_phone' => $supplier->supplier_phone]));
                }
            } catch (Exception $exception) {
                DB::rollBack();

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

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

    /**
     * Display the specified resource.
     */
    public function show(string $id): JsonResponse
    {
        try {
            return successResponseWithData([
                'purchase' => Purchase::query()->with('stocks')->where(['user_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' => Purchase::query()->with('stocks')->where(['user_id' => Auth::id(), 'id' => $id, 'status' => '0'])->first(),
            ], 'success', 200);
        } catch (Exception $exception) {
            return errorResponse($exception, 500);
        }
    }

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

        try {
            $purchase = Purchase::query()->where(['user_id' => Auth::id(), 'status' => '0'])->find($id);
            $originalPurchase = $purchase->replicate();
            DB::beginTransaction();
            try {
                $updatePurchase = Purchase::updatePurchase($request, $purchase);
                if ($updatePurchase->status != '2') {
                    $stocks = Stock::updateStock($request, $updatePurchase, $originalPurchase);
                    Purchase::updateFinancialInfo($updatePurchase, $stocks);
                }

                if ($originalPurchase->status == '0' && $updatePurchase->status == '0') {
                    $supplier = Supplier::query()->with('medicineCompany:id,company_name')->findOrFail($request->supplier_id, ['id', 'medicine_company_id', 'supplier_name', 'supplier_email', 'supplier_phone']);
                    Mail::to($supplier->supplier_email)->send(new PurchaseMail($stocks, $supplier));
                }
            } catch (Exception $exception) {
                DB::rollBack();

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

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

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