<?php
/**
 * Invoice controller.
 *
 * @since 1.0
 */

declare( strict_types=1 );
namespace FeData\FastEvents\RestAPI\Public\Download;

defined( 'ABSPATH' ) || exit;

use FeData\FastEvents\Utilities\PluginUtil;
use stdClass;
use TCPDF;

/**
 * Invoice class.
 */
class EventInvoice {

	private const FONTNAME = 'helvetica';

	/**
	 * PDF Class variable
	 *
	 * @since 1.0
	 * @var TCPDF
	 */
	private TCPDF $pdf;

	/**
	 * Info on the position of blocks in the invoice
	 *
	 * @since 1.0
	 * @var stdClass
	 */
	private stdClass $json;

	/**
	 * Currency string
	 *
	 * @since 1.0
	 * @var string
	 */
	private string $currency;


	/**
	 * Invoice constructor.
	 *
	 * @param string $sender_name     The name of the sender (SMTP Sender Name).
	 * @param string $currency_symbol The currency symbol.
	 * @param string $pdf_info        JSON string of PDF info on where to print the invoice blocks.
	 *
	 * @since 1.0
	 */
	public function __construct( string $sender_name, string $currency_symbol, string $pdf_info ) {
		// Get the PDF-template.
		$this->json = json_decode( $pdf_info );

		// Prepare the PDF.
		include_once ABSPATH . 'wp-admin/includes/file.php';
		$this->pdf = new EventPdf();
		// Set properties.
		$this->pdf->SetCreator( PluginUtil::get_user_agent() );
		$this->pdf->SetAuthor( $sender_name );
		$this->pdf->SetTitle( __( 'Invoice', 'fast-events' ) );
		$this->pdf->SetTextColor();
		$this->pdf->setFontSubsetting( false );

		// Set the currency.
		$this->currency = $currency_symbol;
	}


