<?php

namespace App\Http\Controllers;

use App\Models\ShipmentDelivery;
use App\Models\Store;
use App\Models\ArmadaType;
use App\Traits\ExcelUploadTrait;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Cache;
use Illuminate\Validation\Rule;

class ShipmentDeliveriesController extends Controller
{
    use ExcelUploadTrait;


    public function index(Request $request)
    {
        if ($request->ajax()) {
            $query = ShipmentDelivery::select('m_shipment_deliveries.*')
                ->with(['store', 'armadaType']);

            // 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}%");
                    })
                    ->orWhereHas('armadaType', function ($aq) use ($search) {
                        $aq->where('name', 'ilike', "%{$search}%");
                    })
                    ->orWhere('m_shipment_deliveries.day_name', 'ilike', "%{$search}%")
                    ->orWhere('m_shipment_deliveries.type', 'ilike', "%{$search}%")
                    ->orWhere('m_shipment_deliveries.status', 'ilike', "%{$search}%");
                });
            }

            $total = $query->count();

            // Sorting
            $columns = ['id', 'store_id', 'armada_type_id', 'type', 'day_name', 'arrival_time', 'departure_time', 'h_minus', 'status', '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) {
                $typeBadge = $row->type == 'DCKP' ? '<span class="badge badge-primary">DCKP</span>' : '<span class="badge badge-info">DSLK</span>';
                
                $result[] = [
                    $no++,
                    '<a href="' . route('shipment_deliveries.show', $row->id) . '">' . ($row->store->name ?? '') . '</a>',
                    $row->armadaType->name ?? '',
                    $typeBadge,
                    $row->day_name,
                    $row->arrival_time,
                    $row->departure_time,
                    'H-' . $row->h_minus,
                    $row->status,
                    $row->created_at->format('M jS Y, H:i'),
                ];
            }

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

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

    public function create()
    {
        $variables['judul'] = 'Add Shipment Delivery';
        $variables['stores'] = Store::where('delete_flag', 0)->orderBy('name')->get();
        $variables['armada_types'] = ArmadaType::where('delete_flag', 0)->orderBy('name')->get();
        $variables['days'] = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
        $variables['types'] = ['DCKP', 'DSLK'];
        
        return view('m-shipment-deliveries.form', [
            'data' => json_decode(json_encode(array('id' => 0, 'h_minus' => 2, 'status' => 'Active', 'type' => 'DCKP'))),
            'variables' => $this->variables($variables)
        ]);
    }

    public function edit(ShipmentDelivery $ShipmentDelivery)
    {
        $variables['judul'] = 'Edit Shipment Delivery';
        $variables['stores'] = Store::where('delete_flag', 0)->orderBy('name')->get();
        $variables['armada_types'] = ArmadaType::where('delete_flag', 0)->orderBy('name')->get();
        $variables['days'] = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
        $variables['types'] = ['DCKP', 'DSLK'];
        
        return view('m-shipment-deliveries.form', [
            'data' => $ShipmentDelivery,
            'variables' => $this->variables($variables)
        ]);
    }

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

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

        // Validasi
        $rules = [
            'store_id' => 'required|exists:m_stores,id',
            'armada_type_id' => 'required|exists:m_armada_types,id',
            'type' => 'required|in:DCKP,DSLK',
            'day_name' => 'required|in:Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday',
            'arrival_time' => 'nullable|date_format:H:i',
            'departure_time' => 'nullable|date_format:H:i',
            'h_minus' => 'required|integer|min:1|max:7',
            'status' => 'required|in:Active,Inactive',
        ];

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

        try {
            DB::beginTransaction();
            
            if ($shipmentDelivery) {
                $shipmentDelivery->update(array_merge($saveData, [
                    'updated_by' => $this->logged_user_id,
                ]));
                $notif = 'Updated successfully.';
            } else {
                $shipmentDelivery = ShipmentDelivery::create(array_merge($saveData, [
                    'created_by' => $this->logged_user_id,
                ]));
                $notif = 'Successfully created.';
            }

            DB::commit();
            return response()->json(['success', $notif]);
        } catch (\Exception $e) {
            DB::rollback();

            $notif = $this->getErrorCatch($e->getMessage());
            return response()->json(['warning', $notif]);
        }
    }

    public function show(ShipmentDelivery $ShipmentDelivery)
    {
        $ShipmentDelivery->load(['creator', 'modificator', 'store', 'armadaType']);
        $variables['judul'] = 'View Shipment Delivery: ' . ($ShipmentDelivery->store->name ?? 'ID#' . $ShipmentDelivery->id);
        return view('m-shipment-deliveries.show', [
            'data' => $ShipmentDelivery,
            'variables' => $this->variables($variables)
        ]);
    }

    public function destroy(ShipmentDelivery $ShipmentDelivery)
    {
        if ($ShipmentDelivery->delete_flag == 0) {
            $ShipmentDelivery->update([
                'delete_flag' => 1,
                'status' => 'Inactive',
                'updated_by' => $this->logged_user_id
            ]);

            return redirect()->route('shipment_deliveries.index')
                ->with('success', 'Successfully inactive');
        } else {
            $ShipmentDelivery->update([
                'delete_flag' => 0,
                'status' => 'Active',
                'updated_by' => $this->logged_user_id
            ]);

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

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

        return $e;
    }

    public function download_template()
    {
        $spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
        $sheet = $spreadsheet->getActiveSheet();

        // Set header
        $sheet->setCellValue('A1', 'store_code');
        $sheet->setCellValue('B1', 'armada_type_name');
        $sheet->setCellValue('C1', 'type');
        $sheet->setCellValue('D1', 'day_name');
        $sheet->setCellValue('E1', 'arrival_time');
        $sheet->setCellValue('F1', 'departure_time');
        $sheet->setCellValue('G1', 'h_minus');
        $sheet->setCellValue('H1', 'status');

        // 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
        $sheet->getColumnDimension('A')->setWidth(15);
        $sheet->getColumnDimension('B')->setWidth(20);
        $sheet->getColumnDimension('C')->setWidth(10);
        $sheet->getColumnDimension('D')->setWidth(15);
        $sheet->getColumnDimension('E')->setWidth(15);
        $sheet->getColumnDimension('F')->setWidth(15);
        $sheet->getColumnDimension('G')->setWidth(10);
        $sheet->getColumnDimension('H')->setWidth(12);

        // Add example data
        $sheet->setCellValue('A2', 'STORE001');
        $sheet->setCellValue('B2', 'Truk Besar');
        $sheet->setCellValue('C2', 'DCKP');
        $sheet->setCellValue('D2', 'Senin');
        $sheet->setCellValue('E2', '08:00');
        $sheet->setCellValue('F2', '06:00');
        $sheet->setCellValue('G2', '1');
        $sheet->setCellValue('H2', 'Active');

        // Add notes
        $sheet->setCellValue('A4', 'Catatan:');
        $sheet->setCellValue('A5', '- store_code: Kode store yang sudah terdaftar');
        $sheet->setCellValue('A6', '- armada_type_name: Nama tipe armada yang sudah terdaftar');
        $sheet->setCellValue('A7', '- type: DCKP atau DSLK');
        $sheet->setCellValue('A8', '- day_name: Senin, Selasa, Rabu, Kamis, Jumat, Sabtu, Minggu');
        $sheet->setCellValue('A9', '- arrival_time: Format HH:MM (contoh: 08:00)');
        $sheet->setCellValue('A10', '- departure_time: Format HH:MM (contoh: 06:00)');
        $sheet->setCellValue('A11', '- h_minus: Angka (contoh: 1, 2, 3)');
        $sheet->setCellValue('A12', '- status: Active atau Inactive');

        $writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
        $filename = 'template_shipment_deliveries_' . 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;
    }

    public function upload_excel(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, 'shipment_deliveries');
            
            $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; // +2 karena index mulai dari 0 dan ada header

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

                try {
                    // Validate required fields
                    if (empty($row[0]) || empty($row[1]) || empty($row[2]) || empty($row[3])) {
                        $errors[] = ['row' => $rowNumber, 'error' => 'Store code, armada type, type, dan day name wajib diisi'];
                        continue;
                    }

                    // Find store
                    $store = Store::where('code', $row[0])->where('delete_flag', 0)->first();
                    if (!$store) {
                        $errors[] = ['row' => $rowNumber, 'error' => 'Store dengan kode ' . $row[0] . ' tidak ditemukan'];
                        continue;
                    }

                    // Find armada type
                    $armadaType = ArmadaType::where('name', $row[1])->where('delete_flag', 0)->first();
                    if (!$armadaType) {
                        $errors[] = ['row' => $rowNumber, 'error' => 'Tipe armada ' . $row[1] . ' tidak ditemukan'];
                        continue;
                    }

                    // Validate type
                    if (!in_array($row[2], ['DCKP', 'DSLK'])) {
                        $errors[] = ['row' => $rowNumber, 'error' => 'Type harus DCKP atau DSLK'];
                        continue;
                    }

                    // Validate day_name
                    $validDays = ['Senin', 'Selasa', 'Rabu', 'Kamis', 'Jumat', 'Sabtu', 'Minggu'];
                    if (!in_array($row[3], $validDays)) {
                        $errors[] = ['row' => $rowNumber, 'error' => 'Hari tidak valid'];
                        continue;
                    }

                    $data = [
                        'store_id' => $store->id,
                        'armada_type_id' => $armadaType->id,
                        'type' => $row[2],
                        'day_name' => $row[3],
                        'arrival_time' => $row[4] ?? null,
                        'departure_time' => $row[5] ?? null,
                        'h_minus' => $row[6] ?? 0,
                        'status' => $row[7] ?? 'Active',
                        'delete_flag' => 0,
                        'updated_by' => auth()->id(),
                    ];

                    // Check if exists (by store_id, armada_type_id, type, and day_name)
                    $existing = ShipmentDelivery::where('store_id', $store->id)
                        ->where('armada_type_id', $armadaType->id)
                        ->where('type', $row[2])
                        ->where('day_name', $row[3])
                        ->first();

                    if ($existing) {
                        $existing->update($data);
                        $updated++;
                    } else {
                        $data['created_by'] = auth()->id();
                        ShipmentDelivery::create($data);
                        $inserted++;
                    }
                } catch (\Exception $e) {
                    $errors[] = ['row' => $rowNumber, 'error' => $e->getMessage()];
                }
            }

            // Log upload
            $errorCount = count($errors);
            \App\Models\ExcelUploadLog::create([
                'upload_type' => 'shipment_deliveries',
                '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);
        }
    }
}
