<?php

namespace App\Http\Controllers;

use App\Models\StoreRawMaterial;
use App\Models\Store;
use App\Models\RawMaterial;
use App\Models\Period;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use App\Traits\ExcelUploadTrait;

class StoreRawMaterialsController extends Controller
{
    use ExcelUploadTrait;
    public function index(Request $request)
    {
        if ($request->ajax()) {
            $query = StoreRawMaterial::select('m_store_raw_materials.*')
                ->with(['store', 'rawMaterial']);
                // Removed delete_flag filter - show all records

            // Filter by user's accessible stores
            $userStoreIds = auth()->user()->getAccessibleStoreIds();
            if (!empty($userStoreIds)) {
                $query->whereIn('store_id', $userStoreIds);
            }

            // Searching
            if ($request->has('search') && $request->search['value'] != '') {
                $search = $request->search['value'];
                $query->where(function ($q) use ($search) {
                    $q->whereHas('store', function ($sq) use ($search) {
                        $sq->where('name', 'ilike', "%{$search}%")
                          ->orWhere('code', 'ilike', "%{$search}%");
                    })
                    ->orWhereHas('rawMaterial', function ($rq) use ($search) {
                        $rq->where('name', 'ilike', "%{$search}%")
                           ->orWhere('code', 'ilike', "%{$search}%");
                    });
                });
            }

            // Filter by store
            if ($request->has('store_filter') && $request->store_filter != '') {
                $query->where('store_id', $request->store_filter);
            }

            // Filter by status (is_active)
            if ($request->has('status_filter') && $request->status_filter != '') {
                $query->where('is_active', $request->status_filter == '1');
            }

            $total = $query->count();

            // Sorting
            $columns = ['id', 'store_id', 'raw_material_id', 'tipe_dokumen', 'is_active', 'min_stock', 'max_stock', 'reorder_point', 'created_at'];
            $orderColumn = $columns[$request->order[0]['column']] ?? 'created_at';
            $orderDir = $request->order[0]['dir'] ?? 'desc';

            $query->orderBy($orderColumn, $orderDir);

            // Pagination
            $start = $request->start;
            $length = $request->length;
            $data = $query->skip($start)->take($length)->get();

            // Format data
            $result = [];
            $no = $start + 1;
            foreach ($data as $row) {
                // Status badge based on is_active
                if ($row->is_active) {
                    $statusBadge = 'badge-success';
                    $statusText = 'Active';
                } else {
                    $statusBadge = 'badge-danger';
                    $statusText = 'Deleted';
                }
                
                // Tipe Dokumen badge
                $docTypeBadge = match($row->tipe_dokumen) {
                    'DO' => '<span class="badge badge-primary">DO</span>',
                    'PO' => '<span class="badge badge-secondary">PO</span>',
                    'PR' => '<span class="badge badge-info">PR</span>',
                    default => '<span class="badge badge-secondary">' . $row->tipe_dokumen . '</span>'
                };
                
                // Tipe Barang badge
                $materialTypeBadge = $row->rawMaterial->tipe_barang === 'Basah' 
                    ? '<span class="badge badge-info">Basah</span>' 
                    : '<span class="badge badge-secondary">Kering</span>';
                
                // Action buttons - hide edit/delete for deleted records, show activate instead
                $actions = '';
                if ($row->is_active) {
                    $actions = '<a href="' . route('store_raw_materials.edit', $row->id) . '" class="btn btn-xs btn-warning">
                                    <i class="fa fa-edit"></i> Edit
                                </a>
                                <a href="' . route('store_raw_materials.destroy', $row->id) . '" data="delete" onclick="notificationBeforeDelete(event, this)" class="btn btn-xs btn-danger">
                                    <i class="fa fa-trash"></i> Delete
                                </a>';
                } else {
                    // Show activate button for deleted records
                    $actions = '<button type="button" class="btn btn-xs btn-success btn-activate" data-id="' . $row->id . '" data-url="' . route('store_raw_materials.destroy', $row->id) . '">
                                    <i class="fa fa-check"></i> Activate
                                </button>';
                }
                
                $result[] = [
                    $no++,
                    $row->store->name ?? '',
                    $row->rawMaterial->code . ' - ' . $row->rawMaterial->name ?? '',
                    $docTypeBadge,
                    $materialTypeBadge,
                    '<span class="badge ' . $statusBadge . '">' . $statusText . '</span>',
                    number_format($row->min_stock, 2),
                    number_format($row->max_stock, 2),
                    number_format($row->reorder_point, 2),
                    $row->created_at->format('M jS Y, H:i'),
                    $actions
                ];
            }

            return response()->json([
                "draw" => intval($request->draw),
                "recordsTotal" => $total,
                "recordsFiltered" => $total,
                "data" => $result,
            ]);
        }

        // Get only stores that user has access to
        $userStoreIds = auth()->user()->getAccessibleStoreIds();
        $stores = Store::where('delete_flag', 0)
            ->when(!empty($userStoreIds), function($q) use ($userStoreIds) {
                $q->whereIn('id', $userStoreIds);
            })
            ->orderBy('name')
            ->get();
        
        return view('m-store-raw-materials.index', [
            'variables' => $this->variables(),
            'stores' => $stores
        ]);
    }

