<?php
/**
 * Lead email status service.
 *
 * @package SubmissionInbox
 */

namespace SUBIN\Mail;

use SUBIN\Leads\LeadRepository;
use SUBIN\MailLog\MailEventRepository;

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

/**
 * Derives lead email status from related mail events.
 */
class LeadEmailStatusService {
	/**
	 * Lead repository.
	 *
	 * @var LeadRepository
	 */
	private $leads;

	/**
	 * Mail event repository.
	 *
	 * @var MailEventRepository
	 */
	private $events;

	/**
	 * Constructor.
	 *
	 * @param LeadRepository|null      $leads Leads.
	 * @param MailEventRepository|null $events Events.
	 */
	public function __construct( ?LeadRepository $leads = null, ?MailEventRepository $events = null ) {
		$this->leads  = $leads ? $leads : new LeadRepository();
		$this->events = $events ? $events : new MailEventRepository();
	}

	/**
	 * Recalculate and persist a lead email status.
	 *
	 * @param int    $lead_id Lead id.
	 * @param string $fallback Fallback status.
	 * @return string
	 */
	public function recalculate( $lead_id, $fallback = LeadRepository::EMAIL_STATUS_UNKNOWN ) {
		$status = $this->derive_status( $lead_id, $fallback );
		$this->leads->update_email_status( $lead_id, $status );

		return $status;
	}

	/**
	 * Derive status from related events.
	 *
	 * @param int    $lead_id Lead id.
	 * @param string $fallback Fallback.
	 * @return string
	 */
	public function derive_status( $lead_id, $fallback = LeadRepository::EMAIL_STATUS_UNKNOWN ) {
		$has_sent = false;
		foreach ( $this->events->get_by_lead_id( $lead_id ) as $event ) {
			$status = sanitize_key( $event->status ?? '' );
			if ( MailEventRepository::STATUS_FAILED === $status ) {
				return LeadRepository::EMAIL_STATUS_FAILED;
			}
			if ( MailEventRepository::STATUS_NO_EMAIL_GENERATED === $status ) {
				return LeadRepository::EMAIL_STATUS_NO_EMAIL_GENERATED;
			}
			if ( MailEventRepository::STATUS_SENT === $status ) {
				$has_sent = true;
			}
		}

		return $has_sent ? LeadRepository::EMAIL_STATUS_SENT : $fallback;
	}
}
