<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Services\BusinessCentralService;
use App\Services\InventoryBC;
use App\Models\BudgetButcher;
class TransferHeaderController extends Controller
{
        public function createTransferLine()

    {
        return view('transferheader');
    }

public function showItems()
{
    $start = microtime(true);

    $bcService = new InventoryBC();

    // ============================
    // 1. Ambil item ledger + mapping
    // ============================
    $data = $bcService->getItemLedgerAndSkuMappingAsync();

    $executionTime = round(microtime(true) - $start, 2);

    $currentCompany = session('current_company_name', session('user')['role'] ?? '');

    if ($currentCompany === 'Regent' || $currentCompany === 'SUPER') {
        $locationOptions = ['CI.1012'];
    } elseif ($currentCompany === 'HIN') {
        $locationOptions = ['HIN.1200', 'HIN.1300', 'HIN.1000', 'HIN.3000'];
    }

    // ===========================================
    // 2. Ambil Transfer Header + Lines
    // ===========================================
    $bcService2 = new BusinessCentralService();
    $transferResponse = $bcService2->getAllTransferWithLinesV2();

    $transferDecoded = $transferResponse instanceof \Illuminate\Http\JsonResponse
        ? $transferResponse->getData(true)
        : $transferResponse;

    $transferData = $transferDecoded['data'] ?? [];

    // ===========================================
    // 3. Filter hanya transfer line dengan "ST. ORDER"
    // ===========================================
    $filteredLines = [];

    foreach ($transferData as $header) {
        $spec = $header['transSpec'] ?? '';

        if (trim(strtoupper($spec)) === 'ST. ORDER') {
            if (!empty($header['Lines']) && is_array($header['Lines'])) {
                foreach ($header['Lines'] as $line) {
                    $filteredLines[] = $line;
                }
            }
        }
    }

    // ===========================================
    // 4. Ambil Assembly Line Custom
    // ===========================================
    $assemblyResponse = $bcService2->assemblyLineCustom();

    $assemblyDecoded = $assemblyResponse instanceof \Illuminate\Http\JsonResponse
        ? $assemblyResponse->getData(true)
        : $assemblyResponse;

    $assemblyLines = $assemblyDecoded ?? [];

    // ===========================================
    // 5. Ambil DATA DARI DATABASE budget_butcher 
    //    khusus bulan sebelumnya
    // ===========================================

    // Tentukan bulan sebelumnya
    $lastMonthStart = now()->subMonth()->startOfMonth()->toDateString();
    $lastMonthEnd   = now()->subMonth()->endOfMonth()->toDateString();

    // Ambil data bulan sebelumnya
    $budgetItems = BudgetButcher::whereBetween('PostingDate', [$lastMonthStart, $lastMonthEnd])
        ->orderBy('PostingDate', 'desc')
        ->get();

    // Sum CostAmountActual
    $sumCost = $budgetItems->sum('CostAmountActual');
    // Jadikan positif
    $positiveSum = abs($sumCost);

    // Pembulatan ke bawah ke 100 juta terdekat
    $rounded = floor($positiveSum / 100000000) * 100000000;

    // ===========================================
    // 6. Kirim ke view
    // ===========================================
    return view('items', [
        'result'            => $data['result'],
        'transferLines'     => $filteredLines,
        'assemblyLines'     => $assemblyLines,      // nilai final (dibulatkan ke 100 juta terdekat)
    ]);
}





        public function showAOApprovals()
    {
$aoList = [
            [
                'document_no' => 'AO-001',
                'recipe_name' => 'Croissant Butter',
                'quantity' => 120,
                'uom' => 'pcs',
                'requested_by' => 'Chef Lina',
                'status' => 'Pending',
                'posting_date' => '2025-11-02',
                'due_date' => '2025-11-05',
            ],
            [
                'document_no' => 'AO-002',
                'recipe_name' => 'Pain au Chocolat',
                'quantity' => 80,
                'uom' => 'pcs',
                'requested_by' => 'Chef Yanto',
                'status' => 'Approved',
                'posting_date' => '2025-10-29',
                'due_date' => '2025-11-03',
            ],
            [
                'document_no' => 'AO-003',
                'recipe_name' => 'Danish Blueberry',
                'quantity' => 60,
                'uom' => 'pcs',
                'requested_by' => 'Chef Ayu',
                'status' => 'Pending',
                'posting_date' => '2025-11-01',
                'due_date' => '2025-11-02', // paling cepat
            ],
        ];

        // Urutkan agar due date terdekat muncul lebih dulu
        usort($aoList, function ($a, $b) {
            return strtotime($a['due_date']) - strtotime($b['due_date']);
        });

        // Kirim data ke view
        return view('aoApproval', compact('aoList'));
    }

