<?php

namespace SugarCalendarBookings\Payments;

use DateTimeImmutable;
use SugarCalendarBookings\Appointments\AppointmentModel;
use SugarCalendarBookings\Customers\CustomerModel;
use SugarCalendarBookings\Support\Database\AbstractModel;
use SugarCalendarBookings\Support\Database\Relations\BelongsToManyRelation;
use SugarCalendarBookings\Support\Database\Relations\BelongsToRelation;

/**
 * Payment model.
 *
 * @since 1.0.0
 *
 * @property int                    $id
 * @property int                    $customer_id
 * @property string                 $status
 * @property float                  $subtotal_amount
 * @property float                  $total_amount
 * @property string                 $currency
 * @property string                 $gateway
 * @property string                 $mode
 * @property string                 $transaction_id
 * @property DateTimeImmutable      $created_at
 * @property DateTimeImmutable      $updated_at
 * @property null|DateTimeImmutable $trashed_at
 */
class PaymentModel extends AbstractModel {

	/**
	 * Pending status.
	 *
	 * @since 1.0.0
	 *
	 * @var string
	 */
	const STATUS_PENDING = 'pending';

	/**
	 * Completed status.
	 *
	 * @since 1.0.0
	 *
	 * @var string
	 */
	const STATUS_COMPLETED = 'completed';

	/**
	 * Failed status.
	 *
	 * @since 1.0.0
	 *
	 * @var string
	 */
	const STATUS_FAILED = 'failed';

	/**
	 * Refunded status.
	 *
	 * @since 1.0.0
	 *
	 * @var string
	 */
	const STATUS_REFUNDED = 'refunded';

	/**
	 * The database table name without prefix.
	 *
	 * @since 1.0.0
	 *
	 * @var string
	 */
	protected static $table_name = 'payments';

	/**
	 * The model type identifier.
	 *
	 * @since 1.0.0
	 *
	 * @var string
	 */
	protected static $type = 'payment';

	/**
	 * Column formats for the model.
	 *
	 * @since 1.0.0
	 *
	 * @var array<string, string>
	 */
	protected static $column_formats = [
		'id'              => '%d',
		'customer_id'     => '%d',
		'status'          => '%s',
		'subtotal_amount' => '%f',
		'total_amount'    => '%f',
		'currency'        => '%s',
		'gateway'         => '%s',
		'mode'            => '%s',
		'tracking_id'     => '%s',
		'transaction_id'  => '%s',
		'created_at'      => '%s',
		'updated_at'      => '%s',
		'trashed_at'      => '%s',
	];

	/**
	 * The attributes and meta that should be cast.
	 *
	 * @since 1.0.0
	 *
	 * @var array<string, string>
	 */
	protected static $casts = [
		'id'              => 'integer',
		'customer_id'     => 'integer',
		'subtotal_amount' => 'float',
		'total_amount'    => 'float',
		'created_at'      => 'datetime',
		'updated_at'      => 'datetime',
		'trashed_at'      => 'datetime',
	];

	/**
	 * Column defaults for the model.
	 *
	 * @since 1.0.0
	 *
	 * @return array<string, mixed>
	 */
	protected static function column_defaults() {

		return [
			'status'          => 'pending',
			'subtotal_amount' => 0,
			'total_amount'    => 0,
			'mode'            => 'live',
		];
	}

	/**
	 * Get the customer of the payment.
	 *
	 * @since 1.0.0
	 *
	 * @return BelongsToRelation
	 */
	public function customer() {

		return $this->belongs_to( CustomerModel::class );
	}

	/**
	 * Get the appointment for the payment.
	 *
	 * @since 1.0.0
	 *
	 * @return BelongsToManyRelation
	 */
	public function appointments() {

		// TODO: make this polymorphic.
		return $this->belongs_to_many( AppointmentModel::class, 'payment_items', 'payment_id', 'item_id' );
	}

	/**
	 * Get the status label.
	 *
	 * @since 1.0.0
	 *
	 * @return string
	 */
	public function get_status_label() {

		$label = '';

		switch ( $this->status ) {
			case self::STATUS_PENDING:
				$label = esc_html__( 'Pending', 'sugar-calendar-bookings-scheduling-appointments-lite' );
				break;

			case self::STATUS_COMPLETED:
				$label = esc_html__( 'Completed', 'sugar-calendar-bookings-scheduling-appointments-lite' );
				break;

			case self::STATUS_FAILED:
				$label = esc_html__( 'Failed', 'sugar-calendar-bookings-scheduling-appointments-lite' );
				break;

			case self::STATUS_REFUNDED:
				$label = esc_html__( 'Refunded', 'sugar-calendar-bookings-scheduling-appointments-lite' );
				break;
		}

		return $label;
	}
}
