<?php

namespace App\Http\Controllers;

use App\Models\Store;
use App\Models\ExcelUploadLog;
use App\Services\CacheService;
use App\Traits\ExcelUploadTrait;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Cache;
use Illuminate\Validation\Rule;

class StoresController extends Controller
{
    use ExcelUploadTrait;

    public function index(Request $request)
    {
        if ($request->ajax()) {
            // $query = Store::where('delete_flag', 0);
            $query = Store::select('m_stores.*');

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

            $total = $query->count();

            // Sorting
            $columns = ['id', 'code', 'name', 'pic', '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) {
                $result[] = [
                    $no++,
                    '<a href="' . route('stores.show', $row->id) . '">' . $row->code . '</a>',
                    $row->name,
                    $row->pic,
                    $row->status, 
                    $row->created_at->format('M jS Y, H:i'),
                ];
            }

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

        // Cache view data
        $variables['stores'] = CacheService::getStores();

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

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

    public function edit(Store $store)
    {
        $variables['judul'] = 'Edit data';
        return view('m-stores.form', [
            'data' => $store,
            'variables' => $this->variables($variables)
        ]);
    }

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

    public function store(Request $request, $prm_id)
    {
        $store = null;
        if ($prm_id)
            $store = Store::findOrFail($prm_id); // Jika tidak ditemukan, otomatis throw 404

        // Validasi untuk description dan data items
        $rules = [
            'code' => [
                'required',
                'string',
                'max:20',
                Rule::unique('m_stores', 'code')->ignore($store?->id)->where(function ($query) {
                    return $query->where('delete_flag', 0);
                }),
            ],
            'version' => 'required|numeric|min:0',
            'name' => [
                'required',
                'string',
                'max:100',
                Rule::unique('m_stores', 'name')->ignore($store?->id),
            ], 
            'pic' => 'nullable|string|max:64',
            'pic_phone' => 'nullable|string|max:16',
            'pic_email' => 'nullable|string|email|max:64',
            'address' => 'nullable|string|max:256',  
        ];

        $messages = [
            'code.required' => 'Store code is required',
            'code.unique' => 'Store code already exists',
            'code.max' => 'Store code maximum 20 characters',
        ];
        $saveData = $request->validate($rules, $messages);

        // echo '<pre>';
        // print_r($saveData);
        // exit; 
        try {
            DB::beginTransaction();
            // Jika ada $store, berarti update
            if ($store) {
                $store->update(array_merge($saveData, [
                    'updated_by' => $this->logged_user_id,
                ]));
                $notif = 'Updated successfully.';
            } else {
                // Jika tidak ada $store, berarti create
                $store = Store::create(array_merge($saveData, [
                    'created_by' => $this->logged_user_id,
                ]));
                $notif = 'Successfully created.';
            }

            DB::commit();
            
            // Clear cache
            CacheService::clearStoreCache($store->id);
            
            return response()->json(['success', $notif]);
        } catch (\Exception $e) {
            DB::rollback();

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

    public function show(Store $store)
    {
        $store->load(['creator', 'modificator', 'storeRawMaterials.rawMaterial']);
        $variables['judul'] = 'View data ID#' . $store->id;
        return view('m-stores.show', [
            'data' => $store,
            'variables' => $this->variables($variables)
        ]);
    }

    public function destroy(Store $store)
    {
        if ($store->delete_flag == 0) {
            $store->update([
                'delete_flag' => 1,
                'status' => 'Inactive',
                'inactive_date' => date('Y-m-d H:i:s'),
                'updated_by' => $this->logged_user_id
            ]);

            // Clear cache
            CacheService::clearStoreCache($store->id);

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

            // Clear cache
            CacheService::clearStoreCache($store->id);

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

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

        return $e;
    }

    /**
     * Upload Excel untuk bulk insert/update stores
     */
    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, 'stores');
            
            $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])) {
                        $errors[] = ['row' => $rowNumber, 'error' => 'Code dan Name wajib diisi'];
                        continue;
                    }

                    $status = $row[5] ?? 'Active';
                    $data = [
                        'code' => $row[0],
                        'name' => $row[1],
                        'address' => $row[2] ?? null,
                        'pic' => $row[3] ?? null,
                        'phone' => $row[4] ?? null,
                        'status' => $status,
                        'inactive_date' => ($status == 'Inactive') ? now() : null,
                        'delete_flag' => 0,
                        'updated_by' => auth()->id(),
                    ];

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

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

                    // Clear cache
                    Cache::forget('select_stores');
                } catch (\Exception $e) {
                    $errors[] = ['row' => $rowNumber, 'error' => $e->getMessage()];
                }
            }

            // Log upload
            $errorCount = count($errors);
            \App\Models\ExcelUploadLog::create([
                'upload_type' => 'stores',
                '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 stores
     */
    public function downloadTemplate()
    {
        $spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
        $sheet = $spreadsheet->getActiveSheet();

        // Set header
        $sheet->setCellValue('A1', 'Code');
        $sheet->setCellValue('B1', 'Name');
        $sheet->setCellValue('C1', 'Address');
        $sheet->setCellValue('D1', 'PIC');
        $sheet->setCellValue('E1', 'Phone');
        $sheet->setCellValue('F1', '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:F1')->applyFromArray($headerStyle);

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

        // Add sample data
        $sheet->setCellValue('A2', 'STORE001');
        $sheet->setCellValue('B2', 'BakmieGM Soho Pancoran');
        $sheet->setCellValue('C2', 'Jl. Letjen MT Haryono');
        $sheet->setCellValue('D2', 'John Doe');
        $sheet->setCellValue('E2', '021-1234567');
        $sheet->setCellValue('F2', 'Active');

        $sheet->setCellValue('A3', 'STORE002');
        $sheet->setCellValue('B3', 'BakmieGM Kelapa Gading');
        $sheet->setCellValue('C3', 'Jl. Boulevard Raya');
        $sheet->setCellValue('D3', 'Jane Smith');
        $sheet->setCellValue('E3', '021-7654321');
        $sheet->setCellValue('F3', 'Active');

        $writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
        $filename = 'template_stores_' . 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;
    }
    
    protected function getUniqueField()
    {
        return 'code';
    }
}
