<?php
/**
 * Lead notes and activity repository.
 *
 * @package SubmissionInbox
 */

namespace SUBIN\Leads;

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

// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Repository methods read/write Submission Inbox custom workflow tables directly.
// phpcs:disable PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Table names are plugin-owned $wpdb->prefix values.

/**
 * Stores lead notes and workflow activity.
 */
class LeadActivityRepository {
	const MAX_NOTE_LENGTH = 5000;

	/**
	 * Add a note and activity entry.
	 *
	 * @param int    $lead_id Lead id.
	 * @param string $note Note text.
	 * @param int    $user_id User id.
	 * @return int
	 */
	public function add_note( $lead_id, $note, $user_id = 0 ) {
		$result = $this->add_note_checked( $lead_id, $note, $user_id );

		return is_wp_error( $result ) ? 0 : absint( $result );
	}

	/**
	 * Add a note after validating and locking its parent lead.
	 *
	 * @param int    $lead_id Lead id.
	 * @param string $note Note text.
	 * @param int    $user_id User id.
	 * @return int|\WP_Error
	 */
	public function add_note_checked( $lead_id, $note, $user_id = 0 ) {
		global $wpdb;

		$lead_id = absint( $lead_id );
		$user_id = absint( $user_id );
		if ( $lead_id <= 0 ) {
			return new \WP_Error( 'subin_note_lead_invalid', __( 'A valid lead is required.', 'submission-inbox' ) );
		}
		$note = $this->validate_note_text( $note );
		if ( is_wp_error( $note ) ) {
			return $note;
		}
		if ( false === $wpdb->query( 'START TRANSACTION' ) ) {
			return new \WP_Error( 'subin_note_transaction_failed', __( 'The note transaction could not start.', 'submission-inbox' ) );
		}

		$parent_locked = $this->lock_parent_lead( $lead_id );
		if ( is_wp_error( $parent_locked ) ) {
			$wpdb->query( 'ROLLBACK' );

			return $parent_locked;
		}

		$now      = current_time( 'mysql' );
		$inserted = $wpdb->insert(
			$wpdb->prefix . 'subin_lead_notes',
			array(
				'lead_id'    => $lead_id,
				'user_id'    => $user_id,
				'note'       => $note,
				'sync_footprint' => 0,
				'created_at' => $now,
				'updated_at' => $now,
			),
			array( '%d', '%d', '%s', '%d', '%s', '%s' )
		);

		if ( ! $inserted ) {
			return $this->rollback_error( 'subin_note_insert_failed', __( 'The note could not be added.', 'submission-inbox' ) );
		}

		$note_id = absint( $wpdb->insert_id );
			$activity_id = $this->insert_activity_row(
			$lead_id,
			'note_added',
			__( 'Note added.', 'submission-inbox' ),
			array(
				'note_id'      => $note_id,
				'note_version' => 1,
			),
			$user_id
		);
		if ( $activity_id <= 0 ) {
			return $this->rollback_error( 'subin_note_activity_failed', __( 'The note activity could not be recorded.', 'submission-inbox' ) );
		}
		if ( ! $this->touch_lead( $lead_id, $now ) ) {
			return $this->rollback_error( 'subin_note_lead_update_failed', __( 'The lead could not be updated with the note.', 'submission-inbox' ) );
		}
		if ( false === $wpdb->query( 'COMMIT' ) ) {
			return $this->rollback_error( 'subin_note_commit_failed', __( 'The note could not be committed.', 'submission-inbox' ) );
		}

		$note_snapshot = array(
			'id'           => $note_id,
			'lead_id'      => $lead_id,
			'user_id'      => $user_id,
			'note'         => $note,
			'note_version' => 1,
			'sync_footprint' => false,
			'created_at'   => $now,
			'updated_at'   => $now,
		);
		do_action( 'subin_lead_note_added', $lead_id, $note_id, $note_snapshot );

		return $note_id;
	}

