<?php

namespace Limb_Chatbot\Includes\Data_Objects;

use Limb_Chatbot\Includes\Services\Collection;

/**
 * Class Lead
 *
 * Represents a lead capture record with source tracking and qualification status.
 * Stores lead metadata without the actual field values (see Lead_Field and Lead_Value).
 *
 * @package Limb_Chatbot\Includes\Data_Objects
 * @since 1.0.13
 */
class Lead extends WPDB_Data_Object {

	/**
	 * Database table name.
	 */
	const TABLE_NAME = 'lbaic_leads';

	/**
	 * Attributes allowed for mass assignment.
	 *
	 * @var array
	 */
	const FILLABLE = [
		'id',
		'chatbot_user_uuid',
		'chatbot_uuid',
		'chat_uuid',
		'source_type',
		'source',
		'source_title',
		'metadata',
		'created_at',
		'status',
		'is_qualified',
	];
	/**
	 * Source type: Action
	 */
	const SOURCE_TYPE_ACTION = 'action';
	/**
	 * Source type: Widget
	 */
	const SOURCE_TYPE_WIDGET = 'widget';
	/**
	 * Status: Active
	 */
	const STATUS_NEW = 'new';
	/**
	 * Status: Archived
	 */
	const STATUS_ARCHIVED = 'archived';
	public ?string $chat_uuid = null;
	/**
	 * @json_excluded
	 * @var array
	 */
	public $included = [];
	/**
	 * @json_excluded
	 * @var array|string[]
	 */
	public array $meta_properties = [ 'lead_values', 'last_activity' ];

	/**
	 * Chatbot user UUID
	 *
	 * @var string
	 */
	public string $chatbot_user_uuid;
	/**
	 * Chatbot UUID (optional)
	 *
	 * @var string|null
	 */
	public ?string $chatbot_uuid = null;
	/**
	 * Source type (action or widget)
	 *
	 * @var string
	 */
	public string $source_type;
	/**
	 * Source ID as string (action ID or widget ID)
	 *
	 * @var string
	 */
	public string $source;
	/**
	 * Source title (action title or widget title)
	 *
	 * @var string
	 */
	public string $source_title;
	/**
	 * Optional lead metadata payload.
	 *
	 * @var array|null
	 */
	public ?array $metadata = null;
	/**
	 * When the lead was captured
	 *
	 * @var string
	 */
	public string $created_at;
	/**
	 * Lead status (active, archived)
	 *
	 * @var string
	 */
	public string $status = self::STATUS_NEW;
	/**
	 * Whether lead is qualified
	 *
	 * @var int
	 */
	public int $is_qualified = 0;

	public function lead_values() {
		return Lead_Value::where( [
			'lead_id' => $this->id
		] )->get();
	}

	/**
	 * Get chatbot user UUID
	 *
	 * @return string
	 * @since 1.0.13
	 */
	public function get_chatbot_user_uuid(): string {
		return $this->chatbot_user_uuid;
	}

	/**
	 * Set chatbot user UUID
	 *
	 * @param  string  $uuid
	 *
	 * @return void
	 * @since 1.0.13
	 */
	public function set_chatbot_user_uuid( string $uuid ): void {
		$this->chatbot_user_uuid = $uuid;
	}

	/**
	 * Get chatbot UUID
	 *
	 * @return string|null
	 * @since 1.0.13
	 */
	public function get_chatbot_uuid(): ?string {
		return $this->chatbot_uuid;
	}

	/**
	 * Set chatbot UUID
	 *
	 * @param  string|null  $uuid
	 *
	 * @return void
	 * @since 1.0.13
	 */
	public function set_chatbot_uuid( ?string $uuid ): void {
		$this->chatbot_uuid = $uuid;
	}

	/**
	 * Get source type
	 *
	 * @return string
	 * @since 1.0.13
	 */
	public function get_source_type(): string {
		return $this->source_type;
	}

	/**
	 * Set source type
	 *
	 * @param  string  $type
	 *
	 * @return void
	 * @since 1.0.13
	 */
	public function set_source_type( string $type ): void {
		$this->source_type = $type;
	}

	/**
	 * Get source ID
	 *
	 * @return string
	 * @since 1.0.13
	 */
	public function get_source(): string {
		return $this->source;
	}

