<?php

namespace App\Http\Controllers\Traits;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
use SpreadsheetReader;

trait CsvImportTrait
{
    public function processCsvImport(Request $request)
    {
        try {
            $filename = $request->input('filename', false);
            $path     = storage_path('app/csv_import/' . $filename);

            $hasHeader = $request->input('hasHeader', false);

            $fields = $request->input('fields', false);
            $fields = array_flip(array_filter($fields));

            $modelName = $request->input('modelName', false);
            $model     = "App\Models\\" . $modelName;

            $reader = new SpreadsheetReader($path);
            $insert = [];

            foreach ($reader as $key => $row) {
                if ($hasHeader && $key == 0) {
                    continue;
                }

                $tmp = [];
                foreach ($fields as $header => $k) {
                    if (isset($row[$k])) {
                        $tmp[$header] = $row[$k];
                    }
                }

                if (count($tmp) > 0) {
                    $insert[] = $tmp;
                }
            }

            $for_insert = array_chunk($insert, 100);


            //Assets Import Only
            /*
            foreach ($for_insert as $insert_item) {
                // Get list of fillable columns from the model
                $fillableColumns = (new $model)->getFillable();

                // Define CSV header mapping to database columns
                $headerMapping = [
                    'client_id' => 'client_id',
                    'air_compressor_part_no' => 'air_compressor_part_no',
                    'air_compressor_serial_no' => 'air_compressor_serial_no',
                    'air_dryer_part_no' => 'air_dryer_part_no',
                    'airdryer_serial_no' => 'airdryer_serial_no',
                    'filter_part_no' => 'filter_part_no',
                    'filter_serial_no' => 'filter_serial_no',
                    'eco_drain_serial_no' => 'eco_drain_serial_no',
                    'eco_drain_part_no' => 'eco_drain_part_no',
                    'air_receiver_id' => 'air_receiver_id',
                    'commisioned_date' => 'commisioned_date',
                    'warranty_start_date' => 'warranty_start_date',
                    'warranty_end_date' => 'warranty_end_date',
                    'commissioning' => 'commissioning',
                    'air_dryer_id' => 'airdryer_id',
                    'filter_id' => 'filter_id',
                    'eco_drain_id' => 'eco_drain_id',
                    'air_compressor_id' => 'air_compressor_id'
                ];

                // Define columns that should be integers
                $integerColumns = [
                    'client_id',
                    'air_receiver_id',
                    'airdryer_id',
                    'filter_id',
                    'eco_drain_id',
                    'air_compressor_id'
                ];

                $complete_items = array_map(function($row) use ($headerMapping, $fillableColumns, $integerColumns) {
                    // Create base array with all fillable columns set to null
                    $base = array_fill_keys($fillableColumns, null);

                    // Map and clean the data
                    $cleaned_data = [];
                    foreach ($row as $csvHeader => $value) {
                        // Skip if header mapping doesn't exist
                        if (!isset($headerMapping[$csvHeader])) {
                            continue;
                        }

                        // Get the database column name
                        $dbColumn = $headerMapping[$csvHeader];

                        // Convert empty strings to null
                        if ($value === '' || $value === 'NULL') {
                            $cleaned_data[$dbColumn] = null;
                            continue;
                        }

                        // Handle integer columns
                        if (in_array($dbColumn, $integerColumns)) {
                            if ($value === null || $value === '') {
                                $cleaned_data[$dbColumn] = null;
                            } else {
                                // Remove any non-numeric characters and convert to integer
                                $numericValue = preg_replace('/[^0-9]/', '', $value);
                                $cleaned_data[$dbColumn] = $numericValue ? (int)$numericValue : null;
                            }
                            continue;
                        }

                        // Handle date fields
                        $dateFields = ['commisioned_date', 'warranty_start_date', 'warranty_end_date'];
                        if (in_array($dbColumn, $dateFields) && $value) {
                            try {
                                $cleaned_data[$dbColumn] = \Carbon\Carbon::createFromFormat('d-m-Y', $value)->format('Y-m-d');
                            } catch (\Exception $e) {
                                $cleaned_data[$dbColumn] = null;
                            }
                            continue;
                        }

                        $cleaned_data[$dbColumn] = $value;
                    }

                    // Merge cleaned data with base array
                    return array_merge($base, $cleaned_data);
                }, $insert_item);

                // Debug the output before insert (uncomment if needed)
                // dd($complete_items);

                $model::insert($complete_items);
            }

            //Assets Import ONly Finish
            */


            foreach ($for_insert as $insert_item) {
                $model::insert($insert_item);
            }

            $rows  = count($insert);
            $table = Str::plural($modelName);

            File::delete($path);

            session()->flash('message', trans('global.app_imported_rows_to_table', ['rows' => $rows, 'table' => $table]));

            return redirect($request->input('redirect'));
        } catch (\Exception $ex) {
            throw $ex;
        }
    }

    public function parseCsvImport(Request $request)
    {
        $file = $request->file('csv_file');
        $request->validate([
            'csv_file' => 'mimes:csv,txt',
        ]);

        $path      = $file->path();
        $hasHeader = $request->input('header', false) ? true : false;

        $reader  = new SpreadsheetReader($path);
        $headers = $reader->current();
        $lines   = [];

        $i = 0;
        while ($reader->next() !== false && $i < 5) {
            $lines[] = $reader->current();
            $i++;
        }

        $filename = Str::random(10) . '.csv';
        $file->storeAs('csv_import', $filename);

        $modelName     = $request->input('model', false);
        $fullModelName = "App\Models\\" . $modelName;

        $model     = new $fullModelName();
        $fillables = $model->getFillable();

        $redirect = url()->previous();

        $routeName = 'admin.' . strtolower(Str::plural(Str::kebab($modelName))) . '.processCsvImport';

        return view('csvImport.parseInput', compact('headers', 'filename', 'fillables', 'hasHeader', 'modelName', 'lines', 'redirect', 'routeName'));
    }
}