    public function soPage()
    {
        return view('so.index'); // file Blade: resources/views/so/index.blade.php
    }

    // API: return JSON transfer header + lines
    public function withLines(Request $r)
    {
        try {
            // Panggil service yang sudah ada di projectmu
            // Misal: app('App\Services\BusinessCentralService')
            // dan method getAllTransferWithLines() mengembalikan array/nilai atau Response JSON
            $svc = app()->make(\App\Services\BusinessCentralService::class);

            // Jika service menyediakan fungsi getAllTransferWithLines yang sudah return json array:
            if (method_exists($svc, 'getAllTransferWithLines')) {
                $result = $svc->getAllTransferWithLines();

                // Jika service sudah mengembalikan response()->json, forward langsung
                if ($result instanceof \Illuminate\Http\JsonResponse) {
                    return $result;
                }

                // Jika service mengembalikan array, bungkus jadi response JSON
                return response()->json([
                    'status' => 'success',
                    'data'   => $result,
                ]);
            }

            // fallback: coba panggil method lain atau return error
            return response()->json([
                'status' => 'error',
                'message' => 'BC service method not found',
            ], 500);

        } catch (\Throwable $e) {
            Log::error('[SO PAGE] error fetching transfer lines: ' . $e->getMessage(), [
                'trace' => $e->getTraceAsString()
            ]);
            return response()->json([
                'status' => 'error',
                'message' => $e->getMessage(),
            ], 500);
        }
    }

    public function showReplaceMaterialPage()
    {
        $bcService = app(BusinessCentralService::class);

        // 1. Ambil data BOM lengkap beserta stok
        $res = $bcService->getCombinedBOMWithStock();
        $rawData = $res['items'] ?? [];

        // 2. Tidak melakukan grouping di sini — dikirim mentah
        return view('editrecipe.index', [
            'rawData' => $rawData
        ]);
    }