    public function create()
    {
        $variables['judul'] = 'Add Store Raw Material Mapping';
        
        // Get only stores that user has access to
        $userStoreIds = auth()->user()->getAccessibleStoreIds();
        $variables['stores'] = Store::where('delete_flag', 0)
            ->when(!empty($userStoreIds), function($q) use ($userStoreIds) {
                $q->whereIn('id', $userStoreIds);
            })
            ->orderBy('name')
            ->get();
            
        $variables['raw_materials'] = RawMaterial::where('delete_flag', 0)->orderBy('name')->get();
        $variables['periods'] = Period::enabled()->orderBy('code')->get();
        
        return view('m-store-raw-materials.form', [
            'data' => json_decode(json_encode(array(
                'id' => 0,
                'lsm_flag' => true,
                'spb_flag' => true,
                'inv_matrix_flag' => false,
                'min_stock' => 0,
                'max_stock' => 0,
                'reorder_point' => 0
            ))),
            'variables' => $this->variables($variables)
        ]);
    }

    public function edit(StoreRawMaterial $storeRawMaterial)
    {
        // Check if user has access to this store
        if (!auth()->user()->hasAccessToStore($storeRawMaterial->store_id)) {
            abort(403, 'Anda tidak memiliki akses ke store ini.');
        }
        
        $storeRawMaterial->load(['store', 'rawMaterial', 'period']);
        $variables['judul'] = 'Edit Store Raw Material Mapping';
        
        // Get only stores that user has access to
        $userStoreIds = auth()->user()->getAccessibleStoreIds();
        $variables['stores'] = Store::where('delete_flag', 0)
            ->when(!empty($userStoreIds), function($q) use ($userStoreIds) {
                $q->whereIn('id', $userStoreIds);
            })
            ->orderBy('name')
            ->get();
            
        $variables['raw_materials'] = RawMaterial::where('delete_flag', 0)->orderBy('name')->get();
        $variables['periods'] = Period::enabled()->orderBy('code')->get();
        
        return view('m-store-raw-materials.form', [
            'data' => $storeRawMaterial,
            'variables' => $this->variables($variables)
        ]);
    }

    private function variables($variables = null)
    {
        $variables['header_routes'] = ' 
								<li class="breadcrumb-item">Master Data</li>  
								<li class="breadcrumb-item active">Store Raw Materials</li>
							 ';
        return $variables;
    }

