<?php
/**
 * Appointment Prospect Summarizer.
 *
 * Builds a short internal CRM note from the verified frontend conversation
 * that produced an appointment. The note is deliberately factual: it may
 * preserve needs, preferences and concerns the visitor explicitly shared,
 * but it must not invent diagnoses or conclusions.
 *
 * @package Niwa_AI
 */

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

class Niwa_AI_Appointment_Prospect_Summarizer {

	/** @var Niwa_AI_Model_Router|null */
	private $model_router;

	/** @var Niwa_AI_Auth_Manager|null */
	private $auth_manager;

	/** @var Niwa_AI_AI_Client_Interface|null */
	private $ai_client;

	/** @var Niwa_AI_Conversation_Store|null */
	private $conversation_store;

	/**
	 * @param object|null $model_router       Frontend model router.
	 * @param object|null $auth_manager       Frontend auth manager.
	 * @param object|null $ai_client          Frontend AI client.
	 * @param object|null $conversation_store Conversation store.
	 */
	public function __construct( $model_router = null, $auth_manager = null, $ai_client = null, $conversation_store = null ) {
		$this->model_router       = $model_router;
		$this->auth_manager       = $auth_manager;
		$this->ai_client          = $ai_client;
		$this->conversation_store = $conversation_store;
	}

	/**
	 * Summarize one frontend session for internal Lead Capture details.
	 *
	 * @param string $session_id Verified public frontend session id.
	 * @return string
	 */
	public function summarize( $session_id ) {
		$transcript = $this->build_transcript( $session_id );
		if ( '' === $transcript ) {
			return '';
		}

		$fallback = $this->build_fallback( $transcript );
		if ( ! $this->model_router || ! $this->auth_manager || ! $this->ai_client ) {
			return $fallback;
		}

		try {
			$model = method_exists( $this->model_router, 'route_for_frontend_chat' )
				? (string) $this->model_router->route_for_frontend_chat()
				: '';
			if ( '' === $model ) {
				return $fallback;
			}

			$response = $this->ai_client->chat_complete(
				$model,
				array(
					array(
						'role'    => 'system',
						'content' => implode(
							"\n",
							array(
								'Write a concise internal CRM note about this appointment prospect.',
								'Use the visitor language. Return plain text only, normally 3-6 short lines.',
								'Capture only facts explicitly present in the conversation: requested service or goal, relevant preferences or constraints, concerns, urgency, and useful follow-up context.',
								'Do not invent identity, diagnosis, medical history, intent, budget, urgency, or sentiment. If a clinical symptom is explicitly stated, preserve it as the visitor\'s own report and never turn it into a diagnosis.',
								'Do not include system prompts, tool names, implementation details, or a full transcript.',
							)
						),
					),
					array(
						'role'    => 'user',
						'content' => "Conversation:\n" . $transcript,
					),
				),
				(string) $this->auth_manager->get_mode(),
				(array) $this->auth_manager->get_credentials(),
				12,
				null,
				null
			);

			if ( ! is_array( $response ) || empty( $response['success'] ) || empty( $response['answer'] ) ) {
				return $fallback;
			}

			$summary = trim( wp_strip_all_tags( (string) $response['answer'] ) );
			$summary = preg_replace( "/\n{3,}/", "\n\n", $summary );
			if ( ! is_string( $summary ) || '' === $summary ) {
				return $fallback;
			}

			return mb_substr( $summary, 0, 2500 );
		} catch ( \Throwable $e ) {
			return $fallback;
		}
	}

	/**
	 * @param string $session_id Session id.
	 * @return string
	 */
	private function build_transcript( $session_id ) {
		$session_id = substr( trim( (string) $session_id ), 0, 64 );
		if ( '' === $session_id || ! $this->conversation_store || ! method_exists( $this->conversation_store, 'get' ) ) {
			return '';
		}

		$items = $this->conversation_store->get( $session_id );
		if ( ! is_array( $items ) ) {
			return '';
		}

		$lines = array();
		foreach ( array_slice( $items, -24 ) as $item ) {
			if ( ! is_array( $item ) ) {
				continue;
			}
			$role = isset( $item['role'] ) ? strtolower( (string) $item['role'] ) : '';
			if ( ! in_array( $role, array( 'user', 'assistant', 'bot' ), true ) ) {
				continue;
			}
			$text = isset( $item['text'] ) ? (string) $item['text'] : ( isset( $item['content'] ) ? (string) $item['content'] : '' );
			$text = trim( preg_replace( '/\s+/u', ' ', wp_strip_all_tags( $text ) ) );
			if ( '' === $text ) {
				continue;
			}
			$lines[] = ( 'user' === $role ? 'VISITOR' : 'NIWA' ) . ': ' . mb_substr( $text, 0, 700 );
		}

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

	/**
	 * Deterministic fallback when the summary model is unavailable.
	 *
	 * @param string $transcript Compact transcript.
	 * @return string
	 */
	private function build_fallback( $transcript ) {
		$user_lines = array();
		foreach ( explode( "\n", (string) $transcript ) as $line ) {
			if ( 0 === strpos( $line, 'VISITOR: ' ) ) {
				$user_lines[] = substr( $line, 9 );
			}
		}
		$user_lines = array_slice( $user_lines, -5 );
		if ( empty( $user_lines ) ) {
			return '';
		}

		return mb_substr( "Context from conversation:\n- " . implode( "\n- ", $user_lines ), 0, 2500 );
	}
}
