<?php

namespace App\Http\Controllers\API\V4;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;
use App\User;
use App\Models\Purchase;
use App\Models\Supplier;
use Carbon\CarbonPeriod;
use App\Models\LogPaymentDebtSupplier;
use App\Models\HistoryDebtSupplier;

use App\Items;
use App\Models\Store;

class PurchaseController extends Controller
{
    /**
     * Store a new purchase order.
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */

public function storePurchase(Request $request)
{
    $decoded = $request->all();
    $now = Carbon::now();
    $expdate = $now->format('Y-m-d');

    $id_supplier    = $decoded["id_supplier"];
    $due_date       = $decoded["due_date"] ?? $expdate;
    $total_order    = $decoded["total_order"];
    $totalpay       = $decoded["amountPaid"];
    $key            = $decoded["key"];
    $type_payment   = $decoded["payment_type"];

    // Validate user session
    $user = DB::table('users')->where('id_session', $key)->first();
    if (!$user) {
        return response()->json([
            'status'  => 'true',
            'errCode' => '00',
            'msg'     => 'User Not Found'
        ]);
    }

    $master = DB::table('users')->where('phone_number', $user->master)->first();
    $lastPurchase = DB::table('purchasing_data')
        ->where('user', $master->phone_number)
        ->orderByDesc('id_purchasing_data')
        ->first();

    $supplier = DB::table('supplier')->where('id_supplier', $id_supplier)->first();

    // Generate invoice number
    $nameParts = explode(' ', $supplier->name_supplier);
    $initials = '';
    foreach ($nameParts as $part) {
        $initials .= substr($part, 0, 1);
    }

    $code = strtoupper($initials);
    $dateCode = now()->format('dHi');
    $invoice = "{$code}-{$lastPurchase->id_purchasing_data}{$dateCode}";

    $payment = 'payment_type';

     if ($totalpay >= $total_order) {
        $status = 'Paid';
    } elseif ($totalpay > 0) {
        $status = 'Partially Paid';
    } else { 
        $status = 'Unpaid'; // Still unpaid
    }

    $change = 0 - $total_order;

    if ($type_payment == 1) {
        $payment = 'Cash';
       // $status = 'Paid';
    } elseif ($type_payment == 2) {
       // $status = 'Paid';
    } elseif ($type_payment == 3) {
        // Credit payment
        DB::table('supplier')
            ->where('id_supplier', $id_supplier)
            ->update(['debt' => 1]);

        DB::table('historydebtsupplier')->insert([
            'id_supplier' => $id_supplier,
            'user' => $master->phone_number,
            'status' => 'debt',
            'no_invoice' => $invoice,
            'nominal' => $total_order - $totalpay,
            'date' => $expdate
        ]);
    }

    DB::beginTransaction();

    try {
        foreach ($decoded["product"] as $item) {
            $id_product = $item["id_product"];
            $amount = $item["amount_product"];

            $product = DB::table('product')
                ->where('id', $id_product)
                ->orWhere('local_id', $id_product)
                ->first();

            $total_price = $product->purchase_price * $amount;
            $new_stock = $product->stock + $amount;

            // Insert into purchase
            DB::table('purchase')->insert([
                'id_product' => $id_product,
                'amount' => $amount,
                'id_supplier' => $id_supplier,
                'id_store' => $user->id_store,
                'user' => $master->phone_number,
                'no_invoice' => $invoice,
                'status' => $status,
                'price' => $product->purchase_price,
                'totalprice' => $total_price,
                'date' => $expdate,
                'note' => 'note'
            ]);

            // Update product stock
            DB::table('product')
                ->where('id', $id_product)
                ->orWhere('local_id', $id_product)
                ->update(['stock' => $new_stock]);

            // Update or insert into stock table
            $existingStock = DB::table('stock')
                ->where('id_product', $id_product)
                ->where('id_store', $user->id_store)
                ->first();

            if ($existingStock) {
                DB::table('stock')
                    ->where('id_product', $id_product)
                    ->where('id_store', $user->id_store)
                    ->update(['stock' => $existingStock->stock + $amount]);
            } else {
                DB::table('stock')->insert([
                    'id_product' => $id_product,
                    'id_store' => $user->id_store,
                    'stock' => $amount,
                    'user' => $master->phone_number
                ]);
            }

            // Insert history_stock
            DB::table('history_stock')->insert([
                'id_product' => $id_product,
                'id_store' => $user->id_store,
                'stock' => $amount,
                'detail' => 'Add Stock (Purchase)',
                'status' => 0,
                'date' => $expdate,
                'user' => $master->phone_number
            ]);
        }

        // Insert into purchasing_data
        DB::table('purchasing_data')->insert([
            'id_supplier' => $id_supplier,
            'no_invoice' => $invoice,
            'date' => $expdate,
            'id_store' => $user->id_store,
            'payment' => $payment,
            'totalorder' => $total_order,
            'totalpay' => $totalpay,
            'note' => 'note',
            'status' => $status,
            'changepay' => $change,
            'due_date' => $due_date,
            'operator' => $user->phone_number,
            'user' => $master->phone_number
        ]);

        DB::commit();

        return response()->json([
            'status' => 'true',
            'errCode' => '01',
            'msg' => 'Success',
            'data' => [
                'invoice' => $invoice
            ]
        ]);
    } catch (\Exception $e) {
        DB::rollBack();
        return response()->json([
            'status' => 'false',
            'errCode' => '99',
            'msg' => 'Error: ' . $e->getMessage()
        ]);
    }
}




public function purchaseHistoryReport(Request $request)
{
    $key = $request->input('key');
    $firstDate = $request->input('first_date');
    $lastDate = $request->input('last_date');
    $status = $request->input('status');

    // Find user by session key
    $user = User::where('id_session', $key)->first();

    if (!$user) {
        return response()->json([
            'status' => 'true',
            'errCode' => '00',
            'msg' => 'User Not Found'
        ]);
    }

    // Find master user
    $master = User::where('phone_number', $user->master)->first();

    $response = [
        'status' => 'true',
        'errCode' => '01',
        'msg' => 'Success',
        'data' => []
    ];

    $period = CarbonPeriod::create($firstDate, $lastDate);

    foreach ($period as $date) {
        $tanggal = $date->format('Y-m-d');

        // Get total order sum
        $query = Purchase::query();
        if ($user->level == 'master') {
            $query->where('user', $master->phone_number);
        } else {
            $query->where('operator', $user->phone_number);
        }
        
        if ($status == 'all' || $status == '') {
            $status = '';
        } else {
            $status = $status;
        }

        $query->whereDate('date', $tanggal)
              ->where('status', 'like', "%$status%");
        $totalOrder = $query->sum('totalorder');

        // Get purchase data
        $query = Purchase::query();
        if ($user->level == 'master') {
            $query->where('user', $master->phone_number);
        } else {
            $query->where('operator', $user->phone_number);
        }
        $query->whereDate('date', $tanggal)
              ->where('status', 'like', "%$status%")
              ->orderBy('id_purchasing_data', 'asc');

        $purchases = $query->get();
        $details = [];

        foreach ($purchases as $purchase) {
            $supplier = Supplier::find($purchase->id_supplier);

            $details[] = [
                'id_supplier'   => $purchase->id_supplier,
                'name_supplier' => $supplier ? $supplier->name_supplier : '',
                'no_invoice'    => $purchase->no_invoice,
                'date'          => $purchase->date,
                'payment'       => $purchase->payment,
                'totalorder'    => $purchase->totalorder,
                'totalpay'      => $purchase->totalpay,
                'changepay'     => $purchase->changepay,
                'status'        => $purchase->status,
            ];
        }

        $response['data'][] = [
            'totalorderall' => $totalOrder ?? 0,
            'date' => $tanggal,
            'detail' => $details
        ];
    }

    return response()->json($response);
}

public function getPurchaseDetails(Request $request)
    {
        $key = $request->query('key');
        $noInvoice = $request->query('no_invoice');

        $user = User::where('id_session', $key)->first();

        if (!$user) {
            return response()->json([
                'status'  => 'true',
                'errCode' => '00',
                'msg'     => 'User Not Found'
            ]);
        }

        $master = User::where('phone_number', $user->master)->first();
        if (!$master) {
            return response()->json([
                'status'  => 'true',
                'errCode' => '00',
                'msg'     => 'Master User Not Found'
            ]);
        }

        $purchasingData = Purchase::where('no_invoice', $noInvoice)->first();
        $purchases = DB::table('purchase')->where('no_invoice', $noInvoice)->get();

        if ($purchases->isEmpty() || !$purchasingData) {
            return response()->json([
                'status'  => 'true',
                'errCode' => '02',
                'msg'     => 'no data'
            ]);
        }

        $supplier = Supplier::find($purchasingData->id_supplier);
        $store = Store::find($user->id_store);

        $host = request()->getSchemeAndHttpHost();

        $struk = [
            'name_store'     => $store->name_store ?? '',
            'email'          => $store->email ?? '',
            'nohp'           => $store->nohp ?? '',
            'address'        => $store->address ?? '',
            'no_invoice'     => $purchasingData->no_invoice,
            'operator'       => $user->full_name,
            'id_supplier'    => $purchasingData->id_supplier,
            'name_supplier'  => $supplier->name_supplier ?? '',
            'id_table'       => 1,
            'date'           => $purchasingData->date,
            'payment'        => $purchasingData->payment,
            'totalorder'     => $purchasingData->totalorder,
            'totallast'      => $purchasingData->totalorder,
            'totalpay'       => $purchasingData->totalpay,
            'changepay'      => $purchasingData->changepay,
            'status'         => $purchasingData->status,
            'paymentstatus'  => $purchasingData->status,
            'note'           => $purchasingData->note, 
            'due_date'       => $purchasingData->due_date,
            'footer'         => "",
            'img'            => "$host/uploads/restorants/{$store->img}",
            'link_order'     => "$host/app/track.php?code={$purchasingData->no_invoice}"
        ];

        $products = $purchases->map(function ($purchase) use ($host) {
          //  $product = Items::find('local_id', $purchase->id_product);
           // $product = Items::where('local_id', $purchase->id_product)->first();
            $product = DB::table('product')->where('local_id', $purchase->id_product)->first();
            return [
                'codeproduct' => $product->user ?? '',
                'name_product'=> $product->name ?? '',
                'unit'        => $product->unit ?? '',
                'date'        => $purchase->date,
                'amount'      => $purchase->amount,
                'price'       => $purchase->price,
                'totalprice'  => $purchase->totalprice,
                'status'      => $purchase->status,
                'note'        => $purchase->note,
                'stock'       => $product->stock ?? 0,
                'have_stock'  => $product->have_stock ?? 0,
                'img'         => "",
            ];
        });

        return response()->json([
            'status' => 'true',
            'errCode' => '01',
            'msg' => 'Success',
            'data' => [
                'struk' => $struk,
                'data' => $products
            ]
        ]);
    }


  

public function makePayment(Request $request)
{
    $validated = $request->validate([
        'key' => 'required|string',
        'no_invoice' => 'required|string',
        'amountPay' => 'required|numeric|min:0',
        'paymentDate' => 'nullable|date',
        'paymentMethord' => 'nullable|string',
        'note' => 'nullable|string',
    ]);

    $key = $validated['key'];
    $noInvoice = $validated['no_invoice'];
    $amountPay = $validated['amountPay'];
    $paymentDate = $validated['paymentDate'] ?? Carbon::now()->toDateString();
    $note = $validated['note'] ?? null;

    $user = User::where('id_session', $key)->first();
    if (!$user) {
        return response()->json([
            'status' => 'true',
            'errCode' => '00',
            'msg' => 'User Not Found'
        ]);
    }

    $master = User::where('phone_number', $user->master)->first();
    if (!$master) {
        return response()->json([
            'status' => 'true',
            'errCode' => '00',
            'msg' => 'Master User Not Found'
        ]);
    }

    $purchase = Purchase::where('user', $master->phone_number)
                ->where('no_invoice', $noInvoice)->first();

    if (!$purchase) {
        return response()->json([
            'status' => 'true',
            'errCode' => '02',
            'msg' => 'No data'
        ]);
    }

    $purchase->totalpay += $amountPay;
    $purchase->changepay = $purchase->totalpay - $purchase->totalorder;

    // Determine new status
    if ($purchase->totalpay >= $purchase->totalorder) {
        $purchase->status = 'Paid';
    } elseif ($purchase->totalpay > 0) {
        $purchase->status = 'Partially Paid';
    } else {
        $purchase->status = 'Unpaid'; // Still unpaid
    }
    $purchase->save();

    // Log payment 
    LogPaymentDebtSupplier::create([
        'id_supplier' => $purchase->id_supplier,
        'user' => $master->phone_number,
        'no_invoice' => $noInvoice,
        'nominal' => $amountPay,
        'date' => $paymentDate,
    ]);

    // Update HistoryDebtSupplier status to match
    HistoryDebtSupplier::where('no_invoice', $noInvoice)
        ->update(['status' => $purchase->status]);

    // Update supplier debt flag
    $hasDebts = HistoryDebtSupplier::where('id_supplier', $purchase->id_supplier)
                  ->whereIn('status', ['Unpaid', 'Partially Paid'])->exists();

    Supplier::where('id_supplier', $purchase->id_supplier)
        ->update(['debt' => $hasDebts ? 1 : 0]);

    return response()->json([
        'status' => 'true',
        'errCode' => '01',
        'msg' => $purchase->status === 'Partially Paid' ? 'Partial Payment Success' : 'Payment Success'
    ]);
}


}