	/**
	 * Add an activity entry.
	 *
	 * @param int                 $lead_id Lead id.
	 * @param string              $type Activity type.
	 * @param string              $message Activity message.
	 * @param array<string,mixed> $metadata Metadata.
	 * @param int                 $actor_user_id Actor user id.
	 * @return int
	 */
	public function add_activity( $lead_id, $type, $message, array $metadata = array(), $actor_user_id = 0 ) {
		global $wpdb;

		$lead_id = absint( $lead_id );
		if ( $lead_id <= 0 ) {
			return 0;
		}
		if ( false === $wpdb->query( 'START TRANSACTION' ) ) {
			return 0;
		}
		if ( is_wp_error( $this->lock_parent_lead( $lead_id ) ) ) {
			$wpdb->query( 'ROLLBACK' );

			return 0;
		}

		$activity_id = $this->insert_activity_row( $lead_id, $type, $message, $metadata, $actor_user_id );
		if ( $activity_id <= 0 ) {
			$wpdb->query( 'ROLLBACK' );

			return 0;
		}

		$projected   = $wpdb->update(
			$wpdb->prefix . 'subin_leads',
			array( 'last_activity_at' => current_time( 'mysql' ) ),
			array( 'id' => $lead_id ),
			array( '%s' ),
			array( '%d' )
		);
		if ( false === $projected ) {
			$wpdb->query( 'ROLLBACK' );

			return 0;
		}
		if ( false === $wpdb->query( 'COMMIT' ) ) {
			$wpdb->query( 'ROLLBACK' );

			return 0;
		}

		return $activity_id;
	}

	/**
	 * Insert an activity row inside a transaction whose parent lead is locked.
	 *
	 * @param int                 $lead_id Lead id.
	 * @param string              $type Activity type.
	 * @param string              $message Activity message.
	 * @param array<string,mixed> $metadata Metadata.
	 * @param int                 $actor_user_id Actor user id.
	 * @return int
	 */
	private function insert_activity_row( $lead_id, $type, $message, array $metadata = array(), $actor_user_id = 0 ) {
		global $wpdb;

		$metadata_json = wp_json_encode( $metadata );
		$inserted      = $wpdb->insert(
			$wpdb->prefix . 'subin_lead_activity',
			array(
				'lead_id'          => absint( $lead_id ),
				'actor_user_id'    => absint( $actor_user_id ),
				'activity_type'    => sanitize_key( (string) $type ),
				'activity_message' => sanitize_text_field( (string) $message ),
				'metadata_json'    => is_string( $metadata_json ) ? $metadata_json : '',
				'created_at'       => current_time( 'mysql' ),
			),
			array( '%d', '%d', '%s', '%s', '%s', '%s' )
		);

		return $inserted ? absint( $wpdb->insert_id ) : 0;
	}

	/**
	 * Get notes for a lead.
	 *
	 * @param int $lead_id Lead id.
	 * @return array<int,object>
	 */
	public function get_notes( $lead_id ) {
		global $wpdb;

		return $wpdb->get_results(
			$wpdb->prepare(
				"SELECT notes.*, users.display_name
				FROM {$wpdb->prefix}subin_lead_notes notes
				LEFT JOIN {$wpdb->users} users ON users.ID = notes.user_id
				WHERE notes.lead_id = %d
				ORDER BY notes.created_at DESC, notes.id DESC",
				absint( $lead_id )
			)
		);
	}

	/**
	 * Update a single lead note.
	 *
	 * @param int    $note_id Note id.
	 * @param int    $lead_id Lead id.
	 * @param string $note Note text.
	 * @param int    $user_id User id.
	 * @return bool
	 */
	public function update_note( $note_id, $lead_id, $note, $user_id = 0 ) {
		$result = $this->persist_note_update( $note_id, $lead_id, $note, null, $user_id );

		return true === $result;
	}

	/**
	 * Update a note only when the editor still has its current version.
	 *
	 * @param int    $note_id Note id.
	 * @param int    $lead_id Lead id.
	 * @param string $note Note text.
	 * @param mixed  $expected_version Version rendered with the editor.
	 * @param int    $user_id User id.
	 * @return true|\WP_Error
	 */
	public function update_note_if_current( $note_id, $lead_id, $note, $expected_version, $user_id = 0 ) {
		$expected_version = $this->validate_note_version( $expected_version );
		if ( is_wp_error( $expected_version ) ) {
			return $expected_version;
		}

		return $this->persist_note_update( $note_id, $lead_id, $note, $expected_version, $user_id );
	}

