<?php

namespace App\Jobs;

use App\Exceptions\ImportRowException;
use App\Models\ImportLog;
use App\Services\ImportService;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Modules\Internal\Services\ExclusionService;
use Storage;

class ProcessImport implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public $import_log;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct(ImportLog $importLog)
    {
        $this->import_log = $importLog;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        $file = $this->import_log->files()->where('type', 'import')->first();

        $this->import_log->fill(['status' => 'progress'])->save();
        $corporate = $this->import_log->importable;

        $import = new ImportService();
        $import->read(Storage::path($file->full_path));
        $import->write(Storage::disk('public')->path('result/'.$this->import_log->file_path), 'xsls');

        foreach ($import->sheetsIterator() as $sheetIndex => $sheet) {
            $doc_headers_indexes = [];
            foreach ($sheet->getRowIterator() as $index => $row) {
                if ($index == 1) { // First Row Must be Header
                    foreach ($row->getCells() as $index => $cell) {
                        $title = $cell->getValue();
                        $title = preg_replace( "/\r|\n/", " ", $title );
                        $title = preg_replace('/\xc2\xa0/', " ", $title );
                        $title = rtrim($title);
                        $title = ltrim($title);
                        $doc_headers_indexes[$index] = $title;
                    }

                    // Write Header to File
                    $result_headers = array_merge($doc_headers_indexes, ['Ingest Code', 'Ingest Note']);
                    $import->addArrayToRow($result_headers);

                    // TODO Validate if First Row not Header
                } else { // Next Row Should be Data
                    $row_data = [];
                    $row_map = [
                        0 => 'code',
                        1 => 'description',
                        2 => 'ip_exclusion',
                        3 => 'op_exclusion',
                        4 => 'de_exclusion',
                        5 => 'ma_exclusion',
                        6 => 'sp_exclusion',
                        7 => 'pre_exist_exclusion',
                        8 => 'op_de_exclusion',
                        9 => 'keterangan',
                        10 => 'maternity_waiting'
                    ];
                    
                    foreach ($row->getCells() as $header_index => $cell) {
                        if (isset($row_map[$header_index])) {
                            $value = $cell->getValue();
                            $value = preg_replace( "/\r|\n/", " ", $value );
                            $value = preg_replace('/\xc2\xa0/', " ", $value );
                            $value = rtrim($value);
                            $value = ltrim($value);
                            $row_data[$row_map[$header_index]] = $cell->getValue();
                        }
                    }

                    try { // Process the Row Data
                        if (
                            // empty($row_data['code']) &&
                            // empty($row_data['description']) &&
                            empty($row_data['ip_exclusion']) &&
                            empty($row_data['op_exclusion']) &&
                            empty($row_data['de_exclusion']) &&
                            empty($row_data['ma_exclusion']) &&
                            empty($row_data['sp_exclusion']) &&
                            empty($row_data['pre_exis_exclusion']) &&
                            empty($row_data['op_de_exclusion']) &&
                            empty($row_data['maternity_waiting'])) {
                            continue;
                        }

                        // Save the Row
                        $exclusionService = new ExclusionService();
                        $exclusionService->handleDiagnosisExclusionRow($corporate, $row_data);

                        // Write Success Result to File
                        $import->addArrayToRow(array_merge($row_data, [
                            'Ingest Code' => 200,
                            'Ingest Note' => 'Success',
                        ]), $sheet->getName());

                    } catch (ImportRowException $e) {
                        // Write Data Validation Error to File
                        $import->addArrayToRow(array_merge($row_data, [
                            'Ingest Code' => $e->getCode(),
                            'Ingest Note' => $e->getMessage(),
                        ]), $sheet->getName());
                    } catch (\Exception $e) {
                        throw new \Exception($e);
                        // Write Server Error to File
                        $import->addArrayToRow(array_merge($row_data, [
                            'Ingest Code' => 500,
                            'Ingest Note' => env('APP_DEBUG') ? $e->getMessage() : 'Server Error',
                        ]), $sheet->getName());
                    }
                }
            }

            break; // Only Read First Row
        }
        $import->reader->close();
        Storage::delete('temp/'.$file_name);
        $import->writer->close();

    }
}