    public function store(Request $request, $prm_id)
    {
        $storeRawMaterial = null;
        if ($prm_id)
            $storeRawMaterial = StoreRawMaterial::findOrFail($prm_id);

        // Check if user has access to the selected store
        $storeId = $request->store_id ?? ($storeRawMaterial ? $storeRawMaterial->store_id : null);
        if ($storeId && !auth()->user()->hasAccessToStore($storeId)) {
            return response()->json(['warning', 'Anda tidak memiliki akses ke store ini.']);
        }

        $rules = [
            'store_id' => 'required|exists:m_stores,id',
            'raw_material_id' => 'required|exists:m_raw_materials,id',
            'tipe_dokumen' => 'required|in:DO,PO,PR',
            'lsm_flag' => 'boolean',
            'spb_flag' => 'boolean',
            'inv_matrix_flag' => 'boolean',
            'period_id' => 'nullable|exists:m_periods,id',
            'min_stock' => 'nullable|numeric|min:0',
            'max_stock' => 'nullable|numeric|min:0',
            'reorder_point' => 'nullable|numeric|min:0',
            'notes' => 'nullable|string',
        ];

        // Check for duplicate mapping (except for current record)
        if (!$storeRawMaterial) {
            $rules['store_id'] .= '|unique:m_store_raw_materials,store_id,NULL,id,raw_material_id,' . $request->raw_material_id;
        } else {
            $rules['store_id'] .= '|unique:m_store_raw_materials,store_id,' . $storeRawMaterial->id . ',id,raw_material_id,' . $request->raw_material_id;
        }

        $messages = [
            'store_id.unique' => 'This store and raw material combination already exists.',
        ];
        
        $saveData = $request->validate($rules, $messages);
        
        // Set flags from checkbox
        $saveData['lsm_flag'] = $request->has('lsm_flag');
        $saveData['spb_flag'] = $request->has('spb_flag');
        $saveData['inv_matrix_flag'] = $request->has('inv_matrix_flag');
        
        // Always set is_active to true for create/update
        $saveData['is_active'] = true;

        try {
            if ($storeRawMaterial) {
                $storeRawMaterial->update(array_merge($saveData, [
                    'updated_by' => $this->logged_user_id,
                ]));
            } else {
                StoreRawMaterial::create(array_merge($saveData, [
                    'created_by' => $this->logged_user_id,
                ]));
            }
            
            $notif = $storeRawMaterial ? 'Updated successfully.' : 'Successfully created.';
            return response()->json(['success', $notif]);
            
        } catch (\Exception $e) {
            $notif = $this->getErrorCatch($e->getMessage());
            return response()->json(['warning', $notif]);
        }
    }

    public function show(StoreRawMaterial $storeRawMaterial)
    {
        // Check if user has access to this store
        if (!auth()->user()->hasAccessToStore($storeRawMaterial->store_id)) {
            abort(403, 'Anda tidak memiliki akses ke store ini.');
        }
        
        $storeRawMaterial->load(['creator', 'modificator', 'store', 'rawMaterial', 'period']);
        $variables['judul'] = 'View Store Raw Material Mapping';
        return view('m-store-raw-materials.show', [
            'data' => $storeRawMaterial,
            'variables' => $this->variables($variables)
        ]);
    }

    public function destroy(StoreRawMaterial $storeRawMaterial, Request $request)
    {
        // Check if user has access to this store
        if (!auth()->user()->hasAccessToStore($storeRawMaterial->store_id)) {
            abort(403, 'Anda tidak memiliki akses ke store ini.');
        }
        
        // Check action type from request
        $action = $request->input('action', 'delete'); // default: delete
        
        if ($action === 'activate') {
            // Activate: set is_active to true
            $storeRawMaterial->update([
                'is_active' => true,
                'updated_by' => $this->logged_user_id
            ]);
            $message = 'Successfully activated';
        } else {
            // Delete: set is_active to false
            $storeRawMaterial->update([
                'is_active' => false,
                'updated_by' => $this->logged_user_id
            ]);
            $message = 'Successfully deleted';
        }

        return redirect()->route('store_raw_materials.index')
            ->with('success', $message);
    }

