<?php

namespace App\Mail;

use App\Facades\Settings;
use App\Traits\LoadsDataFromSource;
use Illuminate\Bus\Queueable;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Address;
use Illuminate\Mail\Mailables\Attachment;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Storage;
use Mtc\ContentManager\Models\Page;
use Mtc\Crm\Contracts\EnquiryModel;
use App\Traits\GetsColourSettings;
use Mtc\Crm\Models\FormQuestion;
use Mtc\MercuryDataModels\Dealership;
use Mtc\MercuryDataModels\GlobalContent;
use Mtc\MercuryDataModels\NewCar;
use Mtc\MercuryDataModels\Vehicle;
use Mtc\MercuryDataModels\VehicleOffer;

class NewEnquiryMail extends Mailable
{
    use Queueable;
    use SerializesModels;
    use GetsColourSettings;
    use LoadsDataFromSource;

    private Collection $questions;

    /**
     * Create a new notification instance.
     *
     * @return void
     */
    public function __construct(
        public readonly EnquiryModel $enquiry,
    ) {

        $action = $this->enquiry->actions->where('action_name', 'send-copy-via-mail')->first();
        if ($action) {
            $this->enquiry->subject = $action->data['enquiry_subject'] ?? '';
            $this->enquiry->intro = $action->data['enquiry_content'] ?? '';
        }

        $this->enquiry->details = $this->enrichDetails();
    }

    public function envelope(): Envelope
    {
        return new Envelope(
            from: new Address(config('mail.from.address'), config('mail.from.name')),
            subject: !empty($this->enquiry->subject)
                ? $this->enquiry->subject
                : __('crm::enquiries.new-enquiry', ['title' => $this->enquiry->title]),
        );
    }

    public function content(): Content
    {
        return new Content(
            view: 'crm::emails.new-enquiry',
            with: [
                'site_name' => Settings::get('app-name'),
                'site_logo' => Settings::get('site-logo'),
                'site_logo_alternate' => Settings::get('site-alternate-logo'),
                'colours' => $this->getColourSettings(),
                'global' => GlobalContent::query()->where('slug', 'email-content')->first()?->content,
                'valuation_email_price_to_show' => Settings::get('valuation-email-price-to-show', 'all'),
            ]
        );
    }

    public function attachments(): array
    {
        return $this->enquiry->getNormalizedAnswers()
            ->filter(function ($answer) {
                $question = $this->getQuestions()->where('id', $answer['question_id'])->first();

                if ($question && $question->type == 'file_upload') {
                    if (is_array($answer['answer'])) {
                        foreach ($answer['answer'] as $file) {
                            if (Storage::disk('file-storage')->exists($file)) {
                                return true;
                            }
                        }
                    } else {
                        return !empty($answer['answer']) && Storage::disk('file-storage')->exists($answer['answer']);
                    }
                }
                return false;
            })
            ->filter(fn ($answer) => $this->getQuestions()
                ->where('id', $answer['question_id'])
                ->first()
                ?->type == 'file_upload')
            ->map(fn ($answer) => $answer['answer'])
            ->flatten()
            ->map(fn ($file) => Attachment::fromStorageDisk('file-storage', $file))
            ->values()
            ->toArray();
    }

    private function getQuestions(): Collection
    {
        if (empty($this->questions)) {
            $this->questions = FormQuestion::withTrashed()
                ->where('form_id', $this->enquiry->form_id)
                ->get();
        }

        return $this->questions;
    }

    private function enrichDetails()
    {
        return $this->enquiry->getNormalizedAnswers()
            ->map(function ($answer) {
                $question = $this->getQuestions()
                    ->where('id', $answer['question_id'])
                    ->first();

                $answer['type'] = $question?->type;

                $answer['value'] = match ($answer['type']) {
                    'dealership_id' => Dealership::query()->find($answer['answer'])?->name,
                    'vehicle_id' => Vehicle::query()->find($answer['answer'])?->title,
                    'offer_id' => VehicleOffer::query()->find($answer['answer'])?->name,
                    'new_car_id' => NewCar::query()->find($answer['answer'])?->name,
                    'page_id' => Page::query()->find($answer['answer'])?->title,
                    default => null,
                };

                if ($answer['value'] === null) {
                    $source = $question?->data['meta']['options']['source'] ?? null;
                    if ($source && is_numeric($answer['answer'])) {
                        $answer['value'] = $this->getChoicesFromDataSource($source)
                            ?->firstWhere('id', $answer['answer'])
                            ?->name ?? $answer['answer'];
                    }
                }

                return $answer;
            });
    }
}
