<?php

namespace App\Http\Resources;

use App\Mail\NewReservationCustomerCopyNotification;
use App\Traits\IconForType;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Str;
use Mtc\Crm\Facades\EnquiryData;
use Mtc\Crm\Http\Resources\FormViewResource as BaseFormViewResource;
use Mtc\Crm\Contracts\FormQuestionModel as FormQuestion;
use Mtc\Crm\Contracts\FormSectionModel as FormSection;
use Mtc\Crm\Models\EnquiryStatus;
use Mtc\Crm\Models\EnquiryType;
use Mtc\MercuryDataModels\Enquiry;
use Mtc\MercuryDataModels\Vehicle;
use Mtc\MercuryDataModels\VehicleValuation;
use Mtc\VehicleReservations\Reservation;
use Ramsey\Uuid\Uuid;

class FormViewResource extends BaseFormViewResource
{
    use IconForType;

    public static $wrap = '';

    /**
     * Transform the resource into an array.
     *
     * @param Request $request
     * @return array
     */
    public function toArray($request)
    {
        $this->resource->available_actions = $this->getAvailableActions();
        $this->resource->load([
            'sections.questions',
        ]);

        $this->setActions();

        $resource = $this->resource->toArray();
        $resource['sections'] = $this->setSections();
        $resource['multistep'] = $resource['data']['multistep'] ?? false;
        $resource['preview_content'] = $this->getTemplateContent();

        return [
            'form' => $resource,
            'types' => EnquiryType::query()->orderBy('name')->get(),
            'statuses' => EnquiryStatus::query()->orderBy('name')->get(),
        ];
    }

    /**
     * Get list of available actions on forms
     *
     * @return Collection
     */
    protected function getAvailableActions()
    {
        return collect(config('crm.form_actions'))
            ->filter(fn($class) => App::make($class)->enabled())
            ->map(fn($class, $key) => [
                'name' => Str::title(str_replace('-', ' ', $key)),
                'enabled' => false,
                'question_fields' => collect(App::make($class)->formQuestionDataFields() ?? []),
                'fields' => collect(App::make($class)->formAdditionalDataFields() ?? [])
                    ->map(function ($field) {
                        $field['value'] = null;
                        return $field;
                    }),
            ]);
    }

    private function setActions()
    {
        $actions = $this->resource->available_actions->toArray();
        $enabledActions = $this->resource->actions()
            ->get()
            ->keyBy('action_name');

        foreach ($actions as $id => $availableAction) {
            if (isset($enabledActions[$id])) {
                $actions[$id]['enabled'] = true;
                $actions[$id]['fields'] = collect($actions[$id]['fields'])
                    ->map(function ($field, $fieldName) use ($id, $enabledActions) {
                        $field['value'] = $enabledActions[$id]['fields'][$fieldName] ?? null;
                        return $field;
                    });
            }
        }

        $this->resource->action_data = $actions;
    }

    private function setSections()
    {
        return $this->resource
            ->sections
            ->map(fn(FormSection $section) => [
                'id' => $section->id,
                'name' => $section->name,
                'is_active' => $section->is_active,
                'settings' => $section->settings,
                'sections' => collect($section->segments ?? [])
                    ->map(fn($segment) => [
                        'id' => Uuid::uuid4(),
                        'name' => $segment,
                        'questions' => $section->questions
                            ->where('segment', $segment)
                            ->map(fn(FormQuestion $question) => [
                                'id' => $question->id,
                                'name' => $question->name,
                                'cssId' => $question->data['cssId'] ?? null,
                                'cssClass' => $question->data['cssClass'] ?? null,
                                'fieldId' => $question->type,
                                'component' => $question->data['component'] ?? null,
                                'componentName' => $question->data['componentName'] ?? null,
                                'optionsMenuVisible' => false,
                                'meta' => $question->data['meta'] ?? null,
                                'type' => $question->type,
                                'is_active' => $question->is_active,
                                'validation' => is_array($question->validation)
                                    ? $question->validation
                                    : json_decode($question->validation, true),
                                'is_customers_email' => $question->is_customers_email,
                                'is_enquiry_subject' => $question->is_enquiry_subject,
                                'description' => $question->description,
                                'placeholder' => $question->placeholder,
                                'data' => $question->data ?? [],
                                'editable' => true,
                                'error' => $this->questionError($question),
                                'icon' => $this->getIcon($question->type),
                            ])->values(),
                    ])
            ]);
    }


    private function questionError(FormQuestion $question)
    {
        return match ($question->type) {
            'offer_id', 'page_id', 'vehicle_id' => ['This field is hidden, auto-filled by the value of viewed page'],
            default => [],
        };
    }

    private function getTemplateContent(): string
    {
        if ($this->resource?->type?->name === 'Reservation') {
            $reservation = Reservation::factory()->make();
            return (new NewReservationCustomerCopyNotification($reservation))->render();
        }

        $enquiry = Enquiry::query()
            ->where('form_id', $this->resource->id)->first();
        if (empty($enquiry)) {
            $enquiry = Enquiry::factory()->make([
                'form_id' => $this->resource->id,
            ]);
            $valuation = VehicleValuation::factory()->make();
            $enquiry->valuation = $valuation;
        }

        if (empty($enquiry->reason)) {
            $vehicle = Vehicle::query()->first();
            $enquiry->reason = $vehicle;
        }

        $class = config('crm.enquiry_confirmation_mail');
        return (new $class($enquiry))->render();
    }
}