    // API endpoint to get raw materials for specific store
    public function getRawMaterialsForStore(Request $request)
    {
        $storeId = $request->store_id;
        
        if (!$storeId) {
            return response()->json(['success' => false, 'message' => 'Store ID required']);
        }

        // Check if user has access to this store
        if (!auth()->user()->hasAccessToStore($storeId)) {
            return response()->json(['success' => false, 'message' => 'Anda tidak memiliki akses ke store ini.']);
        }

        $rawMaterials = StoreRawMaterial::active()
            ->forStore($storeId)
            ->with(['rawMaterial', 'period'])
            ->get()
            ->map(function ($mapping) {
                return [
                    'id' => $mapping->rawMaterial->id,
                    'code' => $mapping->rawMaterial->code,
                    'name' => $mapping->rawMaterial->name,
                    'uom' => $mapping->rawMaterial->uom,
                    'tipe_dokumen' => $mapping->tipe_dokumen,
                    'tipe_barang' => $mapping->rawMaterial->tipe_barang,
                    'lsm_flag' => $mapping->lsm_flag,
                    'spb_flag' => $mapping->spb_flag,
                    'inv_matrix_flag' => $mapping->inv_matrix_flag,
                    'period' => $mapping->period ? $mapping->period->name : null,
                    'min_stock' => $mapping->min_stock,
                    'max_stock' => $mapping->max_stock,
                    'reorder_point' => $mapping->reorder_point,
                ];
            });

        return response()->json([
            'success' => true,
            'raw_materials' => $rawMaterials
        ]);
    }

    // Bulk assign raw materials to store
    public function bulkAssign(Request $request)
    {
        $request->validate([
            'store_id' => 'required|exists:m_stores,id',
            'raw_material_ids' => 'required|array',
            'raw_material_ids.*' => 'exists:m_raw_materials,id',
        ]);

        // Check if user has access to this store
        if (!auth()->user()->hasAccessToStore($request->store_id)) {
            return response()->json(['success' => false, 'message' => 'Anda tidak memiliki akses ke store ini.']);
        }

        try {
            DB::beginTransaction();

            foreach ($request->raw_material_ids as $rawMaterialId) {
                StoreRawMaterial::updateOrCreate(
                    [
                        'store_id' => $request->store_id,
                        'raw_material_id' => $rawMaterialId,
                    ],
                    [
                        'tipe_dokumen' => 'DO', // Default
                        'lsm_flag' => true, // Default enabled
                        'spb_flag' => true, // Default enabled
                        'inv_matrix_flag' => false, // Default disabled
                        'period_id' => null,
                        'is_active' => true,
                        'created_by' => $this->logged_user_id,
                        'updated_by' => $this->logged_user_id,
                    ]
                );
            }

            DB::commit();
            
            return response()->json(['success' => true, 'message' => 'Raw materials assigned successfully']);
            
        } catch (\Exception $e) {
            DB::rollback();
            return response()->json(['success' => false, 'message' => $e->getMessage()]);
        }
    }

    private function getErrorCatch($e)
    {
        if (strpos($e, '#error#') !== false) {
            $e = explode('#error#', $e);
            $e = $e[1];
        }

        return $e;
    }

