<?php
/**
 * Lead WhatsApp Outreach Service
 *
 * Exposes the explicit outbound lead-message path for admin autonomy.
 *
 * @package Niwa_AI
 * @since   0.13.479
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

class Niwa_AI_Lead_WhatsApp_Outreach_Service {

	const SOURCE_OUTREACH  = 'whatsapp_lead_outreach';

	/**
	 * @var Niwa_AI_Contact_Service
	 */
	private $contact_service;

	public function __construct( $contact_service = null ) {
		$this->contact_service = $contact_service instanceof Niwa_AI_Contact_Service
			? $contact_service
			: new Niwa_AI_Contact_Service();
	}

	public function send_outreach( $args ) {
		$args    = is_array( $args ) ? $args : array();
		$message = isset( $args['message'] ) ? trim( (string) $args['message'] ) : '';
		if ( '' === $message ) {
			return array(
				'success' => false,
				'error'   => 'message_required',
			);
		}

		$target = $this->resolve_outreach_target( $args );
		if ( empty( $target['success'] ) ) {
			return $target;
		}

		$phone = $this->normalize_whatsapp_phone( isset( $target['phone'] ) ? $target['phone'] : '' );
		if ( '' === $phone ) {
			return array(
				'success' => false,
				'error'   => 'valid_whatsapp_phone_required',
			);
		}

		$target_role = $this->assert_sendable_lead_phone( $phone );
		if ( empty( $target_role['success'] ) ) {
			return $target_role;
		}

		$name   = isset( $target['name'] ) ? (string) $target['name'] : '';
		$email  = isset( $target['email'] ) ? (string) $target['email'] : '';
		$source = isset( $args['source'] ) ? sanitize_key( (string) $args['source'] ) : self::SOURCE_OUTREACH;
		if ( '' === $source ) {
			$source = self::SOURCE_OUTREACH;
		}

		$contact_result = $this->contact_service->save_contact( $email, $name, $phone, $source );
		$contact_id     = ! empty( $contact_result['id'] ) ? (int) $contact_result['id'] : ( isset( $target['contact_id'] ) ? (int) $target['contact_id'] : 0 );
		$lead_result    = $this->add_whatsapp_lead( $phone, $this->build_lead_label( $name, $source ) );
		if ( empty( $lead_result['success'] ) ) {
			return array(
				'success'    => false,
				'error'      => isset( $lead_result['error'] ) ? (string) $lead_result['error'] : 'whatsapp_lead_access_sync_failed',
				'contact_id' => $contact_id,
				'phone'      => $this->mask_phone( $phone ),
				'lead_sync'  => $lead_result,
			);
		}

		$confirmed_role = $this->get_whatsapp_role( $phone );
		if ( 'lead' !== $confirmed_role ) {
			return array(
				'success'       => false,
				'error'         => 'whatsapp_lead_access_not_confirmed',
				'contact_id'    => $contact_id,
				'phone'         => $this->mask_phone( $phone ),
				'confirmed_role' => $confirmed_role,
				'lead_sync'     => $lead_result,
			);
		}

		if ( ! empty( $args['dry_run'] ) ) {
			return array(
				'success'    => true,
				'dry_run'    => true,
				'contact_id' => $contact_id,
				'phone'      => $this->mask_phone( $phone ),
				'lead_sync'  => $lead_result,
			);
		}

		if ( ! class_exists( 'Niwa_AI_Admin_Autonomy_WhatsApp' ) ) {
			return array(
				'success' => false,
				'error'   => 'whatsapp_runtime_unavailable',
			);
		}

		$wa       = new Niwa_AI_Admin_Autonomy_WhatsApp();
		$settings = $wa->get_settings();
		if ( empty( $settings['enabled'] ) ) {
			return array(
				'success' => false,
				'error'   => 'whatsapp_not_enabled',
			);
		}

		$send = $wa->send_message(
			$phone,
			$message,
			array(
				'lead_outreach' => true,
				'contact_id'    => $contact_id,
				'source'        => $source,
				'workflow_key'  => isset( $args['workflow_key'] ) ? sanitize_key( (string) $args['workflow_key'] ) : '',
			)
		);

		return array(
			'success'    => ! empty( $send['success'] ),
			'queued'     => ! empty( $send['queued'] ),
			'ids'        => isset( $send['ids'] ) ? $send['ids'] : array(),
			'error'      => isset( $send['error'] ) ? $send['error'] : '',
			'contact_id' => $contact_id,
			'phone'      => $this->mask_phone( $phone ),
			'lead_sync'  => $lead_result,
		);
	}

	private function resolve_outreach_target( $args ) {
		$phone = isset( $args['phone'] ) ? (string) $args['phone'] : '';
		if ( '' !== $this->normalize_whatsapp_phone( $phone ) ) {
			return array(
				'success'    => true,
				'contact_id' => isset( $args['contact_id'] ) ? (int) $args['contact_id'] : 0,
				'phone'      => $phone,
				'name'       => isset( $args['name'] ) ? (string) $args['name'] : '',
				'email'      => isset( $args['email'] ) ? (string) $args['email'] : '',
			);
		}

		$contact_id = isset( $args['contact_id'] ) ? (int) $args['contact_id'] : 0;
		if ( $contact_id > 0 && method_exists( $this->contact_service, 'get_contact' ) ) {
			$contact = $this->contact_service->get_contact( $contact_id );
			if ( is_array( $contact ) && ! empty( $contact['phone'] ) ) {
				$contact['success']    = true;
				$contact['contact_id'] = $contact_id;
				return $contact;
			}
		}

		$query = isset( $args['query'] ) ? trim( (string) $args['query'] ) : '';
		if ( '' === $query || ! method_exists( $this->contact_service, 'search_contacts' ) ) {
			return array(
				'success' => false,
				'error'   => 'contact_id_phone_or_query_required',
			);
		}

		$results = $this->contact_service->search_contacts( $query, 5, 0 );
		$items   = isset( $results['items'] ) && is_array( $results['items'] ) ? $results['items'] : array();
		$items   = array_values(
			array_filter(
				$items,
				function ( $item ) {
					return is_array( $item ) && '' !== $this->normalize_whatsapp_phone( isset( $item['phone'] ) ? $item['phone'] : '' );
				}
			)
		);

		if ( 1 === count( $items ) ) {
			$items[0]['success']    = true;
			$items[0]['contact_id'] = isset( $items[0]['id'] ) ? (int) $items[0]['id'] : 0;
			return $items[0];
		}

		return array(
			'success'    => false,
			'error'      => empty( $items ) ? 'no_sendable_contact_found' : 'ambiguous_contact_query',
			'candidates' => array_map(
				function ( $item ) {
					return array(
						'id'    => isset( $item['id'] ) ? (int) $item['id'] : 0,
						'name'  => isset( $item['name'] ) ? (string) $item['name'] : '',
						'email' => isset( $item['email'] ) ? (string) $item['email'] : '',
						'phone' => $this->mask_phone( isset( $item['phone'] ) ? (string) $item['phone'] : '' ),
					);
				},
				$items
			),
		);
	}

	private function add_whatsapp_lead( $phone, $label ) {
		if ( ! class_exists( 'Niwa_AI_Admin_Autonomy_WhatsApp' ) ) {
			return array( 'success' => false, 'error' => 'whatsapp_runtime_unavailable' );
		}

		$wa = new Niwa_AI_Admin_Autonomy_WhatsApp();
		if ( ! method_exists( $wa, 'manage_access_numbers' ) ) {
			return array( 'success' => false, 'error' => 'whatsapp_access_manager_unavailable' );
		}

		return $wa->manage_access_numbers( 'add', 'lead', $phone, $label );
	}

	private function assert_sendable_lead_phone( $phone ) {
		$role = $this->get_whatsapp_role( $phone );
		if ( in_array( $role, array( 'admin', 'stock_manager' ), true ) ) {
			return array(
				'success' => false,
				'error'   => 'whatsapp_privileged_number_not_lead_target',
				'role'    => $role,
				'phone'   => $this->mask_phone( $phone ),
			);
		}

		return array(
			'success' => true,
			'role'    => $role,
		);
	}

	private function get_whatsapp_role( $phone ) {
		if ( ! class_exists( 'Niwa_AI_Admin_Autonomy_WhatsApp' ) ) {
			return null;
		}

		$wa = new Niwa_AI_Admin_Autonomy_WhatsApp();
		return method_exists( $wa, 'get_user_role' ) ? $wa->get_user_role( $phone ) : null;
	}

	private function normalize_whatsapp_phone( $phone ) {
		return class_exists( 'Niwa_AI_Phone_Normalizer' )
			? (string) Niwa_AI_Phone_Normalizer::normalize( $phone )
			: '';
	}

	private function build_lead_label( $name, $source ) {
		$name   = trim( sanitize_text_field( (string) $name ) );
		$source = sanitize_key( (string) $source );
		$label  = '' !== $name ? $name : 'Niwa lead';
		if ( '' !== $source ) {
			$label .= ' - ' . $source;
		}
		return mb_substr( $label, 0, 100 );
	}

	private function mask_phone( $phone ) {
		$phone = $this->normalize_whatsapp_phone( $phone );
		if ( strlen( $phone ) <= 5 ) {
			return $phone;
		}

		return substr( $phone, 0, 3 ) . str_repeat( '*', max( 1, strlen( $phone ) - 5 ) ) . substr( $phone, -2 );
	}
}
