<?php

namespace App\Http\Controllers;

use App\Models\RawMaterial;
use App\Models\Period;
use App\Services\CacheService;
use App\Traits\ExcelUploadTrait;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\Rule;

class RawMaterialsController extends Controller
{
    use ExcelUploadTrait;
    public function index(Request $request)
    {
        if ($request->ajax()) {
            $query = RawMaterial::select('m_raw_materials.*')
                ->where('delete_flag', 0);

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

            $total = $query->count();

            // Sorting
            $columns = ['id', 'code', 'name', 'uom', 'tipe_barang'];
            $orderColumn = $columns[$request->order[0]['column']] ?? 'code';
            $orderDir = $request->order[0]['dir'] ?? 'asc';

            $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) {
                $tipeBarangBadge = $row->tipe_barang === 'Basah' 
                    ? '<span class="badge badge-info">Basah</span>' 
                    : '<span class="badge badge-secondary">Kering</span>';
                
                $result[] = [
                    $no++,
                    '<a href="' . route('raw_materials.show', $row->id) . '">' . $row->code . '</a>',
                    $row->name,
                    $row->uom,
                    $tipeBarangBadge,
                    number_format($row->suggest_ratio, 2),
                ];
            }

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

        // Get data for view
        $variables['raw_materials'] = RawMaterial::where('delete_flag', 0)->get();

        return view('m-raw-materials.index', [
            'variables' => $this->variables($variables)
        ]);
    }

    public function create()
    {
        $variables['judul'] = 'Add Raw Material';
        
        return view('m-raw-materials.form', [
            'data' => json_decode(json_encode(array('id' => 0))),
            'variables' => $this->variables($variables)
        ]);
    }

    public function edit(RawMaterial $rawMaterial)
    {
        $variables['judul'] = 'Edit Raw Material';
        
        return view('m-raw-materials.form', [
            'data' => $rawMaterial,
            'variables' => $this->variables($variables)
        ]);
    }

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

        $rules = [
            'name' => 'required|string|max:255',
            'uom' => 'required|string|max:2|uppercase',
            'description' => 'nullable|string',
            'konversi_satuan_utuh' => 'nullable|string|max:2|uppercase',
            'konversi_satuan_pakai' => 'nullable|string|max:2|uppercase', 
            'konversi_satuan_kirim' => 'nullable|string|max:2|uppercase',
            'tipe_barang' => 'required|in:Basah,Kering',
            'minimal_order' => 'nullable|numeric|min:0',
            'multiple_order' => 'nullable|numeric|min:0',
            'suggest_ratio' => 'nullable|numeric|min:0',
            'latest_ratio' => 'nullable|numeric|min:0',
        ];

        $messages = [];
        $saveData = $request->validate($rules, $messages);

        // Auto-uppercase UOM fields and limit to 2 chars
        $saveData['uom'] = strtoupper(substr($saveData['uom'], 0, 2));
        if (!empty($saveData['konversi_satuan_utuh'])) {
            $saveData['konversi_satuan_utuh'] = strtoupper(substr($saveData['konversi_satuan_utuh'], 0, 2));
        }
        if (!empty($saveData['konversi_satuan_pakai'])) {
            $saveData['konversi_satuan_pakai'] = strtoupper(substr($saveData['konversi_satuan_pakai'], 0, 2));
        }
        if (!empty($saveData['konversi_satuan_kirim'])) {
            $saveData['konversi_satuan_kirim'] = strtoupper(substr($saveData['konversi_satuan_kirim'], 0, 2));
        }

        // Set default values
        $saveData['minimal_order'] = $saveData['minimal_order'] ?? 0;
        $saveData['multiple_order'] = $saveData['multiple_order'] ?? 1;
        $saveData['suggest_ratio'] = $saveData['suggest_ratio'] ?? 0;
        $saveData['latest_ratio'] = $saveData['latest_ratio'] ?? 0;

        try {
            if ($rawMaterial) {
                $rawMaterial->update(array_merge($saveData, [
                    'updated_by' => $this->logged_user_id,
                ]));
            } else {
                $rawMaterial = RawMaterial::create(array_merge($saveData, [
                    'created_by' => $this->logged_user_id,
                ]));
            }
            
            // Clear cache
            CacheService::clearRawMaterialCache($rawMaterial->id);
            
            $notif = $rawMaterial ? '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(RawMaterial $rawMaterial)
    {
        $rawMaterial->load(['creator', 'modificator']);
        $variables['judul'] = 'View Raw Material: ' . $rawMaterial->code;
        return view('m-raw-materials.show', [
            'data' => $rawMaterial,
            'variables' => $this->variables($variables)
        ]);
    }

    public function destroy(RawMaterial $rawMaterial)
    {
        $rawMaterial->update([
            'delete_flag' => 1,
            'updated_by' => $this->logged_user_id
        ]);

        // Clear cache
        CacheService::clearRawMaterialCache($rawMaterial->id);

        return redirect()->route('raw_materials.index')
            ->with('success', 'Successfully deleted');
    }

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

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

        return $e;
    }

