<?php

namespace App\Livewire\Projects;

use App\Models\Project;
use App\Models\ProjectEmailRecipient;
use App\Rules\HarvestFile;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
use Illuminate\Validation\Rule;
use Livewire\Component;
use Livewire\WithFileUploads;

class ProjectManager extends Component
{
    use WithFileUploads;

    public $formData = [];

    public $processOutput = '';

    public $confirmingReportDeletion = false;

    public $showProjectModal = false;

    public $showMailSettingsModal = false;

    public $reportIdBeingDeleted = null;

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

    /**
     * Mount the component.
     *
     * @return void
     */
    public function mount()
    {
        $this->resetFormData();
    }


    public function editProject(Project $project)
    {
        $this->showProjectModal = true;
        $this->loadFormData($project);
    }

    public function editMailSettings(Project $project)
    {
        $this->showMailSettingsModal = true;
        $this->loadFormData($project);
    }

    private function loadFormData(Project $project)
    {
        $this->formData = $project->toArray();
        $this->formData['mail_recipients'] = $project->emailRecipients->toArray() ?: [
            [
                'name' => '',
                'email' => '',
            ]
        ];
    }

    public function openCreateProjectModal()
    {
        $this->resetFormData();
        $this->showProjectModal = true;
    }

    public function createProject()
    {
        $projectIdentifier = $this->formData['id'] ?? null;
        Validator::make(
            [
                'name' => $this->formData['name']
            ],
            [
                'name' => [
                    'required',
                    Rule::unique('projects')->ignore($projectIdentifier),
                    'string',
                    'max:255'
                ]
            ])->validate();
        $project = Project::create([
            'name' => $this->formData['name'],
            'download_path' => $this->makeValidDirectoryName($this->formData['name'])
        ]);
        return redirect()->route('project.show',[$project->name,'settings']);
    }

    private function makeValidDirectoryName($string)
    {
        return Str::of($string)
            ->replaceMatches('/[^a-zA-Z0-9_-]/', '_')  // Replace invalid characters
            ->trim()  // Remove leading/trailing spaces
            ->lower();  // Convert to lowercase
    }

    public function saveProject()
    {
        $this->resetErrorBag();
        $this->mergeFormData();
        $this->validateForm();
        Project::saveWithFormData($this->formData);
        $this->resetFormData();
        $this->showProjectModal = false;
        $this->dispatch('saved');
    }

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

    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():void
    {
        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();
    }

    public function render()
    {
        return view('livewire.project-manager');
    }

    private function resetFormData()
    {
        $this->formData = [
            'name' => '',
            'borders' => false,
            '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;

        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'],
            'borders' => $this->formData['borders'],
        ], [
            'name' => [
                'required',
                Rule::unique('projects')->ignore($projectIdentifier),
                'string',
                'max:255'
            ],
            'pivot_file.extension' => ['sometimes', function ($attribute, $value, $fail) {
                if ($value && $value != 'json') {
                    $fail('Not a json file');
                }
            }],
            'span_file.extension' => ['sometimes', function ($attribute, $value, $fail) {
                if ($value && $value != 'json') {
                    $fail('Not a json file');
                }
            }],
            'harvest_file' => ['sometimes', new HarvestFile],
            'borders' => ['required', 'boolean'],
        ])->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'],
            'borders' => $this->formData['borders'],
        ], [
            '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'],
            'borders' => ['required', 'boolean'],
        ])->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;
        $this->formData['download_path'] = $this->formData['download_path'] ?? $this->formData['name'];
    }


}