    public function getAvailableItems(Request $r)
    {
        $bcService = app(BusinessCentralService::class);
        $res = $bcService->getAllItemDataWithUoM(); // ambil semua stok item
        return response()->json($res['items'] ?? []);
    }

public function updateMaterial(Request $r)
{
    try {
        // ✅ Payload utama berupa array langsung
        $validated = $r->validate([
            '*.parent_recipe' => 'required|array',
            '*.parent_recipe.bom_parent' => 'required|string',
            '*.parent_recipe.description' => 'required|string',

            '*.materials' => 'required|array|min:1',
            '*.materials.*.old_material' => 'required|array',
            '*.materials.*.old_material.item_no' => 'required|string',
            '*.materials.*.old_material.description' => 'required|string',

            '*.materials.*.new_material' => 'required|array',
            '*.materials.*.new_material.item_no' => 'required|string',
            '*.materials.*.new_material.description' => 'required|string',
            '*.materials.*.new_material.chosen_uom' => 'nullable|string',
            '*.materials.*.new_material.chosen_quantity' => 'nullable|numeric|min:0',
        ]);

        // ✅ Data sudah tervalidasi, langsung pakai
        $payload = $validated;

        // 🔧 Panggil service BusinessCentralService
        $svc = app()->make(\App\Services\BusinessCentralService::class);

        if (!method_exists($svc, 'updateBillOfMaterialItems')) {
            return response()->json([
                'status' => 'error',
                'message' => 'Service method updateBillOfMaterialItems() not found',
            ], 500);
        }

        // 🚀 Jalankan fungsi service
        $result = $svc->updateBillOfMaterialItems($payload);

        // ✅ Jika service mengembalikan JsonResponse langsung forward
        if ($result instanceof \Illuminate\Http\JsonResponse) {
            return $result;
        }

        // ✅ Jika array biasa, bungkus ke response JSON
        return response()->json([
            'status'  => 'success',
            'message' => 'Bill of Material successfully updated!',
            'data'    => $result,
        ]);

    } catch (\Illuminate\Validation\ValidationException $ve) {
        return response()->json([
            'status'  => 'error',
            'message' => 'Validation failed',
            'errors'  => $ve->errors(),
        ], 422);
    } catch (\Throwable $e) {
        \Log::error('[BC BOM PATCH] Failed to update materials: ' . $e->getMessage(), [
            'trace' => $e->getTraceAsString(),
        ]);

        return response()->json([
            'status'  => 'error',
            'message' => $e->getMessage(),
        ], 500);
    }
}

public function viewInventoryBudget()
{
    // ============================
    // 1. Tentukan bulan sebelumnya
    // ============================
    $lastMonthStart = now()->subMonth()->startOfMonth()->toDateString();
    $lastMonthEnd   = now()->subMonth()->endOfMonth()->toDateString();

    // ======================================
    // 2. Ambil data Budget bulan lalu (raw)
    // ======================================
    $rawItems = BudgetButcher::whereBetween('PostingDate', [$lastMonthStart, $lastMonthEnd])
        ->orderBy('PostingDate', 'desc')
        ->get();

    // ======================================================
    // 3. Group by ItemNo + Description, lalu sum CostActual
    // ======================================================
    $budgetItems = $rawItems
        ->groupBy(function ($row) {
            return $row->ItemNo . '|' . $row->Description;
        })
        ->map(function ($group) {
            return [
                'ItemNo'          => $group->first()->ItemNo,
                'Description'     => $group->first()->Description,
                'LocationCode'    => $group->first()->LocationCode,
                'PostingDate'     => $group->first()->PostingDate,
                'TotalCostActual' => $group->sum('CostAmountActual'),
                'rows'            => $group,
            ];
        })
        ->values();

    // ======================================================
    // 4. AMBIL DATA STOCK DARI SERVICE getCombinedStock()
    // ======================================================
    $stockResponse = app(\App\Services\BusinessCentralService::class)->getCombinedStock();

    // keamanan: jika gagal, tetap jalan tanpa error
    $stockItems = collect();
    if (
        is_array($stockResponse) &&
        isset($stockResponse['status']) &&
        $stockResponse['status'] === 'success' &&
        isset($stockResponse['items'])
    ) {
        $stockItems = collect($stockResponse['items']);
    }

    // ======================================================
    // 5. MERGE STOCK KE BUDGET ITEMS (match by ItemNo)
    // ======================================================
      $budgetItems = $budgetItems->map(function ($item) use ($stockItems) {
    
            // cari stock di list stock berdasarkan ItemNo
            $matched = $stockItems->firstWhere("Item_No", $item['ItemNo']);
    
            // ambil Inventory jika ada, jika tidak maka 0
            $stock = $matched['Inventory'] ?? 0;
    
            // ambil Base_UoM jika ada
            $uom = $matched['Base_UoM'] ?? '';
    
            // tambahkan field Stock + Base_UoM
            $item['Stock']   = $stock;
            $item['Base_UoM'] = $uom;
    
            return $item;
        });

    // ======================================================
    // 6. Hitung total keseluruhan bulan lalu
    // ======================================================
    $sumCost = $budgetItems->sum('TotalCostActual');

    $positiveSum = abs($sumCost);
    $rounded = floor($positiveSum / 100000000) * 100000000;
    // dd($budgetItems);
    // ============================
    // 7. Kirim ke View
    // ============================
    return view('Inventorylot.inventorybudget', [
        'budgetItems'    => $budgetItems,
        'lastMonthStart' => $lastMonthStart,
        'lastMonthEnd'   => $lastMonthEnd,
        'sumCost'        => $sumCost,
        'positiveSum'    => $positiveSum,
        'rounded'        => $rounded,
    ]);
}

public function postedAssembly()
{
    $bc = app(BusinessCentralService::class);

    $assemblies = $bc->Postedassemble();

    // SORT berdasarkan SystemCreatedAt (terbaru → terlama)
    usort($assemblies, function ($a, $b) {
        return strtotime($b['SystemCreatedAt'] ?? '') 
             <=> strtotime($a['SystemCreatedAt'] ?? '');
    });

    return view('print_assembly', [
        'assemblies' => $assemblies
    ]);
}
 public function printPostedAssembly(Request $request)
    {
        $request->validate([
            'documentNo' => 'required|string'
        ]);
        try {
            $bc = app(BusinessCentralService::class);

            $result = $bc->printAssemblyLabel(
                $request->documentNo
            );

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

        } catch (\Throwable $e) {
            Log::error('[Print Assembly] failed', [
                'message' => $e->getMessage()
            ]);

            return response()->json([
                'success' => false,
                'message' => $e->getMessage()
            ], 500);
        }
    }

}