<?php

namespace Modules\Internal\Http\Controllers\Api;

use App\Models\Icd;
use App\Services\ImportService;
use App\Helpers\Helper;
use Illuminate\Contracts\Support\Renderable;

use Box\Spout\Reader\Common\Creator\ReaderEntityFactory;
use Box\Spout\Writer\Common\Creator\Style\StyleBuilder;
use Box\Spout\Common\Entity\Style\CellAlignment;
use Box\Spout\Common\Entity\Style\Color;
use Box\Spout\Writer\Common\Creator\WriterEntityFactory;
use Box\Spout\Common\Entity\Row;

use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Storage;
use Modules\Internal\Services\IcdService;

class DiagnosisController extends Controller
{
    public function __construct(IcdService $icdService)
    {
        $this->icdService = $icdService;
    }
    /**
     * Display a listing of the resource.
     * @return Renderable
     */
    public function index(Request $request, $diagnosis_template_id)
    {
        
        $diagnosis = Icd::query()
                            ->filter($request->toArray())
                            ->where('icd_template_id', '=', $diagnosis_template_id)
                            ->orderBy('code', 'ASC')
                            ->paginate(15);
        return $diagnosis;
    }

    /**
     * Show the form for creating a new resource.
     * @return Renderable
     */
    public function create()
    {
        return view('internal::create');
    }

    /**
     * Store a newly created resource in storage.
     * @param Request $request
     * @return Renderable
     */
    public function store(Request $request)
    {
        //
    }

    /**
     * Show the specified resource.
     * @param int $id
     * @return Renderable
     */
    public function show($id)
    {
        return view('internal::show');
    }

    /**
     * Show the form for editing the specified resource.
     * @param int $id
     * @return Renderable
     */
    public function edit($id)
    {
        return view('internal::edit');
    }

    /**
     * Update the specified resource in storage.
     * @param Request $request
     * @param int $id
     * @return Renderable
     */
    public function update(Request $request, $id)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     * @param int $id
     * @return Renderable
     */
    public function destroy($id)
    {
        //
    }

    public function search(Request $request)
    {
        return Icd::when($request->search ?? null, function($icd, $search) {
            $icd->where('name', 'LIKE', '%'.$search.'%')
                ->orWhere('code', 'LIKE', '%'.$search.'%');
        })->limit(10)->get();
    }

    public function import(Request $request, $id) 
    {
        $request->validate([
            'file' => 'required|file|mimes:xls,xlsx,csv,txt',
        ]);
        $file_name = now()->getPreciseTimestamp(3).'-'.$request->file('file')->getClientOriginalName();
        $file = $request->file('file')->storeAs('temp', $file_name);

        $import = new ImportService();
        $import->read(Storage::path('temp/'.$file_name));
        $import->write(Storage::disk('public')->path('temp/result-'.$file_name), 'xsls');

        $imported_icd_data = 0;
        $failed_icd_data = [];
        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 => 'ICD_Code',
                        1 => 'Description',
                    ];
                    
                    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['ICD_Code']) &&
                            empty($row_data['Description'])
                            ) {
                            continue;
                        }

                        // Save the Row
                        $icdService = new IcdService();
                        $icdService->handleIcdRow($row_data, $id);

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

                    } 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());
                        $failed_icd_data[] = ['row_number' => $index, 'error' => $e->getMessage(), 'data' => $row_data];
                    } 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());
                        $failed_icd_data[] = ['row_number' => $index, 'error' => $e->getMessage(), 'data' => $row_data];
                    }
                }
            }

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

        return [
            'total_successed_row' => $imported_icd_data,
            'total_failed_row' => count($failed_icd_data),
            'failed_row' => $failed_icd_data,
            'result_file' => [
                'url' => Storage::disk('public')->url('temp/result-'.$file_name),
                'name' => 'result-'.$file_name,
            ]
        ];
    }

    public function activation(Request $request, $diagnosis_id)
    {
        $request->validate([
            'active' => 'required'
        ]);

        $Icd = Icd::findOrFail($diagnosis_id);
        $Icd->active = $request->active == '1';

        if ($Icd->save()) {
            return response()->json([
                'icd' => $Icd,
                'message' => 'Status Updated Successfully'
            ]);
        }
    }

    public function generateIcdList(Request $request, $diagnosis_id){
        // Mendapatkan data yang akan diekspor (misalnya, dari database)
        $data = Icd::where('icd_template_id', $diagnosis_id)->get()->toArray();

        // Membuat penulis entitas Spout
        $writer = WriterEntityFactory::createXLSXWriter();
        
        // Membuka penulis untuk menulis ke file
        $writer->openToFile(public_path('files/TemplateICDList.xlsx'));
        /** Create a style with the StyleBuilder */
        $style = (new StyleBuilder())
            ->setFontBold()
            ->build();
        
        // Menulis header kolom
        $headers_map_to_table_fields = $this->icdService->listing_doc_headers;
        $headerRow = WriterEntityFactory::createRowFromArray($headers_map_to_table_fields, $style);
              
        $writer->addRow($headerRow);
      
        // Menulis data
        if (!empty($data)) {
            foreach ($data as $item) {
                $rowData = [
                    // $item['rev'],           // Rev
                    // $item['version'],       // Version
                    $item['code'],          // Code
                    // $item['parent_code'],   // Parent Code
                    $item['name'],          // Name
                    // $item['description'],   // Description
                    // $item['active'] == 1 ? 'Active' : 'Inactive', // Status
                    // $item['type'],          // Type
                ];
        
                $row = WriterEntityFactory::createRowFromArray($rowData);
                $writer->addRow($row);
            }
        }
        
        // Menutup penulis
        $writer->close();
        
        // Mengembalikan response untuk mengunduh file
        $filePath = public_path('files/TemplateICDList.xlsx');
        
        return Helper::responseJson([
            'file_name' => "Diagnosis ICD List " . date('Y-m-d h:i:s'),
            "file_url" => url('files/TemplateICDList.xlsx')
        ]);
        
   }
}