    /**
     * Download Excel template for Store Raw Materials
     */
    public function downloadTemplate()
    {
        $headers = [
            'Store Code',
            'Raw Material Code',
            'Tipe Dokumen',
            'LSM Flag',
            'SPB Flag',
            'Inv Matrix Flag',
            'Period Code',
            'Min Stock',
            'Max Stock',
            'Reorder Point',
            'Notes'
        ];

        $sampleData = [
            ['BGM0001', 'RM001', 'DO', 'Yes', 'Yes', 'No', 'HARIAN', '10', '100', '20', 'Sample mapping 1'],
            ['BGM0001', 'RM002', 'PO', 'Yes', 'Yes', 'Yes', 'MINGGUAN', '5', '50', '10', 'Sample mapping 2'],
            ['BGM0002', 'RM001', 'DO', 'Yes', 'No', 'No', 'HARIAN', '15', '150', '30', 'Sample mapping 3'],
        ];

        // Call parent trait method using parent keyword won't work with traits
        // So we need to call it differently or rename
        return $this->generateTemplate('Store_Raw_Materials_Template.xlsx', $headers, $sampleData);
    }

    /**
     * Generate Excel template - wrapper for trait method
     */
    private function generateTemplate($filename, $headers, $sampleData = [])
    {
        $spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
        $sheet = $spreadsheet->getActiveSheet();
        
        // Set headers
        $col = 'A';
        foreach ($headers as $header) {
            $sheet->setCellValue($col . '1', $header);
            $sheet->getStyle($col . '1')->getFont()->setBold(true);
            $sheet->getStyle($col . '1')->getFill()
                ->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)
                ->getStartColor()->setRGB('F39C12');
            $sheet->getColumnDimension($col)->setAutoSize(true);
            $col++;
        }
        
        // Add sample data if provided
        if (!empty($sampleData)) {
            $row = 2;
            foreach ($sampleData as $data) {
                $col = 'A';
                foreach ($data as $value) {
                    $sheet->setCellValue($col . $row, $value);
                    $col++;
                }
                $row++;
            }
            
            // Add notes after sample data
            $noteRow = $row + 1;
            $sheet->setCellValue('A' . $noteRow, 'Catatan:');
            $sheet->getStyle('A' . $noteRow)->getFont()->setBold(true);
            
            $noteRow++;
            $sheet->setCellValue('A' . $noteRow, '- Tipe Dokumen: DO (Delivery Order), PO (Purchase Order), atau PR (Purchase Request)');
            $noteRow++;
            $sheet->setCellValue('A' . $noteRow, '- LSM Flag, SPB Flag, Inv Matrix Flag: Yes atau No');
            $noteRow++;
            $sheet->setCellValue('A' . $noteRow, '- Period Code: HARIAN, MINGGUAN, BULANAN (sesuai dengan master period)');
            $noteRow++;
            $sheet->setCellValue('A' . $noteRow, '- Kosongkan Period Code jika tidak ingin set periode');
            
            // Style notes
            $sheet->getStyle('A' . ($noteRow - 4) . ':A' . $noteRow)
                ->getFont()->setItalic(true)->setSize(9);
        }
        
        $writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
        
        header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
        header('Content-Disposition: attachment;filename="' . $filename . '"');
        header('Cache-Control: max-age=0');
        
