<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Product;
use App\Models\Contact;
use App\Models\MultiUnit;
use App\Models\Contacttype;
use App\Models\Priceproduct;
use App\Models\ProductsWholesale;
use App\Models\Substocktransaction;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class ProductController extends Controller
{
    public function getProductTotal(Request $request)
    {
        try {
            $total = Product::count();

            return response()->json([
                'success' => true,
                'total'   => $total
            ], 200);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Gagal mengambil total produk'
            ], 500);
        }
    }

    public function getProductAll(Request $request)
    {
        $query = Product::with('producttype', 'unit', 'rack', 'nettounit', 'brutounit');

        if ($request->has('for_sale')) {
            $query->where('for_sale', filter_var($request->for_sale, FILTER_VALIDATE_BOOLEAN));
        }

        if ($request->has('for_purchase')) {
            $query->where('for_purchase', filter_var($request->for_purchase, FILTER_VALIDATE_BOOLEAN));
        }

        $data = $query->orderBy('id', 'desc')->get();

        foreach ($data as &$d) {
            $d['multi_unit'] = MultiUnit::with('multi_unit')->whereIn('product_id', [$d->id])->get();

            // Concatenate codes from $data and $multi_unit
            $d['full_code'] = $d->code;
            foreach ($d['multi_unit'] as $multi_unit) {
                if (isset($multi_unit->multi_code)) {
                    $d['full_code'] .= ', ' . $multi_unit->multi_code;
                }
            }
        }

        $response = [
            'success' => true,
            'product' => $data,
        ];

        return response($response, 200);
    }

    public function getProductAllPerPage(Request $request)
    {
        $limit = $request->get('limit', 50);

        $query = Product::with('producttype', 'unit', 'rack', 'nettounit', 'brutounit');

        if ($request->has('for_sale')) {
            $query->where('for_sale', filter_var($request->for_sale, FILTER_VALIDATE_BOOLEAN));
        }

        if ($request->has('for_purchase')) {
            $query->where('for_purchase', filter_var($request->for_purchase, FILTER_VALIDATE_BOOLEAN));
        }

        // Gunakan paginate di sini
        $data = $query->orderBy('id', 'desc')->paginate($limit);

        // Map data untuk menambahkan multi_unit dan full_code
        $data->getCollection()->transform(function ($d) {
            $d['multi_unit'] = MultiUnit::with('multi_unit')
                ->where('product_id', $d->id)
                ->get();

            $d['full_code'] = $d->code;
            foreach ($d['multi_unit'] as $multi_unit) {
                if (isset($multi_unit->multi_code)) {
                    $d['full_code'] .= ', ' . $multi_unit->multi_code;
                }
            }
            return $d;
        });

        $customPagination = [
            'current_page' => $data->currentPage(),
            'data' => $data->items(),
            'from' => $data->firstItem(),
            'to' => $data->lastItem(),
            'per_page' => $data->perPage(),
            'total' => $data->total(),
            'last_page' => $data->lastPage(),
        ];

        $response = [
            'success' => true,
            'product' => $customPagination,
        ];

        return response($response, 200);
    }

    public function getProductSale(Request $request)
    {
        $for_sale = isset($request->for_sale) ? (bool)json_decode($request->for_sale) : 2;

        $query = Product::with('producttype', 'unit', 'rack', 'nettounit', 'brutounit')->where('qty', '>', '0');

        if ($for_sale !== 2) {
            $query->where('for_sale', $for_sale);
        }

        $data = $query->orderBy('id', 'desc')->get();

        foreach ($data as &$d) {
            $d['multi_unit'] = MultiUnit::with('multi_unit')->whereIn('product_id', [$d->id])->get();
            $d['qty_jual'] = 0;

            // Concatenate codes from $data and $multi_unit
            $d['full_code'] = $d->code;
            foreach ($d['multi_unit'] as $multi_unit) {
                if (isset($multi_unit->multi_code)) {
                    $d['full_code'] .= ', ' . $multi_unit->multi_code;
                }
            }
        }

        $response = [
            'success' => true,
            'product' => $data,
        ];

        return response($response, 200);
    }

    public function getProductSalePerPage(Request $request)
    {
        $limit = $request->input('limit', 50);
        $for_sale = isset($request->for_sale) ? (bool)json_decode($request->for_sale) : 2;

        // Subquery untuk menghitung total penjualan
        $subQuery = Substocktransaction::select('product_id', DB::raw('SUM(qty) as total_sold'))
            ->whereNotNull('hpp')
            ->whereNotNull('selling_price')
            ->groupBy('product_id');

        // Query produk + join total_sold
        $query = Product::with('producttype', 'unit', 'rack', 'nettounit', 'brutounit')
            ->leftJoinSub($subQuery, 'sales', function ($join) {
                $join->on('products.id', '=', 'sales.product_id');
            })
            ->select('products.*', DB::raw('COALESCE(sales.total_sold, 0) as total_sold'))
            ->where('qty', '>', '0')
            ->orderByDesc('total_sold')
            ->orderByDesc('id'); // kalau penjualan sama, urutkan terbaru

        if ($for_sale !== 2) {
            $query->where('for_sale', $for_sale);
        }

        // Paginasi
        $data = $query->paginate($limit);

        // Manipulasi data setelah paginasi
        foreach ($data as &$d) {
            // Multi unit
            $d['multi_unit'] = MultiUnit::with('multi_unit')
                ->where('product_id', $d->id)
                ->get();

            $d['qty_jual'] = 0;

            // Full code gabungan
            $d['full_code'] = $d->code;
            foreach ($d['multi_unit'] as $multi_unit) {
                if (isset($multi_unit->multi_code)) {
                    $d['full_code'] .= ', ' . $multi_unit->multi_code;
                }
            }

            // Best seller flag (true kalau total_sold sama dengan penjualan tertinggi)
            $maxSold = $data->max('total_sold');
            $d['is_best_seller'] = $d->total_sold > 0 && $d->total_sold == $maxSold;
        }

        $customPagination = [
            'current_page' => $data->currentPage(),
            'data' => $data->items(),
            'from' => $data->firstItem(),
            'to' => $data->lastItem(),
            'per_page' => $data->perPage(),
            'total' => $data->total(),
            'last_page' => $data->lastPage(),
        ];

        $response = [
            'success' => true,
            'product' => $customPagination,
        ];

        return response($response, 200);
    }

    public function getProducttt(Request $request)
    {
        $for_sale = isset($request->for_sale) ? (bool)json_decode($request->for_sale) : 2;
        if (isset($request->contact_id)) {
            $query = Product::with('producttype', 'unit', 'rack', 'nettounit', 'brutounit')->where('qty', '>', '0');

            if ($for_sale !== 2) {
                $query->where('for_sale', $for_sale);
            }

            $data = $query->orderBy('id', 'desc')->get();

            $customer = Contact::with('type')->where('id', $request->contact_id)->first();
            $total = $data->count();
            foreach ($data as $key => $value) {
                $value['no'] = $total - $key;
                if ($value->pricing_schema == "harga_contact") {
                    if (!empty($customer->type()->first())) {
                        $value['price'] = Priceproduct::where('product_id', $value->id)
                            ->where('contact_type', $customer->type()->first()->id)->get();

                        foreach ($value['price'] as $keyVal => $val) {
                            if ($val->multi_unit_id == null) {
                                $value->selling_price = $val->total;
                            }
                        }
                    }
                }

                $value['multi_unit'] = MultiUnit::with('multi_unit')
                    ->where('product_id', $value->id)
                    ->get();
                $value['qty_jual'] = 0;

                // Concatenate codes from $data and $multi_unit
                $value['full_code'] = $value->code;
                foreach ($value['multi_unit'] as $multi_unit) {
                    if (isset($multi_unit->multi_code)) {
                        $value['full_code'] .= ', ' . $multi_unit->multi_code;
                    }
                }
            }
        } else {
            $query = Product::with('producttype', 'unit', 'rack', 'nettounit', 'brutounit');

            if ($for_sale !== 2) {
                $query->where('for_sale', $for_sale);
            }

            $data = $query->orderBy('id', 'desc')->get();

            $total = $data->count();
            foreach ($data as $key => &$d) {
                $d['no'] = $total - $key;
                $d['multi_unit'] = MultiUnit::with('multi_unit')->whereIn('product_id', [$d->id])->get();
                $d['qty_jual'] = 0;

                // Concatenate codes from $data and $multi_unit
                $d['full_code'] = $d->code;
                foreach ($d['multi_unit'] as $multi_unit) {
                    if (isset($multi_unit->multi_code)) {
                        $d['full_code'] .= ', ' . $multi_unit->multi_code;
                    }
                }
            }
        }

        $response = [
            'success' => true,
            'product' => $data,
        ];

        return response($response, 200);
    }

    public function getProduct(Request $request)
    {
        $for_sale = isset($request->for_sale) ? (bool)json_decode($request->for_sale) : 2;
        // Get customer and customer type first to determine eager loading
        $customer = null;
        $customerTypeId = null;
        if ($request->has('contact_id')) {
            $customer = Contact::with('type')->where('id', $request->contact_id)->first();
            $customerTypeId = $customer?->type?->id ?? $customer?->type()->first()?->id;
        }

        // Build query with conditional eager loading
        $with = ['producttype', 'unit', 'rack', 'nettounit', 'brutounit', 'multiUnits.multi_unit'];

        if ($customerTypeId) {
            $with[] = 'price';
            $query = Product::with($with)->with(['price' => function ($q) use ($customerTypeId) {
                $q->where('contact_type', $customerTypeId);
            }]);
        } else {
            $query = Product::with($with);
        }

        if ($for_sale !== 2) {
            $query->where('for_sale', $for_sale);
        }

        $data = $query->orderBy('id', 'desc')->get();
        $total = $data->count();

        // Process data using eager loaded relations
        foreach ($data as $key => $value) {
            $value['no'] = $total - $key;

            // Handle pricing schema using eager loaded relation
            if ($value->pricing_schema == "harga_contact" && $customerTypeId) {
                $value['price'] = $value->price; // Already filtered by contact_type

                // Set selling price from price with null multi_unit_id
                foreach ($value->price as $price) {
                    if ($price->multi_unit_id == null) {
                        $value->selling_price = $price->total;
                        break; // Exit after finding the first match
                    }
                }
            }

            // Set multi_unit from eager loaded relation
            $value['multi_unit'] = $value->multiUnits;
            $value['qty_jual'] = 0;

            // Build full_code efficiently using eager loaded multi units
            $codes = [$value->code];
            foreach ($value->multiUnits as $multi_unit) {
                if (isset($multi_unit->multi_code)) {
                    $codes[] = $multi_unit->multi_code;
                }
            }
            $value['full_code'] = implode(', ', $codes);
        }

        return response()->json([
            'success' => true,
            'product' => $data
        ], 200);
    }

    public function getProductPerPage(Request $request)
    {
        $limit = $request->input('limit', 20);
        $search = $request->input('search');

        $query = Product::with('producttype', 'price.multi_unit', 'unit', 'rack', 'nettounit', 'brutounit', 'multiUnits.multi_unit', 'productWholesale.product.unit', 'productWholesale.multiunit.multi_unit')
            ->orderBy('id', 'desc');

        // 🔍 Filter pencarian
        if (!empty($search)) {
            $query->where(function ($q) use ($search) {
                $q->where('name', 'like', "%$search%")
                    ->orWhere('code', 'like', "%$search%")
                    ->orWhere('id', 'like', "%$search%")
                    ->orWhereHas('unit', function ($uq) use ($search) {
                        $uq->where('name', 'like', "%$search%");
                    })
                    ->orWhereHas('rack', function ($rq) use ($search) {
                        $rq->where('name', 'like', "%$search%");
                    });
            });
        }

        // 🧩 Filter tambahan dari dialog
        if ($request->filled('product_type')) {
            $query->where('producttype', $request->product_type);
        }

        if ($request->filled('display_rack')) {
            $query->where('display_rack_v2', $request->display_rack);
        }

        if ($request->filled('qty')) {
            if ($request->qty === 'no_stock') {
                $query->where('qty', '<=', 0);
            } elseif ($request->qty === 'available') {
                $query->where('qty', '>', 0)->where('category', '<>', 'service');
            } elseif ($request->qty === 'below_min') {
                $query->where('qty_minimum', '>', 0);
            }
        }

        if ($request->filled('category')) {
            $query->where('category', $request->category); // pastikan field `category` ada di tabel
        }

        if ($request->filled('for_sale')) {
            $query->where('for_sale', $request->for_sale);
        }

        if ($request->filled('for_purchase')) {
            $query->where('for_purchase', $request->for_purchase);
        }

        // hitung total sebelum pagination
        $totalData = (clone $query)->count();

        $data = $query->paginate($limit);

        $total = $data->total();
        $currentPage = $data->currentPage();
        $perPage = $data->perPage();

        foreach ($data as $key => &$d) {
            $d['no'] = $total - (($currentPage - 1) * $perPage + $key);
            $d['qty_jual'] = 0;
            $d['hide'] = true;

            // Gabungkan kode produk
            $d['full_code'] = $d->code;
            foreach ($d->multiUnits as $multi_unit) {
                if (isset($multi_unit->multi_code)) {
                    $d['full_code'] .= ', ' . $multi_unit->multi_code;
                }
            }
        }

        $customPagination = [
            'current_page' => $data->currentPage(),
            'data' => $data->items(),
            'from' => $data->firstItem(),
            'to' => $data->lastItem(),
            'per_page' => $data->perPage(),
            'total' => $data->total(),
            'last_page' => $data->lastPage(),
        ];

        return response()->json([
            'success' => true,
            'product' => $customPagination,
            'total' => $totalData,
        ]);
    }

    public function getProductMin(Request $request)
    {
        $query = Product::whereRaw('qty < qty_minimum');

        // Search functionality
        if (!empty($request->search)) {
            $search = $request->search;
            $query->where(function ($q) use ($search) {
                $q->where('name', 'like', "%{$search}%")
                    ->orWhere('code', 'like', "%{$search}%")
                    ->orWhere('id', 'like', "%{$search}%");
            });
        }

        // Order by yang paling butuh perhatian
        $query->orderByRaw('(qty_minimum - qty) DESC');

        // Paginate results
        $perPage = $request->limit ?: 10;
        $data = $query->paginate($perPage);

        // Custom pagination response
        $customPagination = [
            'current_page' => $data->currentPage(),
            'data' => $data->items(),
            'from' => $data->firstItem(),
            'to' => $data->lastItem(),
            'per_page' => $data->perPage(),
            'total' => $data->total(),
            'last_page' => $data->lastPage(),
        ];

        $response = [
            'success' => true,
            'product' => $customPagination,
            'message' => 'Data product minimum retrieved successfully'
        ];

        return response($response, 200);
    }

    public function getProductNameCode(Request $request)
    {
        $productNames = Product::whereNotNull('name')->orderBy('id', 'desc')->pluck('name');
        $productCodes = Product::whereNotNull('code')->orderBy('id', 'desc')->pluck('code');

        return response()->json([
            'success' => true,
            'product_names' => $productNames,
            'product_codes' => $productCodes,
        ]);
    }


    public function getProductLimit(Request $request)
    {
        if (isset($request->contact_id)) {
            $data = Product::with('producttype', 'price', 'unit', 'rack', 'nettounit', 'brutounit')->where('qty', '>', '0')->where('type', '=', 'limit')->get();
            $customer = Contact::with('type')->where('id', $request->contact_id)->first();
            foreach ($data as $key => $value) {
                if ($value->pricing_schema == "harga_contact") {
                    if (!empty($customer->type()->first())) {
                        $price = Priceproduct::where('product_id', $value->id)
                            ->where('contact_type', $customer->type()->first()->id)
                            ->first();
                        if (!empty($price)) {
                            $value->selling_price = $price->total;
                        }
                    }
                }
            }
        } else {

            $data = Product::with('producttype', 'price', 'unit', 'rack', 'nettounit', 'brutounit')->where('type', '=', 'limit')->get();
            foreach ($data as &$d) {
                $d['multi_unit'] = MultiUnit::with('multi_unit')->whereIn('product_id', [$d->id])->get();
            }
        }

        $response = [
            'success' => true,
            'product' => $data,
        ];

        return response($response, 200);
    }

    public function getPriceProduct(Request $request)
    {
        $data = Product::with('producttype', 'price', 'unit', 'rack', 'nettounit', 'brutounit')
            ->where('id', $request->id)
            ->first();

        $data['multi_unit'] = MultiUnit::with('multi_unit')
            ->where('product_id', $data->id)
            ->get();

        $data['contact'] = Contact::where('id', $request->contact_id)
            ->get();

        if ($data->pricing_schema == "harga_contact") {
            $customer = Contact::with('type')->where('id', $request->contact_id)->first();
            $data['is_contact'] = false;
            if (isset($request->contact_id)) {
                if (!empty($customer->type()->first())) {
                    $data['price'] = Priceproduct::where('product_id', $data->id)
                        ->where('contact_type', $customer->type()->first()->id)
                        ->get();

                    foreach ($data['price'] as $price) {
                        $data['is_contact'] = true;
                        if ($price->multi_unit_id === null) {
                            $data->selling_price = $price->total;
                            // break;
                        }
                    }
                }
            }
        }

        if ($data->pricing_schema == "harga_grosir") {
            if (isset($request->qty)) {
                $data['wholesale'] = ProductsWholesale::where('product_id', $data->id)
                    ->where('min_qty', '<=', $request->qty)
                    ->where(function ($query) use ($request) {
                        $query->whereNull('max_qty')
                            ->orWhere('max_qty', '>=', $request->qty);
                    })
                    ->get();

                foreach ($data['wholesale'] as $wholesale) {
                    if ($wholesale->multi_unit_id === null) {
                        $data->selling_price = $wholesale->price;
                        // break;
                    }
                }
            }
        }

        $response = [
            'success' => true,
            'product' => $data,
        ];

        return response($response, 200);
    }

    public function getProductGoods(Request $request)
    {
        // Buat query awal
        $query = Product::with('producttype', 'price', 'unit', 'rack', 'nettounit', 'brutounit')
            ->where('category', '<>', 'service');

        // Filter berdasarkan for_sale
        if ($request->has('for_sale')) {
            $query->where('for_sale', filter_var($request->for_sale, FILTER_VALIDATE_BOOLEAN));
        }

        // Filter berdasarkan for_purchase
        if ($request->has('for_purchase')) {
            $query->where('for_purchase', filter_var($request->for_purchase, FILTER_VALIDATE_BOOLEAN));
        }

        // Filter berdasarkan qty_gt
        if ($request->has('qty_gt')) {
            $query->where('qty', '>', $request->qty_gt);
        }

        // Filter berdasarkan code
        if ($request->has('code')) {
            $query->where(
                $request->boolean('code') ? fn($q) => $q->whereNotNull('code')
                    : fn($q) => $q->whereNull('code')
            );
        }

        // Ambil data setelah semua filter
        $data = $query->get();

        // Tambahkan data multi_unit & full_code
        foreach ($data as $product) {
            $product['multi_unit'] = MultiUnit::with('multi_unit')
                ->where('product_id', $product->id)
                ->get();

            $product['qty_jual'] = 0;

            // Concatenate codes
            $product['full_code'] = $product->code;
            foreach ($product['multi_unit'] as $multi_unit) {
                if (!empty($multi_unit->multi_code)) {
                    $product['full_code'] .= ', ' . $multi_unit->multi_code;
                }
            }
        }

        // Jika ada contact_id, sesuaikan harga
        if ($request->filled('contact_id')) {
            $customer = Contact::with('type')->find($request->contact_id);

            if ($customer && $customer->type) {
                $customerTypeName = $customer->type->name;

                foreach ($data as $value) {
                    $price = Priceproduct::where('product_id', $value->id)
                        ->where('name', $customerTypeName)
                        ->first();

                    if ($price) {
                        $value->selling_price = $price->total;
                    }
                }
            }
        }

        return response()->json([
            'success' => true,
            'product' => $data
        ], 200);
    }

    public function getProductGoodsPage(Request $request)
    {
        // Ambil parameter page & limit dari frontend
        $limit = $request->get('limit', 20);
        $page = $request->get('page', 1);

        // Query dasar
        if ($request->has('category')) {
            $query = Product::where('category', $request->category);
        } else {
            $query = Product::where('category', '<>', 'service');
        }

        // Filter berdasarkan producttype
        if ($request->has('producttype')) {
            $query->where('producttype', $request->producttype);
        }

        // Filter berdasarkan display_rack
        if ($request->has('display_rack')) {
            $query->where('display_rack_v2', $request->display_rack);
        }

        // Filter berdasarkan for_sale
        if ($request->has('for_sale')) {
            $query->where('for_sale', filter_var($request->for_sale, FILTER_VALIDATE_BOOLEAN));
        }

        // Filter berdasarkan for_purchase
        if ($request->has('for_purchase')) {
            $query->where('for_purchase', filter_var($request->for_purchase, FILTER_VALIDATE_BOOLEAN));
        }

        // Filter berdasarkan qty_gt
        if ($request->has('qty_gt')) {
            $query->where('qty', '>', $request->qty_gt);
        }

        if ($request->filled('qty')) {
            if ($request->qty === 'no_stock') {
                $query->where('qty', '<=', 0);
            } elseif ($request->qty === 'available') {
                $query->where('qty', '>', 0)->where('category', '<>', 'service');
            } elseif ($request->qty === 'below_min') {
                $query->where('qty_minimum', '>', 0);
            }
        }

        if ($request->has('search') && !empty($request->search)) {
            $search = $request->search;
            $query->where(function ($q) use ($search) {
                $q->where('name', 'like', "%{$search}%")
                    ->orWhere('code', 'like', "%{$search}%");
            });
        }

        $query->with('producttype', 'price', 'unit', 'rack', 'nettounit', 'brutounit');

        // Paginate sesuai page & limit
        $products = $query->paginate($limit, ['*'], 'page', $page);

        // Tambahan data per produk
        foreach ($products as $product) {
            $product['multi_unit'] = MultiUnit::with('multi_unit')
                ->where('product_id', $product->id)
                ->get();
            $product['qty_jual'] = 0;

            // Gabung kode utama dengan multi_code
            $product['full_code'] = $product->code;
            foreach ($product['multi_unit'] as $multi_unit) {
                if (!empty($multi_unit->multi_code)) {
                    $product['full_code'] .= ', ' . $multi_unit->multi_code;
                }
            }
        }

        return response([
            'success' => true,
            'product' => [
                'data' => $products->items(), // Array of product items
                'current_page' => $products->currentPage(),
                'last_page' => $products->lastPage(),
                'per_page' => $products->perPage(),
                'total' => $products->total(),
            ]
        ], 200);
    }

    public function getProductByCategory(Request $request, $category)
    {
        $query = Product::with('producttype', 'price', 'unit', 'rack', 'nettounit', 'brutounit')
            ->where('category', $category);

        if ($request->has('for_sale')) {
            $query->where('for_sale', filter_var($request->for_sale, FILTER_VALIDATE_BOOLEAN));
        }

        if ($request->has('for_purchase')) {
            $query->where('for_purchase', filter_var($request->for_purchase, FILTER_VALIDATE_BOOLEAN));
        }

        if ($request->has('qty_gt')) {
            $query->where('qty', '>', $request->qty_gt);
        }

        $data = $query->get();

        foreach ($data as $product) {
            $product['multi_unit'] = MultiUnit::with('multi_unit')
                ->where('product_id', $product->id)
                ->get();
            $product['qty_jual'] = 0;

            $product['full_code'] = $product->code;
            foreach ($product['multi_unit'] as $multi_unit) {
                if (!empty($multi_unit->multi_code)) {
                    $product['full_code'] .= ', ' . $multi_unit->multi_code;
                }
            }
        }

        if ($request->filled('contact_id')) {
            $customer = Contact::with('type')->find($request->contact_id);

            if ($customer && $customer->type) {
                $customerTypeName = $customer->type->name;

                foreach ($data as $value) {
                    $price = Priceproduct::where('product_id', $value->id)
                        ->where('name', $customerTypeName)
                        ->first();

                    if ($price) {
                        $value->selling_price = $price->total;
                    }
                }
            }
        }

        return response()->json([
            'success' => true,
            'product' => $data
        ], 200);
    }

    public function getProductService(Request $request)
    {
        $data = Product::with('producttype', 'price', 'unit', 'rack', 'nettounit', 'brutounit')->where('qty', '>', 0)->where('category', 'service')->get();
        if (isset($request->contact_id)) {
            $customer = Contact::with('type')->where('id', $request->contact_id)->first();
            foreach ($data as $key => $value) {
                if (!empty($customer->type()->first())) {
                    $price = Priceproduct::where('product_id', $value->id)
                        ->where('name', $customer->type()->first()->name)
                        ->first();
                    if (!empty($price)) {
                        $value->selling_price = $price->total;
                    }
                }
            }
        }

        $response = [
            'success' => true,
            'product' => $data,
        ];

        return response($response, 200);
    }

    public function getProductDetail(Request $request)
    {
        $data = Product::with('producttype', 'price', 'unit', 'rack', 'nettounit', 'brutounit')->find($request->id);
        $data['multi_unit'] = MultiUnit::with('multi_unit')
            ->where('product_id', $data->id)
            ->get();

        $response = [
            'success' => true,
            'product' => $data,
        ];

        return response($response, 200);
    }

    public function createProduct(Request $request)
    {
        $request->validate([
            'name' => 'required',
            'unit'  => 'required',
            'purchase_price'  => 'nullable',
            'selling_price'  => 'required',
            'producttype'  => 'nullable',
            'code'  => 'nullable',
            'display_rack_v2'  => 'nullable',
            'category'  => 'required',
            'profit_strategy'  => 'required',
            'profit_strategy_percent'  => 'nullable',
            'netto_qty'  => 'nullable|numeric',
            'netto_unit_id'  => 'nullable|integer',
            'bruto_qty'  => 'nullable|numeric',
            'bruto_unit_id'  => 'nullable|integer',
            'pricing_schema'  => 'required',
            'multi_unit_json'  => 'nullable|array',
            'price_contact_json'  => 'nullable|array',
            'price_wholesale_json'  => 'nullable|array',
        ]);

        // Mulai database transaction
        DB::beginTransaction();

        try {
            $for_sale = isset($request->for_sale) ? $request->for_sale : 1;
            $for_purchase = isset($request->for_purchase) ? $request->for_purchase : 1;

            $data = new Product;
            $data->code = $request->code;
            $data->name = $request->name;
            $data->product_image = $request->product_image;
            $data->display_rack_v2 = $request->display_rack_v2;
            $data->qty = 0;
            $data->qty_minimum = $request->qty_minimum;
            $data->for_sale = $for_sale;
            $data->for_purchase = $for_purchase;
            $data->unit = $request->unit;
            $data->selling_price = $request->selling_price;
            $data->profit_strategy = $request->profit_strategy;
            $data->pricing_schema = $request->pricing_schema;

            if ($request->category == 'service') {
                $data->qty = 1000000;
            } else {
                $data->producttype = $request->producttype;
                $data->purchase_price = $request->purchase_price;
            }

            if ($request->profit_strategy == 'persentase') {
                $data->profit_strategy_percent = $request->profit_strategy_percent;
            } else {
                $data->profit_strategy_percent = null;
            }

            $data->category = $request->category;

            $data->netto_qty = $request->netto_qty;
            $data->netto_unit_id = $request->netto_unit_id;
            $data->bruto_qty = $request->bruto_qty;
            $data->bruto_unit_id = $request->bruto_unit_id;

            $data->save();

            // Simpan multi unit jika ada dan dapatkan mapping ID
            $multiUnitMapping = [];
            if ($request->has('multi_unit_json') && !empty($request->multi_unit_json)) {
                $multiUnitMapping = $this->createMultiUnits($data->id, $request->multi_unit_json);
            }

            // Simpan price contact jika ada
            if ($request->has('price_contact_json') && !empty($request->price_contact_json)) {
                $this->createPriceContact($data->id, $request->price_contact_json, $multiUnitMapping, $request->unit);
            }

            // Simpan price wholesale jika ada
            if ($request->has('price_wholesale_json') && !empty($request->price_wholesale_json)) {
                $this->createPriceWholesale($data->id, $request->price_wholesale_json, $multiUnitMapping, $request->unit);
            }

            // Commit transaction jika semua berhasil
            DB::commit();

            $response = [
                'success' => true,
                'product' => $data,
                'multi_units' => $data->multiUnits ?? [] // Load relasi jika ada
            ];

            return response($response, 200);
        } catch (\Exception $e) {
            // Rollback transaction jika terjadi error
            DB::rollback();

            return response()->json([
                'status' => 'error',
                'message' => 'Terjadi kesalahan saat membuat produk: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Method untuk membuat multi units
     */
    private function createMultiUnits($productId, $multiUnitsData)
    {
        $mapping = [];

        foreach ($multiUnitsData as $index => $multiUnitData) {
            $multiUnit = new MultiUnit();
            $multiUnit->product_id = $productId;
            $multiUnit->multi_unit = $multiUnitData['multi_unit'];
            $multiUnit->multi_qty = $multiUnitData['multi_qty'];
            $multiUnit->multi_code = $multiUnitData['multi_code'] ?? null;
            $multiUnit->multi_purchase_price = $multiUnitData['multi_purchase_price'] ?? 0;
            $multiUnit->multi_selling_price = $multiUnitData['multi_selling_price'] ?? 0;
            $multiUnit->multi_sub_unit = $multiUnitData['multi_sub_unit'] ?? [];

            $multiUnit->save();

            // Simpan mapping antara multi_unit value dengan ID baru
            $mapping[] = [
                'id' => $multiUnit->id,
                'multi_unit' => $multiUnit->multi_unit,
            ];
        }

        return $mapping;
    }

    /**
     * Method untuk membuat price contact dengan mapping ID
     */
    private function createPriceContact($productId, $priceContacts, $multiUnitMapping, $defaultUnitId)
    {
        foreach ($priceContacts as $priceContact) {
            $priceProduct = new Priceproduct();
            $priceProduct->product_id = $productId;
            $priceProduct->contact_type = $priceContact['contacttype'];
            $priceProduct->total = $priceContact['total'];

            // Cari ID dari mapping berdasarkan nama multi_unit
            $matched = collect($multiUnitMapping)->firstWhere('multi_unit', $priceContact['multi_unit_id']);
            $mappedId = $matched['id'] ?? null;

            // Tentukan multi_unit_id berdasarkan kondisi
            if ($defaultUnitId == $priceContact['multi_unit_id']) {
                $priceProduct->multi_unit_id = null;
            } else {
                $priceProduct->multi_unit_id = $mappedId;
            }

            $priceProduct->save();
        }
    }

    /**
     * Method untuk membuat price wholesale dengan mapping ID
     */
    private function createPriceWholesale($productId, $priceWholesales, $multiUnitMapping, $defaultUnitId)
    {
        foreach ($priceWholesales as $priceWholesale) {
            $productWholesale = new ProductsWholesale();
            $productWholesale->product_id = $productId;
            $productWholesale->min_qty = $priceWholesale['min_qty'];
            $productWholesale->max_qty = $priceWholesale['max_qty'];
            $productWholesale->price = $priceWholesale['price'];

            // Cari ID dari mapping berdasarkan nama multi_unit
            $matched = collect($multiUnitMapping)->firstWhere('multi_unit', $priceWholesale['multi_unit_id']);
            $mappedId = $matched['id'] ?? null;

            // Tentukan multi_unit_id berdasarkan kondisi
            if ($defaultUnitId == $priceWholesale['multi_unit_id']) {
                $productWholesale->multi_unit_id = null;
            } else {
                $productWholesale->multi_unit_id = $mappedId;
            }

            $productWholesale->save();
        }
    }

    public function createProductLimit(Request $request)
    {
        $request->validate([
            'name' => 'required',
            'unit'  => 'required',
            'purchase_price'  => 'nullable',
            'selling_price'  => 'required',
            'producttype'  => 'nullable',
            'code'  => 'nullable',
            'category'  => 'required',
            'type'  => 'required',
        ]);
        $for_sale = isset($request->for_sale) ? $request->for_sale : 1;
        $data = new Product;
        $data->code = $request->code;
        $data->name = $request->name;
        $data->qty = 0;
        $data->type = $request->type;
        $data->for_sale = $for_sale;
        $data->unit = $request->unit;
        $data->selling_price = $request->selling_price;
        if ($request->category == 'service') {
            $data->qty = 1000000;
        } else {
            $data->producttype = $request->producttype;
            $data->purchase_price = $request->purchase_price;
        }
        $data->category = $request->category;

        $data->save();

        $response = [
            'success' => true,
            'product' => $data,
        ];

        return response($response, 200);
    }

    public function editProduct(Request $request)
    {
        $request->validate([
            'name' => 'required',
            'unit'  => 'required',
            'purchase_price'  => 'nullable',
            'selling_price'  => 'required',
            'producttype'  => 'nullable',
            'code'  => 'nullable',
            'display_rack_v2'  => 'nullable',
            'category'  => 'required',
            'profit_strategy'  => 'required',
            'profit_strategy_percent'  => 'nullable',
            'netto_qty'  => 'nullable|numeric',
            'netto_unit_id'  => 'nullable|integer',
            'bruto_qty'  => 'nullable|numeric',
            'bruto_unit_id'  => 'nullable|integer',
            'pricing_schema'  => 'required',
            'multi_unit_json'  => 'nullable|array',
            'price_contact_json'  => 'nullable|array',
            'price_wholesale_json'  => 'nullable|array',
        ]);

        // Mulai database transaction
        DB::beginTransaction();

        try {
            $data = Product::find($request->id);

            // Cek apakah product exists
            if (!$data) {
                DB::rollback();
                return response()->json([
                    'status' => 'error',
                    'message' => 'Produk tidak ditemukan'
                ], 404);
            }

            $for_sale = isset($request->for_sale) ? $request->for_sale : 1;
            $for_purchase = isset($request->for_purchase) ? $request->for_purchase : 1;

            $data->name = $request->name;
            $data->unit = $request->unit;
            $data->code = $request->code;
            $data->display_rack_v2 = $request->display_rack_v2;
            $data->product_image = $request->product_image;
            $data->for_sale = $for_sale;
            $data->for_purchase = $for_purchase;
            $data->qty_minimum = $request->qty_minimum;
            $data->selling_price = $request->selling_price;
            $data->profit_strategy = $request->profit_strategy;
            $data->pricing_schema = $request->pricing_schema;

            if ($request->category == 'service') {
                $data->qty = 1000000; // Sesuaikan dengan create (1jt)
            } else {
                $data->producttype = $request->producttype;
                $data->purchase_price = $request->purchase_price;
            }

            if ($request->profit_strategy == 'persentase') {
                $data->profit_strategy_percent = $request->profit_strategy_percent;
            } else {
                $data->profit_strategy_percent = null;
            }

            $data->category = $request->category;

            $data->netto_qty = $request->netto_qty;
            $data->netto_unit_id = $request->netto_unit_id;
            $data->bruto_qty = $request->bruto_qty;
            $data->bruto_unit_id = $request->bruto_unit_id;

            $data->save();

            // Simpan multi unit jika ada dan dapatkan mapping ID
            $multiUnitMapping = [];
            if ($request->has('multi_unit_json') && !empty($request->multi_unit_json)) {
                $multiUnitMapping = $this->updateMultiUnits($data->id, $request->multi_unit_json);
            }

            // Simpan price contact jika ada
            if ($request->has('price_contact_json') && !empty($request->price_contact_json)) {
                $this->updatePriceContact($data->id, $request->price_contact_json, $multiUnitMapping, $request->unit);
            }

            // Simpan price wholesale jika ada
            if ($request->has('price_wholesale_json') && !empty($request->price_wholesale_json)) {
                $this->updatePriceWholesale($data->id, $request->price_wholesale_json, $multiUnitMapping, $request->unit);
            }

            // Commit transaction jika semua berhasil
            DB::commit();

            $response = [
                'success' => true,
                'product' => $data,
                'multi_units' => $data->multiUnits
            ];

            return response($response, 200);
        } catch (\Exception $e) {
            // Rollback transaction jika terjadi error
            DB::rollback();

            return response()->json([
                'status' => 'error',
                'message' => 'Terjadi kesalahan saat mengupdate produk: ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Method untuk update multi units
     */
    private function updateMultiUnits($productId, $multiUnitsData)
    {
        MultiUnit::where('product_id', $productId)->delete();

        $mapping = [];

        foreach ($multiUnitsData as $index => $multiUnitData) {
            if (empty($multiUnitData['multi_unit']) || empty($multiUnitData['multi_qty'])) {
                continue;
            }

            $multiUnit = new MultiUnit();
            $multiUnit->product_id = $productId;
            $multiUnit->multi_unit = $multiUnitData['multi_unit'];
            $multiUnit->multi_qty = $multiUnitData['multi_qty'];
            $multiUnit->multi_code = $multiUnitData['multi_code'] ?? null;
            $multiUnit->multi_purchase_price = $multiUnitData['multi_purchase_price'] ?? 0;
            $multiUnit->multi_selling_price = $multiUnitData['multi_selling_price'] ?? 0;
            $multiUnit->multi_sub_unit = $multiUnitData['multi_sub_unit'] ?? [];

            $multiUnit->save();

            // Simpan mapping antara multi_unit value dengan ID baru
            $mapping[] = [
                'id' => $multiUnit->id,
                'multi_unit' => $multiUnit->multi_unit,
            ];
        }

        return $mapping;
    }

    /**
     * Method untuk update price contact
     */
    private function updatePriceContact($productId, $priceContacts, $multiUnitMapping, $defaultUnitId)
    {
        Priceproduct::where('product_id', $productId)->delete();

        foreach ($priceContacts as $priceContact) {
            if (empty($priceContact['multi_unit_id']) || empty($priceContact['contacttype'])) {
                continue;
            }

            $priceProduct = new Priceproduct();
            $priceProduct->product_id = $productId;
            $priceProduct->contact_type = $priceContact['contacttype'];
            $priceProduct->total = $priceContact['total'];

            // Cari ID dari mapping berdasarkan nama multi_unit
            $matched = collect($multiUnitMapping)->firstWhere('multi_unit', $priceContact['multi_unit_id']);
            $mappedId = $matched['id'] ?? null;

            // Tentukan multi_unit_id berdasarkan kondisi
            if ($defaultUnitId == $priceContact['multi_unit_id']) {
                $priceProduct->multi_unit_id = null;
            } else {
                $priceProduct->multi_unit_id = $mappedId;
            }

            $priceProduct->save();
        }
    }

    /**
     * Method untuk update price wholesale
     */
    private function updatePriceWholesale($productId, $priceWholesales, $multiUnitMapping, $defaultUnitId)
    {
        ProductsWholesale::where('product_id', $productId)->delete();

        foreach ($priceWholesales as $priceWholesale) {
            $productWholesale = new ProductsWholesale();
            $productWholesale->product_id = $productId;
            $productWholesale->min_qty = $priceWholesale['min_qty'];
            $productWholesale->max_qty = $priceWholesale['max_qty'];
            $productWholesale->price = $priceWholesale['price'];

            // Cari ID dari mapping berdasarkan nama multi_unit
            $matched = collect($multiUnitMapping)->firstWhere('multi_unit', $priceWholesale['multi_unit_id']);
            $mappedId = $matched['id'] ?? null;

            // Tentukan multi_unit_id berdasarkan kondisi
            if ($defaultUnitId == $priceWholesale['multi_unit_id']) {
                $productWholesale->multi_unit_id = null;
            } else {
                $productWholesale->multi_unit_id = $mappedId;
            }

            $productWholesale->save();
        }
    }

    public function deleteProduct(Request $request)
    {
        // cek data harga spesial
        $price = Priceproduct::where('product_id', $request->id)->get();
        // cek data penjualan
        $stock = Substocktransaction::where('product_id', $request->id)
            ->with('stocktransaction')
            ->get()
            ->map(function ($item) {
                if ($item->stocktransaction->pending === null && $item->stocktransaction->cashout_id) {
                    return 'BELI PRODUK';
                } else if ($item->stocktransaction->pending && $item->stocktransaction->cashout_id) {
                    return 'PESANAN PEMBELIAN';
                } else if ($item->stocktransaction->pending === null && $item->stocktransaction->cashin_id) {
                    return 'JUAL PRODUK';
                } else if ($item->stocktransaction->pending && $item->stocktransaction->cashin_id) {
                    return 'PESANAN PENJUALAN';
                } else if ($item->stocktransaction->nonmoney === 'in' && $item->stocktransaction->type === 'modal_barang') {
                    return 'PRODUK - PERSEDIAAN AWAL / MODAL&LABA - MODAL BARANG';
                } else if ($item->stocktransaction->nonmoney === 'in') {
                    return 'KOREKSI STOK - TAMBAHKAN';
                } else if ($item->stocktransaction->nonmoney === 'out') {
                    return 'KOREKSI STOK - KURANGI';
                } else if ($item->stocktransaction->beginning_balance === 1) {
                    return 'SALDO AWAL';
                }
            });

        if ($price && count($stock) > 0) {
            // $response = [
            //     'success'=> false,
            //     'message'=> "silahkan hapus harga spesial dan " . join(", ", json_decode($stock, true)) . " terkait produk ini terlebih dahulu",
            // ];

            // return response($response,400);

            $response = [
                'success' => false,
                'message' => "silahkan hapus transaksi di " . join(", ", json_decode($stock, true)) . " terkait produk ini terlebih dahulu",
            ];

            return response($response, 400);

            foreach ($price as $listPrice) {
                $listPrice->delete();
            }
        } else if (count($stock) > 0) {
            $response = [
                'success' => false,
                'message' => "silahkan hapus transaksi di " . join(", ", json_decode($stock, true)) . " terkait produk ini terlebih dahulu",
            ];

            return response($response, 400);
        } else if ($price) {
            // $response = [
            //     'success'=> false,
            //     'message'=> "silahkan hapus harga spesial terkait produk ini terlebih dahulu",
            // ];

            // return response($response,400);
            foreach ($price as $listPrice) {
                $listPrice->delete();
            }
        }

        $data = Product::find($request->id);
        $data->price()->delete();
        $data->delete();

        $multi = MultiUnit::where('product_id', $request->id)->get();
        if (count($multi) > 0) {
            MultiUnit::where('product_id', $request->id)->delete();
        }

        $response = [
            'success' => true,
            'product' => $data,
        ];

        return response($response, 200);
    }

    public function bulkDeleteProduct(Request $request)
    {
        $productIds = $request->ids;
        $skippedProducts = [];
        $deletedProducts = [];

        foreach ($productIds as $productId) {
            $product = Product::find($productId);

            if (!$product) {
                $skippedProducts[] = [
                    'id' => $productId,
                    'message' => 'Product not found',
                ];
                continue;
            }

            // cek data harga spesial
            $price = Priceproduct::where('product_id', $productId)->get();
            // cek data penjualan
            $stock = Substocktransaction::where('product_id', $productId)
                ->with('stocktransaction')
                ->get()
                ->map(function ($item) {
                    if ($item->stocktransaction->pending === null && $item->stocktransaction->cashout_id) {
                        return 'BELI PRODUK';
                    } else if ($item->stocktransaction->pending && $item->stocktransaction->cashout_id) {
                        return 'PESANAN PEMBELIAN';
                    } else if ($item->stocktransaction->pending === null && $item->stocktransaction->cashin_id) {
                        return 'JUAL PRODUK';
                    } else if ($item->stocktransaction->pending && $item->stocktransaction->cashin_id) {
                        return 'PESANAN PENJUALAN';
                    } else if ($item->stocktransaction->nonmoney === 'in') {
                        return 'KOREKSI STOK - TAMBAHKAN';
                    } else if ($item->stocktransaction->nonmoney === 'out') {
                        return 'KOREKSI STOK - KURANGI';
                    }
                });

            if ($price && count($stock) > 0) {
                $skippedProducts[] = [
                    'id' => $productId,
                    'message' => 'Produk ini sudah terkait dengan ' . join(", ", json_decode($stock, true)),
                ];
                continue;
            } else if (count($stock) > 0) {
                $skippedProducts[] = [
                    'id' => $productId,
                    'message' => 'Produk ini sudah terkait dengan ' . join(", ", json_decode($stock, true)),
                ];
                continue;
            } else if ($price) {
                foreach ($price as $listPrice) {
                    $listPrice->delete();
                }
            }

            $data = Product::find($productId);
            $data->delete();

            $deletedProducts[] = [
                'id' => $productId,
                'message' => 'Produk success dihapus'
            ];

            $multi = MultiUnit::where('product_id', $request->id)->get();
            if (count($multi) > 0) {
                MultiUnit::where('product_id', $request->id)->delete();
            }
        }

        $response = [
            'success' => true,
            'message' => 'Products deletion process completed',
            'data' => [
                'deleted' => [
                    'count' => count($deletedProducts),
                    'products' => $deletedProducts
                ],
                'skipped' => [
                    'count' => count($skippedProducts),
                    'products' => $skippedProducts
                ]
            ]
        ];

        return response($response, 200);
    }
}