    /**
     * Upload Excel untuk bulk insert/update raw materials
     */
    public function uploadExcel(Request $request)
    {
        $request->validate([
            'excel_file' => 'required|mimes:xlsx,xls|max:10240',
        ]);

        try {
            $file = $request->file('excel_file');
            
            // Store uploaded file
            $uploadedFilePath = $this->storeUploadedExcel($file, 'raw_materials');
            
            $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($file->getRealPath());
            $sheet = $spreadsheet->getActiveSheet();
            $rows = $sheet->toArray();
            $rows = $this->trimExcelData($rows); // Trim all data to prevent whitespace issues

            // Remove header
            array_shift($rows);

            $inserted = 0;
            $updated = 0;
            $errors = [];
            $totalRows = count($rows);

            foreach ($rows as $index => $row) {
                $rowNumber = $index + 2;

                // Skip empty rows
                if (empty(array_filter($row))) {
                    continue;
                }

                try {
                    // Validate required fields
                    if (empty($row[0]) || empty($row[1]) || empty($row[2])) {
                        $errors[] = ['row' => $rowNumber, 'error' => 'Code, Name, dan UOM wajib diisi'];
                        continue;
                    }

                    $data = [
                        'code' => $row[0],
                        'name' => $row[1],
                        'uom' => $row[2],
                        'description' => $row[3] ?? null,
                        'tipe_barang' => $row[4] ?? 'Kering',
                        'minimal_order' => $row[5] ?? 0,
                        'multiple_order' => $row[6] ?? 1,
                        'suggest_ratio' => $row[7] ?? 0,
                        'latest_ratio' => 0,
                        'delete_flag' => 0,
                        'updated_by' => auth()->id(),
                    ];

                    // Check if exists (by code)
                    $existing = \App\Models\RawMaterial::where('code', $row[0])->first();

                    if ($existing) {
                        $existing->update($data);
                        $updated++;
                    } else {
                        $data['created_by'] = auth()->id();
                        \App\Models\RawMaterial::create($data);
                        $inserted++;
                    }

                    // Clear cache
                    \App\Services\CacheService::clearRawMaterialCache();
                } catch (\Exception $e) {
                    $errors[] = ['row' => $rowNumber, 'error' => $e->getMessage()];
                }
            }

            // Log upload
            $errorCount = count($errors);
            \App\Models\ExcelUploadLog::create([
                'upload_type' => 'raw_materials',
                'uploaded_file' => $uploadedFilePath,
                'original_filename' => $file->getClientOriginalName(),
                'total_rows' => $totalRows,
                'success_rows' => $inserted + $updated,
                'error_rows' => $errorCount,
                'error_details' => $errorCount > 0 ? json_encode($errors) : null,
                'status' => $errorCount > 0 ? ($inserted + $updated > 0 ? 'Partial' : 'Failed') : 'Success',
                'uploaded_by' => auth()->id(),
            ]);

            return response()->json([
                'success' => true,
                'message' => "Upload berhasil! Ditambahkan: {$inserted}, Diperbarui: {$updated}",
                'inserted' => $inserted,
                'updated' => $updated,
                'errors' => $errors,
                'uploaded_file' => $uploadedFilePath,
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Upload gagal: ' . $e->getMessage(),
            ], 500);
        }
    }
    
    /**
     * Download template Excel untuk raw materials
     */
    public function downloadTemplate()
    {
        $spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
        $sheet = $spreadsheet->getActiveSheet();

        // Set header
        $sheet->setCellValue('A1', 'Code');
        $sheet->setCellValue('B1', 'Name');
        $sheet->setCellValue('C1', 'UOM');
        $sheet->setCellValue('D1', 'Description');
        $sheet->setCellValue('E1', 'Tipe Barang');
        $sheet->setCellValue('F1', 'Minimal Order');
        $sheet->setCellValue('G1', 'Multiple Order');
        $sheet->setCellValue('H1', 'Suggest Ratio');

        // Style header
        $headerStyle = [
            'font' => ['bold' => true, 'color' => ['rgb' => 'FFFFFF']],
            'fill' => ['fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID, 'startColor' => ['rgb' => 'F39C12']],
            'alignment' => ['horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER],
        ];
        $sheet->getStyle('A1:H1')->applyFromArray($headerStyle);

        // Set column width
        foreach (range('A', 'H') as $col) {
            $sheet->getColumnDimension($col)->setAutoSize(true);
        }

        // Add sample data
        $sheet->setCellValue('A2', 'RM001');
        $sheet->setCellValue('B2', 'Tepung Terigu');
        $sheet->setCellValue('C2', 'PC');
        $sheet->setCellValue('D2', 'Tepung untuk membuat mie');
        $sheet->setCellValue('E2', 'Kering');
        $sheet->setCellValue('F2', '10');
        $sheet->setCellValue('G2', '5');
        $sheet->setCellValue('H2', '1.5');

        $sheet->setCellValue('A3', 'RM002');
        $sheet->setCellValue('B3', 'Minyak Goreng');
        $sheet->setCellValue('C3', 'LT');
        $sheet->setCellValue('D3', 'Minyak untuk menggoreng');
        $sheet->setCellValue('E3', 'Basah');
        $sheet->setCellValue('F3', '5');
        $sheet->setCellValue('G3', '1');
        $sheet->setCellValue('H3', '2.0');

        // Add note
        $sheet->setCellValue('A5', 'Catatan:');
        $sheet->setCellValue('A6', '- Tipe Barang: Kering atau Basah');
        $sheet->setCellValue('A7', '- Flag LSM, SPB, Matriks Inventori, dan Periode Pemesanan diatur di Master Mapping Store-Item');
        $sheet->getStyle('A5:A7')->getFont()->setItalic(true)->setSize(9);

        $writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
        $filename = 'template_raw_materials_' . date('YmdHis') . '.xlsx';

        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;
    }
}