	/**
	 * Print the invoice
	 *
	 * @param stdClass $order Information on the order.
	 *
	 * @since 2.1.0 Use, if present, the invoice address data
	 * @since 2.2.0 Print coupons if available
	 *
	 * @since 1.0
	 */
	public function print_invoice( stdClass $order ): void {
		$tickets = json_decode( $order->input_fields );

		// Set subject.
		$this->pdf->SetSubject( __( 'Order', 'fast-events' ) . ' #' . $order->id );

		$this->pdf->AddPage();
		$this->pdf->load_template( (int) $this->json->invoice->id );
		$this->pdf->use_template();

		$this->pdf->SetTextColor();
		$this->pdf->SetFont( self::FONTNAME, '', 11 );
		$this->pdf->SetXY( $this->json->invoice->name->x, $this->json->invoice->name->y );

		if ( isset( $tickets->invoice->locked ) ) {
			// Print invoice data.
			$this->pdf->Write( 5, $tickets->invoice->company );
			$this->pdf->SetXY( $this->json->invoice->name->x, $this->json->invoice->name->y + 5 );
			$this->pdf->Write( 5, $tickets->invoice->name );
			$this->pdf->SetXY( $this->json->invoice->name->x, $this->json->invoice->name->y + 10 );
			$this->pdf->Write( 5, $tickets->invoice->street );
			$this->pdf->SetXY( $this->json->invoice->name->x, $this->json->invoice->name->y + 15 );
			$this->pdf->Write( 5, $tickets->invoice->postcode );
			$this->pdf->Write( 5, '  ' . $tickets->invoice->city );
		} else {
			// Print name and email.
			$this->pdf->Write( 5, $order->name );
			$this->pdf->SetXY( $this->json->invoice->name->x, $this->json->invoice->name->y + 10 );
			$this->pdf->Write( 5, $order->email );
		}

		// Orderno, invoiceno and date.
		$this->pdf->SetXY( $this->json->invoice->invoiceno->x, $this->json->invoice->invoiceno->y );
		$this->pdf->Write( 5, __( 'Orderno.', 'fast-events' ) );
		$this->pdf->SetXY( $this->json->invoice->invoiceno->x + 25, $this->json->invoice->invoiceno->y );
		$this->pdf->Cell( 30, 5, $order->id, 0, 0, 'R' );
		$this->pdf->SetXY( $this->json->invoice->invoiceno->x, $this->json->invoice->invoiceno->y + 5 );
		$this->pdf->Write( 5, __( 'Invoiceno.', 'fast-events' ) );
		$this->pdf->SetXY( $this->json->invoice->invoiceno->x + 25, $this->json->invoice->invoiceno->y + 5 );
		$this->pdf->Cell( 30, 5, wp_date( 'Y' ) . '-' . sprintf( '%06d', $order->id ), 0, 0, 'R' );
		$this->pdf->SetXY( $this->json->invoice->invoiceno->x, $this->json->invoice->invoiceno->y + 10 );
		$this->pdf->Write( 5, __( 'Date', 'fast-events' ) );
		$this->pdf->SetXY( $this->json->invoice->invoiceno->x + 25, $this->json->invoice->invoiceno->y + 10 );
		$this->pdf->Cell( 30, 5, mysql2date( 'd-m-Y', $order->created_at ), 0, 0, 'R' );

		// Order-items headerline.
		$this->pdf->SetFillColor( 200, 200, 200 );
		$this->pdf->SetXY( $this->json->invoice->line->x, $this->json->invoice->line->y );
		$this->pdf->Cell( $this->json->invoice->line->w, 5, __( 'Description', 'fast-events' ), 0, 0, '', true );
		$this->pdf->SetXY( $this->json->invoice->line->x + ( $this->json->invoice->line->w * 0.5 ), $this->json->invoice->line->y );
		$this->pdf->Cell( 20, 5, __( 'Qty', 'fast-events' ), 0, 0, 'R', true );
		if ( $this->json->invoice->vat ) { // Only print VAT if the event allows it.
			$this->pdf->SetXY( $this->json->invoice->line->x + ( $this->json->invoice->line->w * 0.7 ), $this->json->invoice->line->y );
			$this->pdf->Cell( 20, 5, __( 'VAT', 'fast-events' ), 0, 0, 'R', true );
		}
		$this->pdf->SetXY( $this->json->invoice->line->x + $this->json->invoice->line->w - 25, $this->json->invoice->line->y );
		$this->pdf->Cell( 25, 5, __( 'Amount', 'fast-events' ), 0, 0, 'R', true );
		$this->pdf->SetFillColor( 255, 255, 255 );

		// Walk through the order lines.
		$line_x   = $this->json->invoice->line->x;
		$line_y   = $this->json->invoice->line->y;
		$width    = $this->json->invoice->line->w;
		$increase = 7;
		if ( ! empty( $tickets->tickets ) ) {
			foreach ( $tickets->tickets as $ticket ) {

				// Don't print order lines with 0 tickets.
				if ( 0 === (int) $ticket->count ) {
					continue;
				}

				$this->pdf->SetTextColor();
				$this->pdf->SetFont( self::FONTNAME, '', 11 );
				$this->pdf->SetXY( $line_x, $line_y + $increase );
				$this->pdf->Write( 5, $ticket->name );
				$this->pdf->SetXY( $line_x + ( $width * 0.5 ), $line_y + $increase );
				$this->pdf->Cell( 20, 5, $ticket->count, 0, 0, 'R' );
				if ( $this->json->invoice->vat ) { // Only print VAT if the event allows it.
					$this->pdf->SetXY( $line_x + ( $width * 0.7 ), $line_y + $increase );
					$this->pdf->Cell( 20, 5, number_format_i18n( (float) $ticket->vat, 2 ) . '%', 0, 0, 'R' );
				}

				// Calculate the amount and VAT.
				$amount = (int) $ticket->count * (float) $ticket->price;

				// Print the amount for this order line.
				$this->pdf->SetXY( $line_x + $width - 25, $line_y + $increase );
				$this->pdf->Cell( 25, 5, $this->currency . ' ' . number_format_i18n( $amount, 2 ), 0, 0, 'R' );

				// Print event-name and date.
				$this->pdf->SetTextColor( 64 );
				$this->pdf->SetFont( self::FONTNAME, '', 8 );
				$increase += 3;
				$this->pdf->SetXY( $line_x, $line_y + $increase );
				$this->pdf->Write( 5, $order->event_name );
				$increase += 3;
				$this->pdf->SetXY( $line_x, $line_y + $increase );
				$this->pdf->Write( 5, mysql2date( $order->event_date_format, $order->event_date ) );

				$increase += 6;
			}
		}

		// Are there any discounts?
		if ( ! empty( $tickets->discounts ) ) {
			foreach ( $tickets->discounts as $discount ) {
				$this->pdf->SetTextColor();
				$this->pdf->SetFont( self::FONTNAME, '', 11 );
				$this->pdf->SetXY( $line_x, $line_y + $increase );
				/* translators: 1: is the coupon code */
				$this->pdf->Write( 5, sprintf( esc_html__( 'Coupon (%1$s)', 'fast-events' ), $discount->code ) );
				$this->pdf->SetXY( $line_x + $width - 25, $line_y + $increase );
				$this->pdf->Cell( 25, 5, $this->currency . ' -' . number_format_i18n( (float) $discount->amount, 2 ), 0, 0, 'R' );
				$increase += 6;
			}
		}

		// Print the VAT totals if there is VAT.
		$this->pdf->SetTextColor();
		$this->pdf->SetFont( self::FONTNAME, '', 11 );
		if ( 0.0000 !== (float) $tickets->order_vat ) {
			if ( $this->json->invoice->vat ) {  // Only print VAT if the event allows it.
				$increase += 7;
				$this->pdf->SetXY( $line_x + ( $width * 0.7 ), $line_y + $increase );
				$this->pdf->Cell( 20, 5, __( 'Total VAT', 'fast-events' ), 0, 0, 'R' );
				$this->pdf->SetXY( $line_x + $width - 25, $line_y + $increase );
				$this->pdf->Cell( 25, 5, $this->currency . ' ' . number_format_i18n( (float) $tickets->order_vat, 2 ), 0, 0, 'R' );
			}
		}

		// Print totals.
		$increase += 7;
		$this->pdf->SetLineWidth( 0.7 );
		$this->pdf->Line( $line_x + $width - 25, $line_y + $increase, $line_x + $width, $line_y + $increase );
		$increase += 3;
		$this->pdf->SetXY( $line_x + ( $width * 0.7 ), $line_y + $increase );
		$this->pdf->Cell( 20, 5, __( 'Total', 'fast-events' ), 0, 0, 'R' );
		$this->pdf->SetXY( $line_x + $width - 25, $line_y + $increase );
		$this->pdf->Cell( 25, 5, $this->currency . ' ' . number_format_i18n( (float) $tickets->order_amount, 2 ), 0, 0, 'R' );
	}


	/**
	 * Send the invoice back to the client.
	 *
	 * @since 1.0
	 */
	public function send_pdf(): void {
		$this->pdf->Output( __( 'Invoice', 'fast-events' ) . '.pdf' );
	}
}
