<?php

namespace WPML\MediaTranslation;

use SitePress;
use WPML_Element_Translation_Package;
use WPML_TM_Translation_Batch;
use WPML_Post_Element;
use WPML\MediaTranslation\MediaField;

class MediaTranslationStatus implements \IWPML_Action {

	const NOT_TRANSLATED = 'media-not-translated';
	const IN_PROGRESS = 'in-progress';
	const TRANSLATED = 'media-translated';
	const NEEDS_MEDIA_TRANSLATION = 'needs-media-translation';

	const STATUS_PREFIX = '_translation_status_';

	/**
	 * @var SitePress
	 */
	private $sitepress;
	
	/**
	 * @var MediaField
	 */
	private $media_field;

	public function __construct( SitePress $sitepress ) {
		$this->sitepress = $sitepress;
		$this->media_field = new MediaField();
	}

	public function add_hooks() {
		add_action( 'wpml_tm_send_post_jobs', array( $this, 'set_translation_status_in_progress' ) );
		add_action( 'wpml_pro_translation_completed', array( $this, 'save_bundled_media_translation' ), 10, 3 );
	}

	public function set_translation_status_in_progress( WPML_TM_Translation_Batch $batch ) {
		foreach ( $batch->get_elements() as $item ) {
			foreach ( $item->get_media_to_translations() as $attachment_id ) {
				foreach ( array_keys( $item->get_target_langs() ) as $lang ) {
					$this->set_status( $attachment_id, $lang, self::IN_PROGRESS );
				}
			}
		}
	}

	private function set_status( $attachment_id, $language, $status ) {
		update_post_meta( $attachment_id, self::STATUS_PREFIX . $language, $status );
	}

	public function save_bundled_media_translation( $new_post_id, $fields, $job ) {

		$media_translations  = $this->get_media_translations( $job );
		$translation_package = new WPML_Element_Translation_Package();

		foreach ( $media_translations as $attachment_id => $translation_data ) {
			$attachment_translation_id = $this->save_attachment_translation(
				$attachment_id,
				$translation_data,
				$translation_package,
				$job->language_code
			);

			if ( $this->should_translate_media_image( $job, $attachment_id ) ) {
				$this->set_status( $attachment_id, $job->language_code, self::NEEDS_MEDIA_TRANSLATION );
			}
		}

	}

	private function should_translate_media_image( $job, $attachment_id ) {
		foreach ( $job->elements as $element ) {
			if ( 'should_translate_media_image_' . $attachment_id === $element->field_type && $element->field_data ) {
				return true;
			}
		}

		return false;
	}

	private function get_media_translations( $job ) {
		$media = array();

		foreach ( $job->elements as $element ) {
			$result = $this->media_field->extractAttachmentIdAndMediaFields( $element->field_type );
			if ( $result ) {
				$attachment_id = $result['attachment_id'];
				$media_field = $result['media_field'];
				$media[ $attachment_id ][ $media_field ] = $element;
			}
		}

		return $media;
	}

	/**
	 * @param int $attachment_id
	 * @param array $translation_data
	 * @param WPML_Element_Translation_Package $translation_package
	 * @param string $language
	 *
	 * @return bool|int|WP_Error
	 */
	private function save_attachment_translation( $attachment_id, $translation_data, $translation_package, $language ) {
		$postarr             = [];
		$alt_text            = null;
		$media_custom_fields = [];

		$post_element              = new WPML_Post_Element( $attachment_id, $this->sitepress );
		$attachment_translation    = $post_element->get_translation( $language );
		$attachment_translation_id = null !== $attachment_translation ? $attachment_translation->get_id() : false;

		foreach ( $translation_data as $field => $data ) {

			$translated_value = $translation_package->decode_field_data(
				$data->field_data_translated,
				$data->field_format
			);

			switch ( $field ) {
				case 'title':
					$wp_post_field             = 'post_title';
					$postarr[ $wp_post_field ] = $translated_value;
					break;
				case 'caption':
					$wp_post_field             = 'post_excerpt';
					$postarr[ $wp_post_field ] = $translated_value;
					break;
				case 'description':
					$wp_post_field             = 'post_content';
					$postarr[ $wp_post_field ] = $translated_value;
					break;
				case 'alt_text':
					$alt_text = $translated_value;
					break;
				default:
					$media_custom_fields[ $field ] = $translated_value;
					$field                         = $this->media_field->getFieldId( $field );
					if ( $attachment_translation_id ) {
						delete_post_meta( $attachment_translation_id, $field );
					}
			}
		}

		if ( $attachment_translation_id ) {
			$postarr['ID'] = $attachment_translation_id;
			wp_update_post( $postarr );
		} else {
			$postarr['post_type']      = 'attachment';
			$postarr['post_status']    = 'inherit';
			$postarr['guid']           = get_post_field( 'guid', $attachment_id );
			$postarr['post_mime_type'] = get_post_field( 'post_mime_type', $attachment_id );

			$attachment_translation_id = wp_insert_post( $postarr );

			$this->sitepress->set_element_language_details( $attachment_translation_id, 'post_attachment', $post_element->get_trid(), $language );

			$this->copy_attached_file_info_from_original( $attachment_translation_id, $attachment_id );

		}

		if ( null !== $alt_text ) {
			update_post_meta( $attachment_translation_id, '_wp_attachment_image_alt', $alt_text );
		}

		foreach ( $media_custom_fields as $field => $value ) {
			$field = $this->media_field->getFieldId( $field );
			add_post_meta( $attachment_translation_id, $field, $value );
		}

		return $attachment_translation_id;
	}

	private function copy_attached_file_info_from_original( $attachment_id, $original_attachment_id ) {
		$meta_keys = array(
			'_wp_attachment_metadata',
			'_wp_attached_file',
			'_wp_attachment_backup_sizes',
		);
		foreach ( $meta_keys as $meta_key ) {
			update_post_meta(
				$attachment_id,
				$meta_key,
				get_post_meta( $original_attachment_id, $meta_key, true )
			);
		}
	}
}
