<?php

namespace Modules\Internal\Http\Controllers\Api;

use App\Exceptions\ImportRowException;
use App\Helpers\Helper;
use App\Models\CorporateFormularium;
use App\Models\Formularium;
use App\Models\FormulariumTemplate;
use App\Services\ImportService;
use Illuminate\Contracts\Support\Renderable;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Storage;
use Modules\Internal\Transformers\CorporateFormulariumResource;
use Modules\Internal\Services\FormulariumService;

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;

class CorporateFormulariumController extends Controller
{
    /**
     * Display a listing of the resource.
     * @return Renderable
     */
    public function __construct(FormulariumService $formulariumService)
    {
        $this->formulariumService = $formulariumService;
    }
    public function index(Request $request, $corporate_id)
    {
        $formulariums = CorporateFormularium::query()
                ->where('corporate_id', $corporate_id)
                ->paginate(15);
        // if (!empty($request->status) && $request->status == 'inactive') {
        //     $formulariums = $formulariums->whereDoesntHave('corporateFormulariums');
        // } else if (!empty($request->status) && $request->status == 'all') {

        // } else { // Active or Default
        //     $formulariums->whereHas('corporateFormulariums', function ($corporateFormularium) use ($corporate_id){
        //         $corporateFormularium->where('corporate_id', $corporate_id);
        //     });
        // }
        return Helper::paginateResources(CorporateFormulariumResource::collection($formulariums));
    }

    /**
     * Show the form for creating a new resource.
     * @return Renderable
     */
    public function create(Request $request, $corporate_id)
    {
        $data = CorporateFormularium::where('corporate_id', $corporate_id)->pluck('formularium_template_id')->toArray(); // agar tidak dobel
        $formularium_template = FormulariumTemplate::whereNotIn('id', $data)->get();
        $respone = [
            "status" => 200,
            "message" => 'data berhasil diambil',
            "data" => $formularium_template
        ];
        return $respone;
    }

    /**
     * Store a newly created resource in storage.
     * @param Request $request
     * @return Renderable
     */
    public function store(Request $request, $corporate_id)
    {
        $request->validate([
            'id' => 'required'
        ]);

        $checkFormularium = FormulariumTemplate::find($request->id);
        if (!$checkFormularium){
            $respone = [
                "status" => 404,
                "message" => "data master formularium tidak ditemukan",
                "data" => []
            ];
            return $respone;
        }
        $newCorporateFormularium = CorporateFormularium::create([
            'corporate_id' => $corporate_id,
            'formularium_template_id' => $request->id,
            'active' => 1
        ]);

        if ($newCorporateFormularium){
            $respone = [
                "status" => 200,
                "message" => "data berhasil disimpan"
            ];
            return $respone;
        }

        return $newCorporatePlan;
    }

    /**
     * Show the specified resource.
     * @param int $id
     * @return Renderable
     */
    public function show(Request $request, $corporate_id, $id)
    {
        $data = Formularium::where('formularium_template_id', $id)->get();
        $respone = [
            "status" => 200,
            "message" => 'data berhasil diambil',
            "data" => $data
        ];
        return $respone;
    }

    /**
     * Show the form for editing the specified resource.
     * @param int $id
     * @return Renderable
     */
    public function edit(Request $request, $corporate_id)
    {
        $data = CorporateFormularium::where('corporate_id', $corporate_id)->pluck('formularium_template_id')->toArray(); // agar tidak dobel
        $formularium_template = FormulariumTemplate::whereNotIn('id', $data)->get();
        $respone = [
            "status" => 200,
            "message" => 'data berhasil diambil',
            "data" => $formularium_template
        ];
        return $respone;
    }

