<?php

namespace WPDesk\FakturyKSEF\Api\Exceptions;

use Exception;
use Throwable;

class KSeFAPIException extends Exception {

	private array $api_response;

	private string $custom_message;

	public function __construct( array $api_response, int $code = 0, ?Throwable $previous = null, string $custom_message = '' ) {
		$this->api_response   = $api_response;
		$this->custom_message = $custom_message;

		$message = $this->generate_string_message();

		parent::__construct( $message, $code, $previous );
	}

	public function get_structured_errors(): array {
		$errors = [];

		$list = $this->api_response['exception']['exceptionDetailList'] ?? null;

		if ( is_array( $list ) && ! empty( $list ) ) {
			foreach ( $list as $item ) {
				$code           = (string) ( $item['exceptionCode'] ?? '' );
				$desc           = trim( (string) ( $item['exceptionDescription'] ?? '' ) );
				$details_string = $this->parse_details_field( $item['details'] ?? null );

				$errors[] = [
					'code'         => $code,
					'description'  => $desc,
					'details'      => $details_string,
					'full_message' => $this->format_single_line( $code, $desc, $details_string ),
				];
			}
		} else {
			$desc = $this->get_error_message_from_api_response();

			$errors[] = [
				'code'         => '',
				'description'  => $desc,
				'details'      => '',
				'full_message' => $desc,
			];
		}

		return $errors;
	}
	private function get_error_message_from_api_response(): string {
		if ( $this->custom_message !== '' ) {
			return $this->custom_message;
		}

		return $this->api_response['exception']['exceptionDescription']
			?? $this->api_response['message']
			?? $this->api_response['detail']
			?? __( 'An unknown error occured.', 'ksef-for-flexible-invoices' );
	}

	private function parse_details_field( $details_raw ): string {
		if ( is_array( $details_raw ) ) {
			$trimmed_array = array_map( 'trim', $details_raw );

			$filtered_array = array_filter(
				$trimmed_array,
				static fn( string $value ): bool => $value !== ''
			);

			return implode( '; ', $filtered_array );
		}

		return trim( (string) $details_raw );
	}

	private function format_single_line( string $code, string $desc, string $details ): string {
		$parts = [];
		if ( $code !== '' ) {
			$parts[] = "[{$code}]";
		}
		if ( $desc !== '' ) {
			$parts[] = $desc;
		} else {
			$parts[] = __( 'Error', 'ksef-for-flexible-invoices' );
		}
		if ( $details !== '' ) {
			$parts[] = "- {$details}";
		}

		return implode( ' ', $parts );
	}

	private function generate_string_message(): string {
		$errors = $this->get_structured_errors();
		$lines  = array_column( $errors, 'full_message' );

		return implode( "\n", $lines );
	}
}