	/**
	 * Validate, lock, and atomically update a note with its activity row.
	 *
	 * @param int      $note_id Note id.
	 * @param int      $lead_id Lead id.
	 * @param string   $note Note text.
	 * @param int|null $expected_version Expected note version for an editor.
	 * @param int      $user_id User id.
	 * @return true|\WP_Error
	 */
	private function persist_note_update( $note_id, $lead_id, $note, $expected_version, $user_id ) {
		global $wpdb;

		$note_id = absint( $note_id );
		$lead_id = absint( $lead_id );
		$user_id = absint( $user_id );
		if ( $note_id <= 0 || $lead_id <= 0 ) {
			return new \WP_Error( 'subin_note_id_invalid', __( 'A valid lead and note are required.', 'submission-inbox' ) );
		}
		$note = $this->validate_note_text( $note );
		if ( is_wp_error( $note ) ) {
			return $note;
		}
		if ( false === $wpdb->query( 'START TRANSACTION' ) ) {
			return new \WP_Error( 'subin_note_transaction_failed', __( 'The note transaction could not start.', 'submission-inbox' ) );
		}

		$parent_locked = $this->lock_parent_lead( $lead_id );
		if ( is_wp_error( $parent_locked ) ) {
			$wpdb->query( 'ROLLBACK' );

			return $parent_locked;
		}
		$existing = $this->lock_note( $note_id, $lead_id );
		if ( is_wp_error( $existing ) ) {
			$wpdb->query( 'ROLLBACK' );

			return $existing;
		}
		if ( ! $existing ) {
			$wpdb->query( 'ROLLBACK' );

			return null !== $expected_version
				? $this->note_conflict_error( 0, 'missing' )
				: new \WP_Error( 'subin_note_missing', __( 'The note no longer exists.', 'submission-inbox' ) );
		}

		$current_version = max( 1, absint( $existing->note_version ?? 1 ) );
		if ( null !== $expected_version && $expected_version !== $current_version ) {
			$wpdb->query( 'ROLLBACK' );

			return $this->note_conflict_error( $current_version );
		}
		if ( (string) ( $existing->note ?? '' ) === $note ) {
			$wpdb->query( 'ROLLBACK' );

			return true;
		}

		$now     = current_time( 'mysql' );
		$updated = $wpdb->query(
			$wpdb->prepare(
				"UPDATE {$wpdb->prefix}subin_lead_notes
				SET note = %s, updated_at = %s, note_version = note_version + 1
				WHERE id = %d AND lead_id = %d AND note_version = %d",
				$note,
				$now,
				$note_id,
				$lead_id,
				$current_version
			)
		);
		if ( false === $updated ) {
			return $this->rollback_error( 'subin_note_update_failed', __( 'The note could not be updated.', 'submission-inbox' ) );
		}
		if ( 0 === $updated ) {
			$wpdb->query( 'ROLLBACK' );

			return $this->note_conflict_error( $current_version );
		}

		$next_version = $current_version + 1;
			$activity_id  = $this->insert_activity_row(
			$lead_id,
			'note_updated',
			__( 'Note updated.', 'submission-inbox' ),
			array(
				'note_id'      => $note_id,
				'from_version' => $current_version,
				'to_version'   => $next_version,
			),
			$user_id
		);
		if ( $activity_id <= 0 ) {
			return $this->rollback_error( 'subin_note_activity_failed', __( 'The note activity could not be recorded.', 'submission-inbox' ) );
		}
		if ( ! $this->touch_lead( $lead_id, $now ) ) {
			return $this->rollback_error( 'subin_note_lead_update_failed', __( 'The lead could not be updated with the note.', 'submission-inbox' ) );
		}
		if ( false === $wpdb->query( 'COMMIT' ) ) {
			return $this->rollback_error( 'subin_note_commit_failed', __( 'The note could not be committed.', 'submission-inbox' ) );
		}

		$note_snapshot = array(
			'id'           => $note_id,
			'lead_id'      => $lead_id,
			'user_id'      => absint( $existing->user_id ?? 0 ),
			'note'         => $note,
			'note_version' => $next_version,
			'sync_footprint' => ! empty( $existing->sync_footprint ),
			'created_at'   => sanitize_text_field( (string) ( $existing->created_at ?? '' ) ),
			'updated_at'   => $now,
		);
		do_action( 'subin_lead_note_updated', $lead_id, $note_id, $note_snapshot );

		return true;
	}