        $writer->save('php://output');
        exit;
    }

    /**
     * Upload Excel file for Store Raw Materials
     */
    public function upload(Request $request)
    {
        $request->validate([
            'excel_file' => 'required|file|mimes:xlsx,xls|max:10240'
        ]);

        $file = $request->file('excel_file');
        
        try {
            // Store uploaded file
            $uploadedFilePath = $this->storeUploadedExcel($file, 'store_raw_materials');
            
            $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($file->getPathname());
            $worksheet = $spreadsheet->getActiveSheet();
            $rows = $worksheet->toArray();
            $rows = $this->trimExcelData($rows); // Trim all data to prevent whitespace issues
            
            if (empty($rows)) {
                return response()->json([
                    'success' => false,
                    'message' => 'File Excel kosong',
                    'errors' => []
                ]);
            }

            // Get header row
            $headers = array_map('trim', $rows[0]);
            
            // Validate required columns (Status removed - always active)
            $requiredColumns = ['Store Code', 'Raw Material Code', 'Tipe Dokumen'];
            $missingColumns = array_diff($requiredColumns, $headers);
            if (!empty($missingColumns)) {
                return response()->json([
                    'success' => false,
                    'message' => 'Kolom yang diperlukan tidak ditemukan: ' . implode(', ', $missingColumns),
                    'errors' => []
                ]);
            }

            // Get user's accessible stores
            $userStoreIds = auth()->user()->getAccessibleStoreIds();
            $userStores = Store::whereIn('id', $userStoreIds)->pluck('id', 'code')->toArray();

            // Process data rows
            $result = $this->processExcelRows($rows, $headers, $userStores);
            
            // Log upload
            $errorCount = count($result['errors']);
            $totalRows = count($rows) - 1; // Exclude header
            \App\Models\ExcelUploadLog::create([
                'upload_type' => 'store_raw_materials',
                'uploaded_file' => $uploadedFilePath,
                'original_filename' => $file->getClientOriginalName(),
                'total_rows' => $totalRows,
                'success_rows' => $result['inserted'] + $result['updated'],
                'error_rows' => $errorCount,
                'error_details' => $errorCount > 0 ? json_encode($result['errors']) : null,
                'status' => $errorCount > 0 ? ($result['inserted'] + $result['updated'] > 0 ? 'Partial' : 'Failed') : 'Success',
                'uploaded_by' => auth()->id(),
            ]);
            
            $result['uploaded_file'] = $uploadedFilePath;
            
            return response()->json($result);
            
        } catch (\Exception $e) {
            Log::error('Excel upload failed', [
                'error' => $e->getMessage(),
                'user_id' => auth()->id()
            ]);
            
            return response()->json([
                'success' => false,
                'message' => 'Gagal memproses file Excel: ' . $e->getMessage(),
                'errors' => []
            ]);
        }
    }

    /**
     * Process Excel rows - Private method untuk logic internal
     */
    private function processExcelRows($rows, $headers, $userStores)
    {
        $inserted = 0;
        $updated = 0;
        $errors = [];
        
        for ($i = 1; $i < count($rows); $i++) {
            $row = $rows[$i];
            
            // Skip empty rows
            if (empty(array_filter($row))) {
                continue;
            }
            
            DB::beginTransaction();
            try {
                // Extract row data
                $rowData = $this->extractRowData($row, $headers);
                
                // Validate and prepare data
                $data = $this->validateAndPrepareRowData($rowData, $userStores);
                
                // Check if mapping exists (check by store_id + raw_material_id, regardless of is_active)
                $existing = StoreRawMaterial::where('store_id', $data['store_id'])
                    ->where('raw_material_id', $data['raw_material_id'])
                    ->first();
                
                if ($existing) {
                    $existing->update($data);
                    $updated++;
                } else {
                    $data['created_by'] = auth()->id();
                    StoreRawMaterial::create($data);
                    $inserted++;
                }
                
                DB::commit();
                
            } catch (\Exception $e) {
                DB::rollback();
                $errors[] = [
                    'row' => $i + 1,
                    'error' => $e->getMessage()
                ];
                
                Log::error("Excel upload error at row " . ($i + 1), [
                    'error' => $e->getMessage(),
                    'user_id' => auth()->id()
                ]);
            }
        }
        
        $totalErrors = count($errors);
        $message = "Upload selesai: {$inserted} data baru, {$updated} data diupdate";
        if ($totalErrors > 0) {
            $message .= ", {$totalErrors} error";
        }
        
        return [
            'success' => $totalErrors == 0 || ($inserted + $updated) > 0,
            'message' => $message,
            'inserted' => $inserted,
            'updated' => $updated,
            'errors' => $errors
        ];
    }

    /**
     * Extract data from Excel row
     */
    private function extractRowData($row, $headers)
    {
        return [
            'store_code' => trim($row[array_search('Store Code', $headers)] ?? ''),
            'raw_material_code' => trim($row[array_search('Raw Material Code', $headers)] ?? ''),
            'tipe_dokumen' => strtoupper(trim($row[array_search('Tipe Dokumen', $headers)] ?? 'DO')),
            'lsm_flag' => trim($row[array_search('LSM Flag', $headers)] ?? 'Yes'),
            'spb_flag' => trim($row[array_search('SPB Flag', $headers)] ?? 'Yes'),
            'inv_matrix_flag' => trim($row[array_search('Inv Matrix Flag', $headers)] ?? 'No'),
            'period_code' => trim($row[array_search('Period Code', $headers)] ?? ''),
            'min_stock' => $row[array_search('Min Stock', $headers)] ?? 0,
            'max_stock' => $row[array_search('Max Stock', $headers)] ?? 0,
            'reorder_point' => $row[array_search('Reorder Point', $headers)] ?? 0,
            'notes' => $row[array_search('Notes', $headers)] ?? '',
        ];
    }

    /**
     * Validate and prepare row data - Private method untuk validation logic
     */
    private function validateAndPrepareRowData($rowData, $userStores)
    {
        // Validate required fields
        if (empty($rowData['store_code'])) {
            throw new \Exception('Store Code tidak boleh kosong');
        }
        if (empty($rowData['raw_material_code'])) {
            throw new \Exception('Raw Material Code tidak boleh kosong');
        }
        
        // Find store by code
        $store = Store::where('code', $rowData['store_code'])->where('delete_flag', 0)->first();
        if (!$store) {
            throw new \Exception("Store dengan code '{$rowData['store_code']}' tidak ditemukan");
        }
        
        // Check if user has access to this store
        if (!isset($userStores[$rowData['store_code']])) {
            throw new \Exception("Anda tidak memiliki akses ke store '{$rowData['store_code']}'");
        }
        
        // Find raw material by code
        $rawMaterial = RawMaterial::where('code', $rowData['raw_material_code'])->where('delete_flag', 0)->first();
        if (!$rawMaterial) {
            throw new \Exception("Raw Material dengan code '{$rowData['raw_material_code']}' tidak ditemukan");
        }
        
        // Validate tipe dokumen
        if (!in_array($rowData['tipe_dokumen'], ['DO', 'PO', 'PR'])) {
            throw new \Exception("Tipe Dokumen harus DO, PO, atau PR");
        }
        
        // Convert Yes/No to boolean for flags
        $lsmFlag = strtolower(trim($rowData['lsm_flag'])) === 'yes';
        $spbFlag = strtolower(trim($rowData['spb_flag'])) === 'yes';
        $invMatrixFlag = strtolower(trim($rowData['inv_matrix_flag'])) === 'yes';
        
        // Find period by code if provided
        $periodId = null;
        if (!empty($rowData['period_code'])) {
            $period = Period::where('code', $rowData['period_code'])->where('is_enabled', true)->first();
            if ($period) {
                $periodId = $period->id;
            }
        }
        
        // Prepare data
        return [
            'store_id' => $store->id,
            'raw_material_id' => $rawMaterial->id,
            'tipe_dokumen' => $rowData['tipe_dokumen'],
            'lsm_flag' => $lsmFlag,
            'spb_flag' => $spbFlag,
            'inv_matrix_flag' => $invMatrixFlag,
            'period_id' => $periodId,
            'is_active' => true, // Always active for uploaded data
            'min_stock' => is_numeric($rowData['min_stock']) ? $rowData['min_stock'] : 0,
            'max_stock' => is_numeric($rowData['max_stock']) ? $rowData['max_stock'] : 0,
            'reorder_point' => is_numeric($rowData['reorder_point']) ? $rowData['reorder_point'] : 0,
            'notes' => $rowData['notes'],
            'updated_by' => auth()->id(),
        ];
    }

    /**
     * Override getUniqueField for ExcelUploadTrait
     */
    protected function getUniqueField()
    {
        return 'id'; // Store-Item mapping uses composite key (store_id + raw_material_id)
    }
}