	/**
	 * Set source ID
	 *
	 * @param  string  $source
	 *
	 * @return void
	 * @since 1.0.13
	 */
	public function set_source( string $source ): void {
		$this->source = $source;
	}

	/**
	 * Get source title
	 *
	 * @return string
	 * @since 1.0.13
	 */
	public function get_source_title(): string {
		return $this->source_title;
	}

	/**
	 * Set source title
	 *
	 * @param  string  $title
	 *
	 * @return void
	 * @since 1.0.13
	 */
	public function set_source_title( string $title ): void {
		$this->source_title = $title;
	}

	/**
	 * Get lead metadata.
	 *
	 * @return array|null
	 * @since 1.0.18
	 */
	public function get_metadata(): ?array {
		return $this->metadata;
	}

	/**
	 * Set lead metadata.
	 *
	 * Accepts array payload directly or JSON string from database hydration.
	 *
	 * @param  mixed  $metadata
	 *
	 * @return void
	 * @since 1.0.18
	 */
	public function set_metadata( $metadata ): void {
		if ( is_array( $metadata ) ) {
			$this->metadata = $metadata;

			return;
		}

		if ( is_string( $metadata ) && $metadata !== '' ) {
			$decoded = json_decode( $metadata, true );
			$this->metadata = is_array( $decoded ) ? $decoded : null;

			return;
		}

		$this->metadata = null;
	}

	/**
	 * Get status
	 *
	 * @return string
	 * @since 1.0.13
	 */
	public function get_status(): string {
		return $this->status;
	}

	/**
	 * Set status
	 *
	 * @param  string  $status
	 *
	 * @return void
	 * @since 1.0.13
	 */
	public function set_status( string $status ): void {
		$this->status = $status;
	}

	/**
	 * Get qualification status
	 *
	 * @return int
	 * @since 1.0.13
	 */
	public function get_is_qualified(): int {
		return $this->is_qualified;
	}

	/**
	 * Set qualification status
	 *
	 * @param  int  $qualified
	 *
	 * @return void
	 * @since 1.0.13
	 */
	public function set_is_qualified( int $qualified ): void {
		$this->is_qualified = $qualified;
	}

	/**
	 * Check if lead is from an action
	 *
	 * @return bool
	 * @since 1.0.13
	 */
	public function is_action_source(): bool {
		return $this->source_type === self::SOURCE_TYPE_ACTION;
	}

	/**
	 * Check if lead is from a widget
	 *
	 * @return bool
	 * @since 1.0.13
	 */
	public function is_widget_source(): bool {
		return $this->source_type === self::SOURCE_TYPE_WIDGET;
	}

	/**
	 * Get lead values
	 *
	 * @return Collection
	 * @since 1.0.13
	 */
	public function get_values() {
		return Lead_Value::where( [ 'lead_id' => $this->get_id() ] );
	}

	/**
	 * Get the chatbot user associated with this lead
	 *
	 * @return Chatbot_User|null
	 * @since 1.0.13
	 */
	public function chatbot_user(): ?Chatbot_User {
		return Chatbot_User::find_by_uuid( $this->chatbot_user_uuid );
	}

	public function get_chat_uuid() {
		return $this->chat_uuid;
	}

	public function set_chat_uuid( ?string $uuid ) {
		$this->chat_uuid = $uuid;
	}

	public function last_activity() {
		if ( ! empty( $this->chatbot_user_uuid ) ) {
			$chatbot_user = Chatbot_User::find_by_uuid( $this->chatbot_user_uuid );
			if ( ! $chatbot_user instanceof Chatbot_User ) {
				return null;
			}
			$chat_participant = Chat_Participant::where( [
				'user_id' => $chatbot_user->get_id()
			], 1, 1, 'joined_at', 'desc' )->first();
			if ( $chat_participant instanceof Chat_Participant ) {
				$chat = Chat::find( $chat_participant->get_chat_id() );
				if ( $chat instanceof Chat ) {
					return $chat->get_last_user_message()->get_created_at();
				}
			}
		}

		return null;
	}

	/**
	 * Get creation timestamp
	 *
	 * @return string
	 * @since 1.0.13
	 */
	public function get_created_at(): string {
		return $this->created_at;
	}

	/**
	 * Set creation timestamp
	 *
	 * @param  string  $timestamp
	 *
	 * @return void
	 * @since 1.0.13
	 */
	public function set_created_at( string $timestamp ): void {
		$this->created_at = $timestamp;
	}
}
