<?php

namespace WC_Affiliate\Models;

defined( 'ABSPATH' ) || exit;

/**
 * Class DataImporter
 *
 * Handles data import operations for various data types.
 */
class DataImporter {

	/**
	 * Import affiliate data.
	 *
	 * @param array $data Affiliate data to import.
	 *
	 * @return array Import results.
	 */
	public static function import_affiliates( array $data ): array {
		/**
		 * Filter to allow preventing affiliate import operations.
		 *
		 * @param bool  $can_import Whether the import can proceed.
		 * @param array $data       Affiliate data to import.
		 */
		$can_import = apply_filters( 'wc_affiliate_can_import_affiliates', true, $data );
		if ( ! $can_import ) {
			return array(
				'imported' => 0,
				'skipped'  => count( $data ),
				'errors'   => array( __( 'Import operation not allowed.', 'wc-affiliate' ) ),
			);
		}

		/**
		 * Filter to modify affiliate import data.
		 *
		 * @param array $data Affiliate data to import.
		 */
		$data = apply_filters( 'wc_affiliate_data_importer_import_affiliates_data', $data );

		/**
		 * Action hook fired before affiliate import.
		 *
		 * @param array $data Affiliate data to import.
		 */
		do_action( 'wc_affiliate_data_importer_before_import_affiliates', $data );
		global $wpdb;

		$results = array(
			'imported' => 0,
			'skipped'  => 0,
			'errors'   => array(),
		);

		foreach ( $data as $email => $affiliate ) {
			$user  = array();
			$email = sanitize_email( $email );

			if ( email_exists( $email ) ) {
				$user = get_user_by( 'email', $email );
			} else {
				$user_data = array(
					'user_login'   => sanitize_text_field( $affiliate->user_name ?? '' ),
					'user_email'   => $email,
					'display_name' => sanitize_text_field( $affiliate->user_name ?? '' ),
				);
				$user_id   = User::create_user( $user_data );
				$user      = get_user_by( 'ID', $user_id );
			}

			if ( $user && ! is_wp_error( $user ) ) {
				// Create affiliate if not exists
				$affiliate_model    = new Affiliate();
				$existing_affiliate = $affiliate_model->get_by_user_id( $user->ID );

				if ( ! $existing_affiliate || is_wp_error( $existing_affiliate ) ) {
					$affiliate_data = array(
						'user_id'           => $user->ID,
						'status'            => sanitize_text_field( $affiliate->affiliate_status ?? 'pending' ),
						'commission_type'   => sanitize_text_field( $affiliate->commission_type ?? 'percent' ),
						'commission_amount' => floatval( $affiliate->commission_amount ?? 0 ),
					);

					$result = $affiliate_model->create( $affiliate_data );
					if ( is_wp_error( $result ) ) {
						$results['errors'][] = sprintf(
						/* translators: 1: Email, 2: Error message */
							__( 'Failed to create affiliate for %1$s: %2$s', 'wc-affiliate' ),
							$email,
							$result->get_error_message()
						);
						++$results['skipped'];
					} else {
						++$results['imported'];
					}
				} else {
					++$results['skipped'];
				}
			} else {
				$results['errors'][] = sprintf(
				/* translators: %s: Email */
					__( 'Failed to create or find user for %s', 'wc-affiliate' ),
					$email
				);
				++$results['skipped'];
			}
		}

		/**
		 * Action hook fired after affiliate import.
		 *
		 * @param array $results Import results.
		 * @param array $data    Original import data.
		 */
		do_action( 'wc_affiliate_data_importer_after_import_affiliates', $results, $data );

		return $results;
	}

	/**
	 * Import referral items.
	 *
	 * @param array $referral_items Referral data to import.
	 *
	 * @return int Number of rows inserted.
	 */
	public static function import_referrals( array $referral_items ): int {
		/**
		 * Filter to allow preventing referral import operations.
		 *
		 * @param bool  $can_import     Whether the import can proceed.
		 * @param array $referral_items Referral data to import.
		 */
		$can_import = apply_filters( 'wc_affiliate_can_import_referrals', true, $referral_items );
		if ( ! $can_import ) {
			return 0;
		}

		/**
		 * Filter to modify referral import data.
		 *
		 * @param array $referral_items Referral data to import.
		 */
		$referral_items = apply_filters( 'wc_affiliate_data_importer_import_referrals_data', $referral_items );

		/**
		 * Action hook fired before referral import.
		 *
		 * @param array $referral_items Referral data to import.
		 */
		do_action( 'wc_affiliate_data_importer_before_import_referrals', $referral_items );
		global $wpdb;

		$referrals_table = "{$wpdb->prefix}wca_referrals";
		$inserted        = 0;

		if ( ! empty( $referral_items ) ) {
			foreach ( $referral_items as $data ) {
				$user = get_user_by( 'email', $data['email'] ?? '' );

				if ( ! $user ) {
					continue;
				}

				// Prepare referral data
				$referral_data = array(
					'affiliate'       => $user->ID,
					'order_id'        => intval( $data['order_id'] ?? 0 ),
					'order_total'     => floatval( $data['order_total'] ?? 0 ),
					'commission'      => floatval( $data['commission'] ?? 0 ),
					'commission_type' => sanitize_text_field( $data['commission_type'] ?? 'percent' ),
					'status'          => sanitize_text_field( $data['status'] ?? 'unpaid' ),
					'payment_status'  => sanitize_text_field( $data['payment_status'] ?? 'unpaid' ),
					'time'            => intval( $data['time'] ?? time() ),
				);

				// Insert referral
				$result = $wpdb->insert(
					$referrals_table,
					$referral_data,
					array( '%d', '%d', '%f', '%f', '%s', '%s', '%s', '%d' )
				);

				if ( false !== $result ) {
					++$inserted;
				}
			}
		}

		/**
		 * Action hook fired after referral import.
		 *
		 * @param int   $inserted       Number of rows inserted.
		 * @param array $referral_items Original import data.
		 */
		do_action( 'wc_affiliate_data_importer_after_import_referrals', $inserted, $referral_items );

		return $inserted;
	}
}
