<?php

namespace Aura\Export\Http\Livewire;

use Maatwebsite\Excel\Facades\Excel;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;

use Barryvdh\DomPDF\Facade\Pdf;

use Illuminate\Database\Eloquent\Collection;
use LivewireUI\Modal\ModalComponent;

class ExportSelectedModal extends ModalComponent
{

    public $model;

    public $fields;

    public $selected;

    public $action;

    public $exportFormat = 'csv';

    public $exportFields = [];

    public $filepath;

    public function mount($selected)
    {
        // Set exportFields to the fields of the model of a selected Item
        // get first item from selected array
        $this->model = app($this->model);
        $this->exportFields = array_keys($this->model->getColumns());
        $this->fields = array_keys($this->model->getColumns());

        // ray('model:', $this->model, $selected, $this->fields, $this->exportFields);
    }

    public function export()
    {
        // Retrieve the records to export
        $records = $this->model::findMany($this->selected);

        // ray('records', $records->toArray(), $this->selected);

        // Select only the fields to export
        $records = $records->map(function ($record) {
            $data = array_merge($record->toArray(), $record['fields']->toArray());
            return collect($data)->only($this->exportFields)->toArray();
        });

        // ray('records2', $records->toArray());

        // Export the records
        switch ($this->exportFormat) {
            case 'csv':
                // Handle CSV export
                $this->exportCsv($records);
                break;
            case 'excel':
                // Handle Excel export
                $this->exportExcel($records);
                break;
            case 'pdf':
                // Handle PDF export
                $this->exportPdf($records);
                break;
            case 'xml':
                // Handle XML export
                $this->exportXml($records);
                break;
        }
    }

    public function exportXml($posts)
    {
        $xml = new \SimpleXMLElement('<root/>');

        foreach ($posts as $post) {
            $postNode = $xml->addChild('post');
            foreach ($post as $key => $value) {
                $postNode->addChild($key, $value);
            }
        }

        $filename = 'posts_' . date('YmdHis') . '.xml';
        $filepath = storage_path('exports/' . $filename);

        $xml->asXML($filepath);

        return 'XML stored successfully at ' . $filepath;
    }

    public function exportCsv($posts)
    {
        // ray('exportCsv', $posts->toArray());

        $posts = $posts->toArray();

        $filename = 'posts_' . date('YmdHis') . '.csv';
        $filepath = storage_path('exports/' . $filename);

        if (!file_exists(dirname($filepath))) {
            mkdir(dirname($filepath), 0777, true);
        }

        $handle = fopen($filepath, 'w');

        $header = []; // Declare $header here

        foreach ($posts as $post) {
            // ray('post', $post);
            // Only fetch data fields that are in the $this->exportFields
            // merge post and post['fields']
            // $post = array_merge($post, $post['fields']);

            $data = array_intersect_key($post, array_flip($this->exportFields));

            if (empty($header)) {
                $header = array_keys($data);
                fputcsv($handle, $header);
            }
            $dataValues = array_values($data);
            // ray('csv Hier', $dataValues, $data, $header);
            fputcsv($handle, $dataValues);
        }

        fclose($handle);

        $this->filepath = $filepath;
    }

    public function exportExcel($posts)
    {
        $filename = 'posts_' . date('YmdHis') . '.xlsx';
        $filepath = 'exports/' . $filename;

        // Define an exportable collection with headings
        $exportable = new class($posts, $this->exportFields) implements FromCollection, WithHeadings {
            private $posts;
            private $fields;

            public function __construct($posts, $fields)
            {
                $this->posts = $posts;
                $this->fields = $fields;
            }

            // Define the collection of records to export
            public function collection()
            {
                return $this->posts->map(function ($post) {
                    // Only fetch data fields that are in the $this->exportFields
                    return collect($post)->only($this->fields)->values();
                });
            }

            // Define the headings based on export fields
            public function headings(): array
            {
                return $this->fields;
            }
        };

        ray('exportExcel', $exportable, $posts->toArray(), $this->exportFields);

        // Store the Excel file and check if it was stored successfully
        $stored = Excel::store($exportable, $filepath);

        ray('stored', $stored, $filepath);

        if ($stored) {
            $this->filepath = $filepath;
            return 'File stored successfully at ' . $filepath;
        } else {
            return 'Failed to store file';
        }

    }

    public function exportPdf($posts)
    {
        $filename = 'posts_' . date('YmdHis') . '.pdf';
        $filepath = storage_path('exports/' . $filename);


        ray('exportPdf', $posts->toArray(), $this->exportFields);

        $pdf = Pdf::loadView('export::pdf.export', ['posts' => $posts]);

        $pdf->save($filepath);

        return $pdf->download($filepath);
    }

    public static function modalMaxWidth(): string
    {
        return '7xl';
    }

    public function render()
    {
        return view('export::livewire.export-selected-modal');
    }
}
