<?php

namespace App\Livewire\Projects\Tabs;

use App\Models\Project;
use App\Models\ProjectEmailRecipient;
use App\PivotNameAnalyser;
use App\Rules\HarvestFile;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Laravel\Jetstream\InteractsWithBanner;
use Livewire\Component;
use Livewire\WithFileUploads;

class Settings extends Component
{
    use InteractsWithBanner;
    use WithFileUploads;

    public $formData = [];

    public $processOutput = '';

    public $confirmingReportDeletion = false;

    public $projectIdBeingDeleted;

    public array $pivotFiles;
    public array $spanFiles;
    public array $harvestDataFiles;

    private $pivotNameAnalyser = false;

    public $isDirty = false;

    public $showFieldNameModal = false;


    /**
     * Mount the component.
     *
     * @return void
     */
    public function mount(Project $project)
    {
        $this->formData = $project->toArray();
        $this->formData['mail_recipients'] = $project->emailRecipients->toArray() ?: [
            [
                'name'  => '',
                'email' => '',
            ]
        ];
        $this->formData['pivot_file'] = Storage::disk('local')->get($project->name.'/Data/pivot.geojson');
        $this->formData['span_file'] = Storage::disk('local')->get($project->name.'/Data/span.geojson');
        $this->formData['harvest_file'] = null;
    }

    public function saveProject()
    {
        $this->resetErrorBag();
        $this->mergeFormData();
        $this->validateForm();
        Project::saveWithFormData($this->formData);
        //dd(route('project.show',[$this->formData['name'],$this->formData['id'],'settings']));
        return redirect()->route('project.show', [$this->formData['name'], $this->formData['id'], 'settings']);
        //$this->dispatch('saved');

    }

    public function saveMailSettings()
    {
        $this->resetErrorBag();
        $this->validateEmailSettingsForm();
        Project::saveWithFormData($this->formData);
        $this->dispatch('saved');
    }

    public function saveSettings()
    {
        $this->resetErrorBag();
        $this->mergeFormData();
        $this->validateForm();
        $this->validateEmailSettingsForm();
        $this->shouldReload();
        Project::saveWithFormData($this->formData);
        $this->shouldDownload();
        //check if the project name changed
        if ($this->isDirty) {
            redirect()->route('project.show', [$this->formData['name'], $this->formData['id'], 'settings']);
        }
//        $this->dispatch('download_notify',title:'Download',message:'hallo');
        $this->dispatch('saved');
    }

    public function shouldReload()
    {
        if (Project::find($this->formData['id'])?->name == $this->formData['name']) {
            return;
        }
        $this->isDirty = true;
    }

    public function shouldDownload()
    {
        /**
         * @var Project $project
         */
        $project = Project::find($this->formData['id']);
        if ($project->hasMissingDownloadsDateInHarvestFile()) {
            $this->dispatch('download_notify');
            session(['show-download.'.$project->id => true]);
        }
    }

    public function addEmailRecipient()
    {
        $this->formData['mail_recipients'][] =
            [
                'name'  => '',
                'email' => '',
            ];
    }

    public function deleteEmailRecipient($index)
    {
        if (array_key_exists('id', $this->formData['mail_recipients'][$index])) {
            ProjectEmailRecipient::whereId($this->formData['mail_recipients'][$index]['id'])->delete();
        }
        unset($this->formData['mail_recipients'][$index]);
        $this->formData['mail_recipients'] = array_values($this->formData['mail_recipients']);
        $this->dispatch('saved');
    }


    /**
     * Confirm that the given Project should be deleted.
     *
     * @param  int  $reportId
     * @return void
     */
    public function confirmReportDeletion($reportId)
    {
        $this->confirmingReportDeletion = true;

        $this->reportIdBeingDeleted = $reportId;
    }

    /**
     * Delete the project
     *
     * @return void
     */
    public function deleteProject()
    {
        Project::whereId($this->reportIdBeingDeleted)->first()->delete();
        $this->resetFormData();

        $this->confirmingReportDeletion = false;
    }

    /**
     * Get the current user of the application.
     *
     * @return mixed
     */
    public function getProjectsProperty()
    {
        return Project::all();
    }


    private function resetFormData()
    {
        $this->formData = [
            'name'            => '',
            'mail_subject'    => '',
            'mail_template'   => '',
            'mail_frequency'  => '',
            'mail_day'        => '',
            'mail_recipients' => [],
        ];
        $this->pivotFiles = [];
        $this->spanFiles = [];
        $this->harvestDataFiles = [];
        $this->addEmailRecipient();
    }

    private function validateForm()
    {
        $projectIdentifier = $this->formData['id'] ?? null;
        $acceptedGeoJsonExtenstions = ['txt', 'json', 'geojson'];

        return Validator::make([
            'name'         => $this->formData['name'],
            'pivot_file'   => $this->formData['pivot_file'],
            'span_file'    => $this->formData['span_file'],
            'harvest_file' => $this->formData['harvest_file'],
        ], [
            'name'                 => [
                'required',
                Rule::unique('projects')->ignore($projectIdentifier),
                'string',
                'max:255'
            ],
            'pivot_file.extension' => [
                'sometimes', function ($attribute, $value, $fail) use ($acceptedGeoJsonExtenstions) {
                    if ($value && !in_array($value, $acceptedGeoJsonExtenstions)) {
                        $fail('The upload field must have one of the following extensions: json, geojson or txt.');
                    }
                }
            ],
            'span_file.extension'  => [
                'sometimes', function ($attribute, $value, $fail) use ($acceptedGeoJsonExtenstions) {
                    if ($value && !in_array($value, $acceptedGeoJsonExtenstions)) {
                        $fail('The upload field must have one of the following extensions: json, geojson or txt.');
                    }
                }
            ],
            'harvest_file'         => ['sometimes', new HarvestFile],
        ])->validate();

    }

    private function validateEmailSettingsForm()
    {
        Validator::make([
            'mail_template'   => $this->formData['mail_template'],
            'mail_subject'    => $this->formData['mail_subject'],
            'mail_frequency'  => $this->formData['mail_frequency'],
            'mail_day'        => $this->formData['mail_day'],
            'mail_recipients' => $this->formData['mail_recipients'],
        ], [
            'mail_template'           => ['required', 'string',],
            'mail_subject'            => ['required', 'string',],
            'mail_frequency'          => ['required', 'string',],
            'mail_day'                => ['required', 'string',],
            'mail_recipients'         => ['required', 'array', 'min:1'],
            'mail_recipients.*.name'  => ['required', 'string', 'max:255'],
            'mail_recipients.*.email' => ['required', 'email'],
        ])->validateWithBag('saveEmailSettingsForm');
    }

    /**
     * @return mixed
     */
    public function mergeFormData(): void
    {
        $this->formData['pivot_file'] = $this->pivotFiles[0] ?? null;
        $this->formData['span_file'] = $this->spanFiles[0] ?? null;
        $this->formData['harvest_file'] = $this->harvestDataFiles[0] ?? null;
    }

    public function render()
    {
        $jsonFile = Storage::disk('local')->path($this->formData['name'].'/Data/pivot.geojson');
        $harvestFile = Storage::disk('local')->path($this->formData['name'].'/Data/harvest.xlsx');

       if (File::exists($harvestFile) && File::exists($jsonFile)) {
            $this->pivotNameAnalyser = new PivotNameAnalyser(
                $jsonFile, $harvestFile
            );
        }
        return view('livewire.projects.tabs.settings');
    }
}