	/**
	 * Delete a single lead note.
	 *
	 * @param int $note_id Note id.
	 * @param int $lead_id Lead id.
	 * @param int $user_id User id.
	 * @return bool
	 */
	public function delete_note( $note_id, $lead_id, $user_id = 0 ) {
		$result = $this->persist_note_delete( $note_id, $lead_id, null, $user_id );

		return true === $result;
	}

	/**
	 * Delete a note only when the editor still has its current version.
	 *
	 * @param int   $note_id Note id.
	 * @param int   $lead_id Lead id.
	 * @param mixed $expected_version Version rendered with the editor.
	 * @param int   $user_id User id.
	 * @return true|\WP_Error
	 */
	public function delete_note_if_current( $note_id, $lead_id, $expected_version, $user_id = 0 ) {
		$expected_version = $this->validate_note_version( $expected_version );
		if ( is_wp_error( $expected_version ) ) {
			return $expected_version;
		}

		return $this->persist_note_delete( $note_id, $lead_id, $expected_version, $user_id );
	}

	/**
	 * Lock and atomically delete a note with a versioned tombstone activity.
	 *
	 * @param int      $note_id Note id.
	 * @param int      $lead_id Lead id.
	 * @param int|null $expected_version Expected note version for an editor.
	 * @param int      $user_id User id.
	 * @return true|\WP_Error
	 */
	private function persist_note_delete( $note_id, $lead_id, $expected_version, $user_id ) {
		global $wpdb;

		$note_id = absint( $note_id );
		$lead_id = absint( $lead_id );
		$user_id = absint( $user_id );
		if ( $note_id <= 0 || $lead_id <= 0 ) {
			return new \WP_Error( 'subin_note_id_invalid', __( 'A valid lead and note are required.', 'submission-inbox' ) );
		}
		if ( false === $wpdb->query( 'START TRANSACTION' ) ) {
			return new \WP_Error( 'subin_note_transaction_failed', __( 'The note transaction could not start.', 'submission-inbox' ) );
		}

		$parent_locked = $this->lock_parent_lead( $lead_id );
		if ( is_wp_error( $parent_locked ) ) {
			$wpdb->query( 'ROLLBACK' );

			return $parent_locked;
		}
		$existing = $this->lock_note( $note_id, $lead_id );
		if ( is_wp_error( $existing ) ) {
			$wpdb->query( 'ROLLBACK' );

			return $existing;
		}
		if ( ! $existing ) {
			$wpdb->query( 'ROLLBACK' );

			return null !== $expected_version
				? $this->note_conflict_error( 0, 'missing' )
				: new \WP_Error( 'subin_note_missing', __( 'The note no longer exists.', 'submission-inbox' ) );
		}

		$current_version = max( 1, absint( $existing->note_version ?? 1 ) );
		if ( null !== $expected_version && $expected_version !== $current_version ) {
			$wpdb->query( 'ROLLBACK' );

			return $this->note_conflict_error( $current_version );
		}

		$deleted = $wpdb->query(
			$wpdb->prepare(
				"DELETE FROM {$wpdb->prefix}subin_lead_notes
				WHERE id = %d AND lead_id = %d AND note_version = %d",
				$note_id,
				$lead_id,
				$current_version
			)
		);
		if ( false === $deleted ) {
			return $this->rollback_error( 'subin_note_delete_failed', __( 'The note could not be deleted.', 'submission-inbox' ) );
		}
		if ( 0 === $deleted ) {
			$wpdb->query( 'ROLLBACK' );

			return $this->note_conflict_error( $current_version );
		}

		$tombstone_version = $current_version + 1;
		$activity_id       = $this->insert_activity_row(
			$lead_id,
			'note_deleted',
			__( 'Note deleted.', 'submission-inbox' ),
			array(
				'note_id'      => $note_id,
				'from_version' => $current_version,
				'to_version'   => $tombstone_version,
			),
			$user_id
		);
		if ( $activity_id <= 0 ) {
			return $this->rollback_error( 'subin_note_activity_failed', __( 'The note activity could not be recorded.', 'submission-inbox' ) );
		}
		$deleted_at = current_time( 'mysql' );
		if ( ! $this->touch_lead( $lead_id, $deleted_at ) ) {
			return $this->rollback_error( 'subin_note_lead_update_failed', __( 'The lead could not be updated after deleting the note.', 'submission-inbox' ) );
		}
		$note_snapshot = array(
			'id'             => $note_id,
			'lead_id'        => $lead_id,
			'note_version'   => $tombstone_version,
			'sync_footprint' => ! empty( $existing->sync_footprint ),
			'deleted'        => true,
			'created_at'     => sanitize_text_field( (string) ( $existing->created_at ?? '' ) ),
			'updated_at'     => $deleted_at,
			'deleted_at'     => $deleted_at,
		);
		if ( class_exists( '\SUBIN\Sync\SyncEventRepository' ) ) {
			$settings = class_exists( '\SUBIN_SettingsRepository' ) ? ( new \SUBIN_SettingsRepository() )->all() : array();
			$sync_payload = array(
				'lead' => array( 'id' => $lead_id ),
				'note' => array(
					'id'             => $note_id,
					'note_version'   => $tombstone_version,
					'deleted'        => true,
					'sync_footprint' => ! empty( $existing->sync_footprint ),
					'created_at'     => $note_snapshot['created_at'],
					'updated_at'     => $deleted_at,
				),
			);
			$sync_result = ( new \SUBIN\Sync\SyncEventRepository() )->stage_note_delete_in_transaction(
				$lead_id,
				$sync_payload,
				! empty( $settings['cloud_sync_enabled'] )
			);
			if ( is_wp_error( $sync_result ) ) {
				return $this->rollback_error( 'subin_note_sync_cleanup_failed', __( 'The note could not be deleted safely from sync history.', 'submission-inbox' ) );
			}
		}
		if ( false === $wpdb->query( 'COMMIT' ) ) {
			return $this->rollback_error( 'subin_note_commit_failed', __( 'The note deletion could not be committed.', 'submission-inbox' ) );
		}

		do_action( 'subin_lead_note_deleted', $lead_id, $note_id, $note_snapshot );

		return true;
	}

