<?php
/**
 * Buyer class to get the buyer data.
 *
 * @since 1.4.0
 * @package EDD\Invoices\XML\Elements
 */

namespace EDD\Pro\Invoices\XML\Elements;

// Exit if accessed directly.
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore

/**
 * Buyer class.
 */
class Buyer extends Element {

	/**
	 * Get the data.
	 *
	 * @since 1.4.0
	 * @return array
	 */
	protected function get_data(): array {
		return array(
			'name'     => 'cac:AccountingCustomerParty',
			'children' => $this->get_buyer_data(),
		);
	}

	/**
	 * Get the buyer data.
	 *
	 * @since 1.4.0
	 * @return array
	 */
	private function get_buyer_data() {
		return array(
			array(
				'name'     => 'cac:Party',
				'children' => $this->get_party_data(),
			),
		);
	}

	/**
	 * Get the party data.
	 *
	 * @since 1.4.0
	 * @return array
	 */
	private function get_party_data() {
		$customer   = edd_get_customer( $this->order->customer_id );
		$vat_order  = \EDD\Pro\Taxes\VAT\Order::get( $this->order->id );
		$buyer_name = $this->get_buyer_name( $customer, $vat_order );

		$data = array(
			array(
				'name'     => 'cac:PartyName',
				'children' => array(
					array(
						'name'  => 'cbc:Name',
						'value' => $buyer_name,
					),
				),
			),
			array(
				'name'     => 'cac:PostalAddress',
				'children' => $this->get_address_data(),
			),
		);

		if ( $this->should_include_party_tax_scheme() ) {
			$data[] = array(
				'name'     => 'cac:PartyTaxScheme',
				'children' => array(
					array(
						'name'  => 'cbc:CompanyID',
						'value' => $this->get_buyer_vat_number( $vat_order ),
					),
					array(
						'name'     => 'cac:TaxScheme',
						'children' => array(
							array(
								'name'  => 'cbc:ID',
								'value' => 'VAT',
							),
						),
					),
				),
			);
		}

		$data[] = array(
			'name'     => 'cac:PartyLegalEntity',
			'children' => array(
				array(
					'name'  => 'cbc:RegistrationName',
					'value' => $buyer_name,
				),
			),
		);

		$data[] = array(
			'name'     => 'cac:Contact',
			'children' => array(
				array(
					'name'  => 'cbc:Name',
					'value' => $customer->name,
				),
				array(
					'name'  => 'cbc:ElectronicMail',
					'value' => $customer->email,
				),
			),
		);

		return $data;
	}

	/**
	 * Get the buyer's VAT number.
	 *
	 * Priority: invoice form override > VIES checkout data.
	 *
	 * @since 3.6.7
	 * @param \EDD\Pro\Taxes\VAT\Order $vat_order The VAT order object.
	 * @return string
	 */
	private function get_buyer_vat_number( $vat_order ): string {
		$invoice_vat = edd_invoices_get_custom_order_meta( $this->order, 'invoices_vat' );
		if ( ! empty( $invoice_vat ) ) {
			return $invoice_vat;
		}

		return ! empty( $vat_order->vat_number ) ? $vat_order->vat_number : '';
	}

	/**
	 * Get the buyer's name for PartyName and RegistrationName.
	 *
	 * Priority: invoice form / order company name > VIES company name > customer name.
	 *
	 * @since 3.6.7
	 * @param \EDD\Customers\Customer  $customer  The customer object.
	 * @param \EDD\Pro\Taxes\VAT\Order $vat_order The VAT order object.
	 * @return string
	 */
	private function get_buyer_name( $customer, $vat_order ): string {
		$company = edd_invoices_get_company( $this->order );
		if ( ! empty( $company ) ) {
			return $company;
		}

		if ( ! empty( $vat_order->name ) ) {
			return $vat_order->name;
		}

		return $customer->name;
	}

	/**
	 * Get the address data.
	 *
	 * @since 1.4.0
	 * @return array
	 */
	private function get_address_data() {
		$address = edd_invoices_get_order_address( $this->order );

		return array(
			array(
				'name'  => 'cbc:StreetName',
				'value' => $address['line1'],
			),
			array(
				'name'  => 'cbc:AdditionalStreetName',
				'value' => $address['line2'],
			),
			array(
				'name'  => 'cbc:CityName',
				'value' => $address['city'],
			),
			array(
				'name'  => 'cbc:PostalZone',
				'value' => $address['zip'],
			),
			array(
				'name'  => 'cbc:CountrySubentity',
				'value' => $address['state'],
			),
			array(
				'name'     => 'cac:Country',
				'children' => array(
					array(
						'name'  => 'cbc:IdentificationCode',
						'value' => $address['country'],
					),
				),
			),
		);
	}
}
