<?php

namespace App\Services\Meet\Calendar;

use App\Models\CalendarConnection;
use App\Models\Room;
use App\Models\User;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

class MailCalendarProvider
{
    public function createEvent(CalendarConnection $connection, Room $room, User $host): ?string
    {
        $mailbox = $connection->calendar_id ?? $host->email;
        if (! $mailbox) {
            return null;
        }

        return $this->createEventForMailbox($mailbox, $room);
    }

    public function createEventForMailbox(string $mailbox, Room $room): ?string
    {
        $response = Http::withToken((string) config('meet.calendar.mail.api_key'))
            ->acceptJson()
            ->timeout(10)
            ->post($this->baseUrl().'/calendar/events', $this->payload($mailbox, $room));

        if (! $response->successful()) {
            Log::warning('Mail calendar create failed', ['status' => $response->status(), 'body' => $response->body()]);

            return null;
        }

        return (string) ($response->json('data.id') ?? $response->json('id'));
    }

    public function updateEvent(CalendarConnection $connection, Room $room, User $host): bool
    {
        $mailbox = $connection->calendar_id ?? $host->email;

        return $mailbox ? $this->updateEventForMailbox($mailbox, $room) : false;
    }

    public function updateEventForMailbox(string $mailbox, Room $room): bool
    {
        if (! $room->calendar_event_id) {
            return false;
        }

        return Http::withToken((string) config('meet.calendar.mail.api_key'))
            ->acceptJson()
            ->timeout(10)
            ->put($this->baseUrl().'/calendar/events/'.$room->calendar_event_id, $this->payload($mailbox, $room))
            ->successful();
    }

    public function deleteEvent(CalendarConnection $connection, Room $room): bool
    {
        return $this->deleteEventForMailbox($connection->calendar_id, $room);
    }

    public function deleteEventForMailbox(?string $mailbox, Room $room): bool
    {
        if (! $room->calendar_event_id) {
            return false;
        }

        return Http::withToken((string) config('meet.calendar.mail.api_key'))
            ->acceptJson()
            ->timeout(10)
            ->delete($this->baseUrl().'/calendar/events/'.$room->calendar_event_id, array_filter([
                'mailbox_email' => $mailbox ? strtolower(trim($mailbox)) : null,
                'external_ref' => $room->uuid,
            ]))
            ->successful();
    }

    /**
     * @return array<string, mixed>
     */
    protected function payload(string $mailbox, Room $room): array
    {
        $starts = $room->scheduled_at ?? now();
        $duration = (int) ($room->duration_minutes ?? 60);

        return [
            'mailbox_email' => strtolower(trim($mailbox)),
            'external_ref' => $room->uuid,
            'title' => $room->title,
            'body' => $room->description,
            'starts_at' => $starts->toIso8601String(),
            'ends_at' => $starts->copy()->addMinutes($duration)->toIso8601String(),
            'join_url' => $room->joinUrl(),
        ];
    }

    protected function baseUrl(): string
    {
        return rtrim((string) config('meet.calendar.mail.api_url', 'https://mail.ladill.com/api/service/v1'), '/');
    }
}
