<?php

namespace Bookaro\Entity;

defined( 'ABSPATH' ) || exit;

class Booking
{
    private ?int $id = null;
    private int $listing_id = 0;
    private int $service_id = 0;
    private string $service_label = '';
    private float $price = 0.0;
    private int $customer_id = 0;
    private string $customer_phone = '';
    private int $provider_id = 0;
    private int $staff_id = 0;
    private string $booking_date = '';
    private ?string $booking_date_to = null;
    private ?int $order_id = null;
    private string $status = '';
    private ?string $notes = null;
    private ?string $cancel_reason = null;
    private string $created_at = '';
    private string $updated_at = '';
    /** Pro-only (populated via Pro meta/hooks). */
    private ?string $google_event_id = null;
    /** Pro-only (populated via Pro meta/hooks). */
    private bool $google_synced = false;
    /** Pro-only (populated via Pro meta/hooks). */
    private ?string $sms_message_sid = null;
    /** Pro-only (populated via Pro meta/hooks). */
    private ?string $sms_message_status = null;
    /** Pro-only (populated via Pro meta/hooks). */
    private ?string $sms_message_updated_at = null;

    public function __get(string $name)
    {
        return $this->$name ?? null;
    }

    public function __isset(string $name): bool
    {
        return property_exists($this, $name) && $this->$name !== null;
    }

    public static function fromArray(array $data): self
    {
        $self = new self();
        $self->id               = isset($data['id']) ? (int)$data['id'] : null;
        $self->listing_id       = (int)($data['listing_id'] ?? 0);
        $self->service_id       = (int)($data['service_id'] ?? 0);
        $self->service_label    = $data['service_label'] ?? '';
        $self->price            = isset($data['price']) ? (float)$data['price'] : 0.0;
        $self->customer_id     = (int)($data['customer_id'] ?? 0);
        $self->customer_phone  = $data['customer_phone'] ?? '';
        $self->provider_id      = (int)($data['provider_id'] ?? 0);
        $self->staff_id         = (int)($data['staff_id'] ?? 0);
        $self->booking_date     = $data['booking_date'] ?? '';
        $self->booking_date_to  = $data['booking_date_to'] ?? null;
        $self->order_id         = isset($data['order_id']) ? (int)$data['order_id'] : null;
        $self->status           = $data['status'] ?? '';
        $self->notes            = $data['notes'] ?? null;
        $self->cancel_reason    = $data['cancel_reason'] ?? null;
        $self->created_at       = $data['created_at'] ?? '';
        $self->updated_at       = $data['updated_at'] ?? '';
        $self->google_event_id  = $data['google_event_id'] ?? null;
        if (isset($data['google_synced'])) {
            $self->google_synced = (bool)$data['google_synced'];
        }
        $self->sms_message_sid       = $data['sms_message_sid'] ?? null;
        $self->sms_message_status    = $data['sms_message_status'] ?? null;
        $self->sms_message_updated_at = $data['sms_message_updated_at'] ?? null;

        return $self;
    }

    public static function fromWpdbRow(\stdClass $row): self
    {
        return self::fromArray((array)$row);
    }

    public function toArray(): array
    {
        return [
            'id'               => $this->id,
            'listing_id'       => $this->listing_id,
            'service_id'       => $this->service_id,
            'service_label'    => $this->service_label,
            'price'            => $this->price,
            'customer_id'     => $this->customer_id,
            'customer_phone'  => $this->customer_phone,
            'provider_id'      => $this->provider_id,
            'booking_date'     => $this->booking_date,
            'booking_date_to'  => $this->booking_date_to,
            'order_id'         => $this->order_id,
            'status'           => $this->status,
            'notes'            => $this->notes,
            'cancel_reason'    => $this->cancel_reason,
            'created_at'       => $this->created_at,
            'updated_at'       => $this->updated_at,
            'google_event_id'  => $this->google_event_id,
            'google_synced'    => $this->google_synced ? 1 : 0,
            'sms_message_sid'  => $this->sms_message_sid,
            'sms_message_status' => $this->sms_message_status,
            'sms_message_updated_at' => $this->sms_message_updated_at,
        ];
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    public function setId(?int $id): void
    {
        $this->id = $id;
    }

    public function getListingId(): int
    {
        return $this->listing_id;
    }

    public function setListingId(int $listing_id): void
    {
        $this->listing_id = $listing_id;
    }

    public function getServiceId(): int
    {
        return $this->service_id;
    }

    public function setServiceId(int $service_id): void
    {
        $this->service_id = $service_id;
    }

    public function getServiceLabel(): string
    {
        return $this->service_label;
    }

    public function setServiceLabel(string $service_label): void
    {
        $this->service_label = $service_label;
    }

    public function getPrice(): float
    {
        return $this->price;
    }

    public function setPrice(float $price): void
    {
        $this->price = $price;
    }

    public function getCustomerId(): int
    {
        return $this->customer_id;
    }

    public function setCustomerId(int $customer_id): void
    {
        $this->customer_id = $customer_id;
    }

    public function getCustomerPhone(): string
    {
        return $this->customer_phone;
    }

    public function setCustomerPhone(string $customer_phone): void
    {
        $this->customer_phone = $customer_phone;
    }

    public function getProviderId(): int
    {
        return $this->provider_id;
    }

    public function setProviderId(int $provider_id): void
    {
        $this->provider_id = $provider_id;
    }

    public function getStaffId(): int
    {
        return $this->staff_id;
    }

    public function setStaffId(int $staff_id): void
    {
        $this->staff_id = $staff_id;
    }

    public function getBookingDate(): string
    {
        return $this->booking_date;
    }

    public function setBookingDate(string $booking_date): void
    {
        $this->booking_date = $booking_date;
    }

    public function getBookingDateTo(): ?string
    {
        return $this->booking_date_to;
    }

    public function setBookingDateTo(?string $booking_date_to): void
    {
        $this->booking_date_to = $booking_date_to;
    }

    public function getOrderId(): ?int
    {
        return $this->order_id;
    }

    public function setOrderId(?int $order_id): void
    {
        $this->order_id = $order_id;
    }

    public function getStatus(): string
    {
        return $this->status;
    }

    public function setStatus(string $status): void
    {
        $this->status = $status;
    }

    public function getNotes(): ?string
    {
        return $this->notes;
    }

    public function setNotes(?string $notes): void
    {
        $this->notes = $notes;
    }

    public function getCancelReason(): ?string
    {
        return $this->cancel_reason;
    }

    public function setCancelReason(?string $cancel_reason): void
    {
        $this->cancel_reason = $cancel_reason;
    }

    public function getCreatedAt(): string
    {
        return $this->created_at;
    }

    public function setCreatedAt(string $created_at): void
    {
        $this->created_at = $created_at;
    }

    public function getUpdatedAt(): string
    {
        return $this->updated_at;
    }

    public function setUpdatedAt(string $updated_at): void
    {
        $this->updated_at = $updated_at;
    }

    public function getGoogleEventId(): ?string
    {
        return $this->google_event_id;
    }

    public function setGoogleEventId(?string $google_event_id): void
    {
        $this->google_event_id = $google_event_id;
    }

    public function isGoogleSynced(): bool
    {
        return $this->google_synced;
    }

    public function setGoogleSynced(bool $google_synced): void
    {
        $this->google_synced = $google_synced;
    }
}
