<?php

namespace App\Http\Controllers\Modules\BookingEngine;

use App\Http\Controllers\Controller;
use Carbon\Carbon;

use App\Models\Hotel\Room;

class IcalExportController extends Controller
{
  //* Constructor
    protected string $timezone;

    public function __construct()
    {
        $this->timezone = config('app.timezone');
    }

  //* Main Functions
    /**
     * Exporta la ocupación de una habitación en formato iCalendar (.ics).
     *
     * Este endpoint genera un calendario compatible con sistemas externos y otros motores
     * de sincronización que soportan el estándar iCal.
     *
     * @param string $token Token iCal único de la habitación.
     *
     * @return \Illuminate\Http\Response Archivo iCalendar (.ics) con la ocupación de la habitación.
    */
    public function roomIcalExport(string $token)
    {
      //* Control Data
        $room = Room::where('ical_token', $token)->firstOrFail();

        $reservations = $room->reservations()->where('show_in_calendar', true) // Avoid Cancelled Reserves
            ->where('status_id','!=',7)->get();

      //* Build File Content
        $ics = [];

        // Headers
        $ics[] = 'BEGIN:VCALENDAR';
        $ics[] = 'VERSION:2.0';
        $ics[] = 'PRODID:-//RS Harsi PMS//Calendar Sync//ES';
        $ics[] = 'CALSCALE:GREGORIAN';
        $ics[] = 'METHOD:PUBLISH';
        $ics[] = 'X-PUBLISHED-TTL:PT15M';
        $ics[] = "X-WR-CALNAME:RS Harsi - $room->room_name";
        $ics[] = "X-WR-TIMEZONE:{$this->timezone}";

        // Reservations
        foreach ($reservations as $reservation) {
          // Control Data
            $last_modified = $reservation->updated_at?->clone()->utc() ?? now()->utc();

          // Structure Record
            $ics[] = "BEGIN:VEVENT";

                $ics[] = "UID:rsv-".$reservation->id."-room-".$room->id."@rsharsi.com"; // Record ID

                $ics[] = 'CREATED:'.$reservation->created_at->clone()->utc()->format('Ymd\THis\Z');
                $ics[] = "DTSTAMP:{$last_modified->format('Ymd\THis\Z')}";
                $ics[] = "LAST-MODIFIED:{$last_modified->format('Ymd\THis\Z')}";
                $ics[] = 'SEQUENCE:'.$last_modified->timestamp;

                if ($reservation->is_express) { // Express Mode
                    $entryHour = $reservation->hour_entry ?? '00:00:00';
                    $departureHour = $reservation->hour_departure ?? '23:59:59';

                    $start = Carbon::parse($reservation->date_entry.' '.$entryHour, $this->timezone)->utc();
                    $end = Carbon::parse($reservation->date_departure.' '.$departureHour, $this->timezone)->utc();

                    $ics[] = 'DTSTART:'.$start->format('Ymd\THis\Z');
                    $ics[] = 'DTEND:'.$end->format('Ymd\THis\Z');

                } else { // Night Mode
                    $ics[] = 'DTSTART;VALUE=DATE:' . Carbon::parse($reservation->date_entry, $this->timezone)->format('Ymd');

                    $ics[] = 'DTEND;VALUE=DATE:' . Carbon::parse($reservation->date_departure, $this->timezone)->format('Ymd');
                }

                $ics[] = "SUMMARY:Reserved";
                $ics[] = "STATUS:CONFIRMED";
                $ics[] = "DESCRIPTION:Reservation #" . $reservation->id;
                $ics[] = "TRANSP:OPAQUE";

            $ics[] = "END:VEVENT";
        }

        // Footer
        $ics[] = 'END:VCALENDAR';

      //* Return File
        return response(
            implode("\r\n", $ics), 200,
            [
                'Content-Type' => 'text/calendar; charset=utf-8',
                'Content-Disposition' => 'inline; filename="harsi-room-'.$room->id.'.ics"',
                'Cache-Control' => 'no-cache, no-store, must-revalidate',
                'Pragma' => 'no-cache',
                'Expires' => '0',
            ]
        );
    }

    /**
     * Listamos todas las URL por las cuales el usuario o agentes externos,
     * podrán conocer la disponibilidad de las habitaciones del hotel.
    */
    public function listRoomIcalLinks() {
      //* Control Data
        $room_ical_tokens = Room::where('id', '!=', 1)
        ->select('id', 'room_name', 'ical_token')
        ->orderBy('roomType_id')->get()
        ->map(function ($room) {
            return [
                'id' => $room->id,
                'name' => $room->room_name,
                'ical_token' => $room->ical_token,
                'ical_link' => route(
                    'api.booking-engine.IcalExportRooms',
                    ['token' => $room->ical_token]
                ),
            ];
        });

        return response()->json($room_ical_tokens);
    }
}
