<?php

namespace Limb_Chatbot\Includes\Data_Objects;

use Limb_Chatbot\Includes\Services\Collection;

/**
 * Class Lead_Value
 *
 * Represents a lead field value with support for multiple data types.
 * Values are stored in type-specific columns for efficient querying and type safety.
 *
 * @package Limb_Chatbot\Includes\Data_Objects
 * @since 1.0.13
 */
class Lead_Value extends WPDB_Data_Object {

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

	/**
	 * Attributes allowed for mass assignment.
	 *
	 * @var array
	 */
	const FILLABLE = [
		'id',
		'lead_id',
		'field_id',
		'value_string',
		'value_number',
		'value_date',
	];

	/**
	 * Lead ID (foreign key)
	 *
	 * @var int
	 */
	public int $lead_id;

	/**
	 * Field ID (foreign key)
	 *
	 * @var int
	 */
	public int $field_id;

	/**
	 * String value storage
	 *
	 * @var string|null
	 */
	public ?string $value_string = null;

	/**
	 * Numeric value storage
	 *
	 * @var float|null
	 */
	public ?float $value_number = null;

	/**
	 * Date value storage
	 *
	 * @var string|null
	 */
	public ?string $value_date = null;


	/**
	 * Get lead ID
	 *
	 * @return int
	 * @since 1.0.13
	 */
	public function get_lead_id(): int {
		return $this->lead_id;
	}

	/**
	 * Set lead ID
	 *
	 * @param int $lead_id
	 *
	 * @return void
	 * @since 1.0.13
	 */
	public function set_lead_id( int $lead_id ): void {
		$this->lead_id = $lead_id;
	}

	/**
	 * Get field ID
	 *
	 * @return int
	 * @since 1.0.13
	 */
	public function get_field_id(): int {
		return $this->field_id;
	}

	/**
	 * Set field ID
	 *
	 * @param int $field_id
	 *
	 * @return void
	 * @since 1.0.13
	 */
	public function set_field_id( int $field_id ): void {
		$this->field_id = $field_id;
	}

	/**
	 * Get string value
	 *
	 * @return string|null
	 * @since 1.0.13
	 */
	public function get_value_string(): ?string {
		return $this->value_string;
	}

	/**
	 * Set string value
	 *
	 * @param string|null $value
	 *
	 * @return void
	 * @since 1.0.13
	 */
	public function set_value_string( ?string $value ): void {
		$this->value_string = $value;
	}

	/**
	 * Get numeric value
	 *
	 * @return float|null
	 * @since 1.0.13
	 */
	public function get_value_number(): ?float {
		return $this->value_number;
	}

	/**
	 * Set numeric value
	 *
	 * @param float|null $value
	 *
	 * @return void
	 * @since 1.0.13
	 */
	public function set_value_number( ?float $value ): void {
		$this->value_number = $value;
	}

	/**
	 * Get date value
	 *
	 * @return string|null
	 * @since 1.0.13
	 */
	public function get_value_date(): ?string {
		return $this->value_date;
	}

	/**
	 * Set date value
	 *
	 * @param string|null $value
	 *
	 * @return void
	 * @since 1.0.13
	 */
	public function set_value_date( ?string $value ): void {
		$this->value_date = $value;
	}

	/**
	 * Get the actual value based on field type
	 *
	 * @return mixed The appropriate value for the field's data type
	 * @since 1.0.13
	 */
	public function get_value() {
		if ( ! is_null( $this->value_string ) ) {
			return $this->value_string;
		}
		if ( ! is_null( $this->value_number ) ) {
			return $this->value_number;
		}
		if ( ! is_null( $this->value_date ) ) {
			return $this->value_date;
		}

		return null;
	}

	/**
	 * Set value based on data type
	 *
	 * @param string $data_type Data type constant from Lead_Field
	 * @param mixed $value The value to store
	 *
	 * @return void
	 * @since 1.0.13
	 */
	public function set_value( string $data_type, $value ): void {
		// Clear all values first
		$this->value_string = null;
		$this->value_number = null;
		$this->value_date   = null;

		// Set based on type
		switch ( $data_type ) {
			case Lead_Field::DATA_TYPE_NUMBER:
				$this->value_number = is_numeric( $value ) ? (float) $value : null;
				break;
			case Lead_Field::DATA_TYPE_DATE:
				$this->value_date = $value;
				break;
			case Lead_Field::DATA_TYPE_TEXT:
			case Lead_Field::DATA_TYPE_EMAIL:
			case Lead_Field::DATA_TYPE_PHONE:
			case Lead_Field::DATA_TYPE_ATTACHMENT:
			default:
				$this->value_string = (string) $value;
				break;
		}
	}

	/**
	 * Get all values for a lead
	 *
	 * @param int $lead_id
	 *
	 * @return Collection
	 * @since 1.0.13
	 */
	public static function get_for_lead( int $lead_id ) {
		return self::where( [ 'lead_id' => $lead_id ] );
	}

	/**
	 * Get all values for a field
	 *
	 * @param int $field_id
	 *
	 * @return Collection
     * @since 1.0.13
	 */
	public static function get_for_field( int $field_id ) {
		return self::where( [ 'field_id' => $field_id ] );
	}

	/**
	 * Get the lead field associated with this value
	 *
	 * @return Lead_Field|null
	 * @since 1.0.13
	 */
	public function lead_field(): ?Lead_Field {
		return Lead_Field::find( $this->field_id );
	}
}