    /**
     * 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 updateStatus($corporate_id, $formularium_id , $status)
    {
        if ($status == 'activate') {
            $corporateFormularium = CorporateFormularium::updateOrCreate([
                'corporate_id' => $corporate_id,
                'formularium_id' => $formularium_id
            ], [
                'corporate_id' => $corporate_id,
                'formularium_id' => $formularium_id,
            ]);

            return response()->json([
                'status' => 'active',
                'message' => 'Formularium activated'
            ]);
        } else {
            $deleteCorporateFormularium = CorporateFormularium::where([
                'corporate_id' => $corporate_id,
                'formularium_id' => $formularium_id
            ])->delete();

            return ($deleteCorporateFormularium) ? response()->json([
                    'status' => 'inactive',
                    'message' => 'Formularium deactivated'
                ]) : response()->json([
                    'status' => 'error',
                    'message' => 'Error deactivating formularium'
                ]);
        }
    }

    public function active(Request $request, $corporate_id, $id)
    {
        $corporateFormularium = CorporateFormularium::find($id);
        $corporateFormularium->fill([
            'active' => $request->active,
        ])->save();

        $respone = [
            "status" => 200,
            "message" => 'data berhasil diedit',
            "data" => $corporateFormularium
        ];

        return $respone;
    }

    public function import(Request $request, $id) 
    {
        $request->validate([
            'file' => 'required|file|mimes:xls,xlsx,csv,txt',
        ]);
        // dd($request->toArray());
        $file_name = now()->getPreciseTimestamp(3).'-'.$request->file('file')->getClientOriginalName();
        $file = $request->file('file')->storeAs('temp', $file_name);
        
        // $importLog = $corporate->importLogs()->create([
        //     'type' => 'diagnosis-exclusions',
        //     'file_path' => $file,
        //     'status' => 'pending',
        //     'progress' => 0,
        // ]);

        $import = new ImportService();
        $import->read(Storage::path('temp/'.$file_name));
        $import->write(Storage::disk('public')->path('temp/result-'.$file_name), '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']);
                    // Tambahkan 'Ingest Code' dan 'Ingest Note' ke akhir array
                    $doc_headers_indexes[] = 'Ingest Code';
                    $doc_headers_indexes[] = 'Ingest Note';
                    $import->addArrayToRow($doc_headers_indexes);

                    // TODO Validate if First Row not Header
                } else { // Next Row Should be Data
                    $row_data = [];
                    $row_map = [
                        0 => 'code',
                        1 => 'active',
                    ];
                    
                    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'])){
                            throw new ImportRowException(__('Internal Code is REQUIRED'), 405, null, $row_data);
                        }
                        if (
                            // empty($row_data['code']) &&
                            // empty($row_data['description']) &&
                            empty($row_data['code']) &&
                            empty($row_data['active'])
                            ) {
                            continue;
                        }

                        // Save the Row
                        $formulariums = Formularium::where('code', $row_data['code'])->first();
                        if ($formulariums){
                            $row_data['formularium_id'] = $formulariums->id;
                        } else {
                            throw new ImportRowException(__('Internal Code is Not Found'), 405, null, $row_data);
                        }
                        $formulariumService = new FormulariumService();
                        $formulariumService->handleFormuariumCorporateRow($row_data, $id);

                        // 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();

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

    public function generateFormulariumList(Request $request, $id){
        // Mendapatkan data yang akan diekspor (misalnya, dari database)
        // $data = Formularium::get()->toArray();
        $formulariums = Formularium::query()
                ->filter($request->all());
        // if (!empty($request->status) && $request->status == 'inactive') {
        //     $formulariums = $formulariums->whereDoesntHave('corporateFormulariums');
        // } else if (!empty($request->status) && $request->status == 'all') {

        // } else { // Active or Default
        //     $formulariums->whereHas('corporateFormulariums', function ($corporateFormularium) use ($corporate_id){
        //         $corporateFormularium->where('corporate_id', $corporate_id);
        //     });
        // }
        $data = $formulariums->with(['corporateFormulariums' => function ($query) use ($id) {
                    $query->where('corporate_id', $id);
                }])->get()->toArray();
        // Membuat penulis entitas Spout
        $writer = WriterEntityFactory::createXLSXWriter();
        
        // Membuka penulis untuk menulis ke file
        $writer->openToFile(public_path('files/TemplateFormulariumList.xlsx'));
        /** Create a style with the StyleBuilder */
        $style = (new StyleBuilder())
            ->setFontBold()
            ->build();
        
        // Menulis header kolom
        $headers_map_to_table_fields = $this->formulariumService->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['code'],           // code
                    $item['name'],       // name
                    $item['description'],          // Description
                    $item['manufacturer'],   // manufacturer
                    $item['category_name'],          // category_name
                    $item['kategori_obat'],   // kategori_obat
                    $item['uom'],   // uom
                    $item['general_indication'],   // Description
                    $item['composition'],   // composition
                    $item['atc_code'],   // atc_code
                    $item['class'],   // class
                    $item['bpom_registration'],   // bpom_registration
                    $item['classifications'],   // classifications
                    $item['cat_for'],   // cat_for
                  
                ];
        
                $row = WriterEntityFactory::createRowFromArray($rowData);
                $writer->addRow($row);
            }
        }
        
        // Menutup penulis
        $writer->close();
        
        // Mengembalikan response untuk mengunduh file
        $filePath = public_path('files/TemplateFormulariumList.xlsx');
        
        return Helper::responseJson([
            'file_name' => "Formularium List " . date('Y-m-d h:i:s'),
            "file_url" => url('files/TemplateFormulariumList.xlsx')
        ]);
        
    }
}