	/**
	 * Validate note input before opening a database transaction.
	 *
	 * @param mixed $note Raw note value.
	 * @return string|\WP_Error
	 */
	private function validate_note_text( $note ) {
		if ( ! is_string( $note ) ) {
			return new \WP_Error( 'subin_note_value_invalid', __( 'The note text is invalid.', 'submission-inbox' ) );
		}
		if ( $this->note_length( $note ) > self::MAX_NOTE_LENGTH ) {
			return new \WP_Error(
				'subin_note_too_long',
				sprintf(
					/* translators: %d: maximum note length. */
					__( 'Notes can contain at most %d characters.', 'submission-inbox' ),
					self::MAX_NOTE_LENGTH
				)
			);
		}

		$note = sanitize_textarea_field( $note );
		if ( '' === trim( $note ) ) {
			return new \WP_Error( 'subin_note_value_invalid', __( 'Enter a note before saving.', 'submission-inbox' ) );
		}

		return $note;
	}

	/**
	 * Validate a browser-rendered note version.
	 *
	 * @param mixed $version Raw version.
	 * @return int|\WP_Error
	 */
	private function validate_note_version( $version ) {
		if ( ( ! is_int( $version ) && ! is_string( $version ) ) || 1 !== preg_match( '/^[1-9]\d*$/', (string) $version ) ) {
			return new \WP_Error(
				'subin_note_version_invalid',
				__( 'The note version is missing or invalid. Refresh the lead and try again.', 'submission-inbox' )
			);
		}

		return absint( $version );
	}

	/**
	 * Lock a parent lead so note creation and retention use the same lock order.
	 *
	 * @param int $lead_id Lead id.
	 * @return true|\WP_Error
	 */
	private function lock_parent_lead( $lead_id ) {
		global $wpdb;

		$lead_id = absint( $lead_id );
		$wpdb->last_error = '';
		$locked_lead_id   = $wpdb->get_var(
			$wpdb->prepare(
				"SELECT id FROM {$wpdb->prefix}subin_leads WHERE id = %d LIMIT 1 FOR UPDATE",
				$lead_id
			)
		);
		if ( '' !== (string) $wpdb->last_error ) {
			return new \WP_Error( 'subin_note_parent_lock_failed', __( 'The lead could not be locked for this note.', 'submission-inbox' ) );
		}
		if ( $lead_id !== absint( $locked_lead_id ) ) {
			return new \WP_Error( 'subin_note_lead_missing', __( 'The lead no longer exists.', 'submission-inbox' ) );
		}

		return true;
	}

