<?php

namespace App\Http\Controllers\Admin\Pos;

use App\Http\Controllers\Controller;
use App\Models\Client;
use App\Models\SalesMaster;
use App\Models\SalesReturnDetails;
use App\Models\SalesReturnMaster;
use App\Models\Shop;
use App\Models\Supplier;
use App\Models\UsedProductDetails;
use App\Models\UsedProductMaster;
use App\Models\Warehouse;
use App\Models\WarehouseStock;
use App\Service\Pos\PosService;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Inertia\Inertia;

class SalesController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index()
    {
        return Inertia::render('Pos/Sales');
    }

    /**
     * Display the specified resource.
     */
    public function show(string $id)
    {
        $sale = SalesMaster::with([
            'details', // includes product + arribute + WareHouse (see SalesMaster model)
            'customer',
            'salesPerson',
            'customerPayment',
            'bank',
            'mobile',
            'transitionLocation',
            'User',
        ])->findOrFail($id);

        return Inertia::render('Pos/SalesSingleView', [
            'sale' => $sale,
        ]);
    }

    public function edit($id)
    {
        $warehouse = Warehouse::get();
        $salesEdit = SalesMaster::with('details', 'customer', 'salesPerson', 'customerPayment')
            ->where('id', $id)
            ->first();

        return Inertia::render('Pos/Pos', compact('warehouse', 'salesEdit'));
    }

    public function view()
    {
        // Check if pagination parameters are provided
        if (request()->has(['rows', 'page']) || request()->has('search')) {
            return $this->getPaginatedSales();
        }
    }

    public function getPaginatedSales()
    {
        $perPage = request('rows', 10);
        $page = request('page', 0);
        $search = request('search', '');

        $query = SalesMaster::with('details', 'user', 'customer', 'transitionLocation', 'salesPerson', 'updatedBy')
            ->orderByDesc('id');

        // Apply search filter if provided
        if (! empty($search)) {
            $query->where(function ($q) use ($search) {
                $q->where('invoice_no', 'LIKE', "%{$search}%")
                    ->orWhereDate('created_at', $search)
                    ->orWhereHas('customer', function ($customerQuery) use ($search) {
                        $customerQuery->where(function ($cq) use ($search) {
                            $cq->where('name', 'LIKE', "%{$search}%")
                                ->orWhere('number', 'LIKE', "%{$search}%")
                                ->orWhere('code', 'LIKE', "%{$search}%");
                        });
                    });
            });
        }

        // Get paginated results
        $sales = $query->paginate($perPage, ['*'], 'page', $page + 1);
        $shop = Shop::where('id', Auth::user()->shop_id)->first();

        return response()->json([
            'sales' => $sales->items(),
            'totalRecords' => $sales->total(),
            'currentPage' => $sales->currentPage() - 1, // Convert back to 0-based
            'lastPage' => $sales->lastPage() - 1,
            'perPage' => $sales->perPage(),
            'shop' => $shop,
        ]);
    }

    public function print($id)
    {
        $sales = SalesMaster::with('details', 'details.product', 'details.arribute', 'user', 'customer', 'exchangeReturn')
            ->where('id', $id)->orderbydesc('id')->first();

        return Inertia::render('Pos/Print', ['sales' => $sales]);
    }

    public function destroy($id)
    {

        PosService::SalesDelete($id);
        DB::table('customer_payment_collections')->where('invoice_id', $id)->delete();

        return response()->json(['success' => 'Data Delete Successfully']);
    }

    public function salseReturn()
    {
        return Inertia::render('Pos/SalesReturn');
    }

    public function salesReturnGetData()
    {
        return SalesReturnMaster::with('client', 'invoice', 'details', 'detailsTotal', 'location')->where('status', 1)->orderby('id', 'DESC')->get();
    }

    public function returnView()
    {

        // Reference No
        $invoice_no = SalesReturnMaster::withoutGlobalScope('typeScope')->orderBy('id', 'desc')->first();

        $reference = invoice_no($invoice_no?->id, 'SR');

        $client = Client::limit('20')->get();
        $salesReturn = $this->salesReturnGetData();

        return response()->json(['reference' => $reference, 'client' => $client, 'salesReturn' => $salesReturn]);
    }

    public function salseReturnStore()
    {

        PosService::SalesReturn(request()->all());

        $invoice_no = SalesReturnMaster::withoutGlobalScope('typeScope')->orderBy('id', 'desc')->first();

        $next_number = invoice_no($invoice_no?->id, 'SR');

        $reference = $next_number;
        $salesReturn = $this->salesReturnGetData();

        return response()->json(['success' => 'Return Successfully', 'reference' => $reference, 'salesReturn' => $salesReturn]);
    }

    public function salseReturnUpdate($id)
    {
        PosService::SalesReturnUpdate(request()->all(), $id);
        $salesReturn = $this->salesReturnGetData();

        return response()->json(['success' => 'Return Update Successfully', 'salesReturn' => $salesReturn]);
    }

    public function directReturn()
    {
        return Inertia::render('Pos/DirectReturn');
    }

    public function DirectReturnView()
    {

        $salesReturn = SalesReturnMaster::orderby('reference_no', 'DESC')->first();
        $reference = invoice_no($salesReturn?->id ?? false, 'DR');

        $suppliers = Supplier::get();
        $salesReturn = SalesReturnMaster::with('client', 'invoice', 'details', 'detailsTotal', 'policy')->where('status', 2)->orderby('id', 'DESC')->get();

        return response()->json(['reference' => $reference, 'salesReturn' => $salesReturn, 'suppliers' => $suppliers]);
    }

    public function DirectReturnStore()
    {

        PosService::DirectReturn(request()->all());
        $salesReturn = SalesReturnMaster::orderby('reference_no', 'DESC')->first();
        $reference = invoice_no($salesReturn?->id ?? false, 'DR');

        $salesReturn = SalesReturnMaster::with('client', 'invoice', 'details', 'detailsTotal', 'policy')->where('status', 2)->orderby('id', 'DESC')->get();

        return response()->json(['reference' => $reference, 'salesReturn' => $salesReturn]);
    }

    public function DirectReturnUpdate($id)
    {
        PosService::DirectReturnUpdate(request()->all(), $id);

        $salesReturn = SalesReturnMaster::orderby('reference_no', 'DESC')->first();
        $reference = invoice_no($salesReturn?->id ?? false, 'DR');

        $salesReturn = SalesReturnMaster::with('client', 'invoice', 'details', 'detailsTotal', 'policy')->where('status', 2)->orderby('id', 'DESC')->get();

        return response()->json(['reference' => $reference, 'salesReturn' => $salesReturn]);
    }

    public function salesReturnDelete($id)
    {

        $salesMaster = SalesReturnMaster::where('id', $id)->first();
        $parentDetails = SalesReturnDetails::where('sales_return_master_id', $id)->get();

        foreach ($parentDetails as $key => $item) {
            WarehouseStock::where('attribute_id', $item->attribute_id)
                ->where('warehouse_id', $salesMaster->location_id)
                ->update([
                    'quantity' => DB::raw('quantity - '.$item->return_qty),
                ]);
        }
        $salesMaster->delete();

        $invoice_no = SalesReturnMaster::withoutGlobalScope('typeScope')->orderBy('id', 'desc')->first();

        $reference = invoice_no($invoice_no?->id, 'SR');

        $salesReturn = $this->salesReturnGetData();

        return response()->json(['success' => 'Data Delete successfully', 'reference' => $reference, 'salesReturn' => $salesReturn]);
    }

    public function usedProduct()
    {
        return Inertia::render('Shops/UsedProduct');
    }

    public function UsedProductView()
    {
        // Check if pagination parameters are provided
        if (request()->has(['page', 'perPage']) || request()->has('search')) {
            return $this->getPaginatedUsedProducts();
        }

        // Return reference number for form
        $lastUsedProduct = UsedProductMaster::orderBy('id', 'DESC')->first();
        $reference = invoice_no($lastUsedProduct?->id ?? false, 'UP');

        return response()->json([
            'reference' => $reference,
        ]);
    }

    public function getPaginatedUsedProducts()
    {
        $perPage = request('perPage', 10);
        $page = request('page', 1);
        $search = request('search', '');

        $query = UsedProductMaster::with('details', 'detailsTotal', 'location')
            ->orderBy('id', 'DESC');

        // Apply search filter if provided
        if (! empty($search)) {
            $query->where(function ($q) use ($search) {
                $q->where('reference_no', 'LIKE', "%{$search}%")
                    ->orWhereDate('used_date', $search)
                    ->orWhere('total', 'LIKE', "%{$search}%");
            });
        }

        // Get paginated results
        $usedProducts = $query->paginate($perPage, ['*'], 'page', $page);

        return response()->json([
            'usedProducts' => $usedProducts,
        ]);
    }

    public function UsedProductStore()
    {
        PosService::UsedProduct(request()->all());

        return response()->json([
            'success' => 'Used Product Saved Successfully',
        ]);
    }

    public function UsedProductUpdate($id)
    {
        PosService::UsedProductUpdate(request()->all(), $id);

        return response()->json([
            'success' => 'Used Product Updated Successfully',
        ]);
    }

    public function usedProductDelete($id)
    {
        $usedProductMaster = UsedProductMaster::where('id', $id)->first();
        $parentDetails = UsedProductDetails::where('used_product_master_id', $id)->get();

        foreach ($parentDetails as $key => $item) {
            WarehouseStock::where('attribute_id', $item->attribute_id)
                ->where('warehouse_id', $usedProductMaster->location_id)
                ->update([
                    'quantity' => DB::raw('quantity + '.$item->used_qty),
                ]);
        }
        $usedProductMaster->delete();

        return response()->json([
            'success' => 'Data Delete successfully',
        ]);
    }
}