	/**
	 * Lock and read one note belonging to an already locked lead.
	 *
	 * @param int $note_id Note id.
	 * @param int $lead_id Lead id.
	 * @return object|null|\WP_Error
	 */
	private function lock_note( $note_id, $lead_id ) {
		global $wpdb;

		$wpdb->last_error = '';
		$note             = $wpdb->get_row(
			$wpdb->prepare(
				"SELECT * FROM {$wpdb->prefix}subin_lead_notes
				WHERE id = %d AND lead_id = %d
				LIMIT 1 FOR UPDATE",
				absint( $note_id ),
				absint( $lead_id )
			)
		);
		if ( '' !== (string) $wpdb->last_error ) {
			return new \WP_Error( 'subin_note_lock_failed', __( 'The note could not be locked for editing.', 'submission-inbox' ) );
		}

		return $note;
	}

	/**
	 * Advance the lead cursor after a committed note mutation.
	 *
	 * @param int    $lead_id Lead id.
	 * @param string $updated_at Mutation timestamp.
	 * @return bool
	 */
	private function touch_lead( $lead_id, $updated_at ) {
		global $wpdb;

		return false !== $wpdb->update(
			$wpdb->prefix . 'subin_leads',
			array(
				'updated_at'       => sanitize_text_field( (string) $updated_at ),
				'last_activity_at' => sanitize_text_field( (string) $updated_at ),
			),
			array( 'id' => absint( $lead_id ) ),
			array( '%s', '%s' ),
			array( '%d' )
		);
	}

	/**
	 * Roll back an open note transaction and return a stable error.
	 *
	 * @param string $code Error code.
	 * @param string $message Error message.
	 * @return \WP_Error
	 */
	private function rollback_error( $code, $message ) {
		global $wpdb;

		$wpdb->query( 'ROLLBACK' );

		return new \WP_Error( sanitize_key( (string) $code ), (string) $message );
	}

	/**
	 * Build a stable note edit/delete conflict.
	 *
	 * @param int    $current_version Current stored version, or zero when removed.
	 * @param string $reason Conflict reason.
	 * @return \WP_Error
	 */
	private function note_conflict_error( $current_version, $reason = 'changed' ) {
		return new \WP_Error(
			'subin_note_conflict',
			__( 'This note changed or was removed after you opened it.', 'submission-inbox' ),
			array(
				'current_version' => absint( $current_version ),
				'reason'          => sanitize_key( (string) $reason ),
			)
		);
	}

	/**
	 * Count note characters with a safe fallback when mbstring is unavailable.
	 *
	 * @param string $note Note text.
	 * @return int
	 */
	private function note_length( $note ) {
		return function_exists( 'mb_strlen' ) ? mb_strlen( $note, 'UTF-8' ) : strlen( $note );
	}

	/**
	 * Get activity timeline for a lead.
	 *
	 * @param int $lead_id Lead id.
	 * @param int $limit Maximum rows.
	 * @return array<int,object>
	 */
	public function get_timeline( $lead_id, $limit = 50 ) {
		global $wpdb;

		return $wpdb->get_results(
			$wpdb->prepare(
				"SELECT activity.*, users.display_name
				FROM {$wpdb->prefix}subin_lead_activity activity
				LEFT JOIN {$wpdb->users} users ON users.ID = activity.actor_user_id
				WHERE activity.lead_id = %d
				ORDER BY activity.created_at DESC, activity.id DESC
				LIMIT %d",
				absint( $lead_id ),
				max( 1, min( 100, absint( $limit ) ) )
			)
		);
	}

	/**
	 * Delete workflow rows for a lead.
	 *
	 * @param int $lead_id Lead id.
	 * @return void
	 */
	public function delete_by_lead_id( $lead_id ) {
		global $wpdb;

		$lead_id = absint( $lead_id );
		if ( $lead_id <= 0 ) {
			return;
		}

		$wpdb->delete( $wpdb->prefix . 'subin_lead_notes', array( 'lead_id' => $lead_id ), array( '%d' ) );
		$wpdb->delete( $wpdb->prefix . 'subin_lead_activity', array( 'lead_id' => $lead_id ), array( '%d' ) );
	}
}
