<?php
if (!defined('ABSPATH')) {
    exit;
}

/**
 * Service for handling business logic of notifications (who to email, when, and checking user preferences).
 */
class EEP_Notification_Service {

    /**
     * @var EEP_Email_Service
     */
    private $email_service;

    /**
     * @var EEP_Date_Helper
     */
    private $date_helper;

    /**
     * Constructor.
     *
     * @param EEP_Email_Service $email_service Service for rendering and sending emails.
     * @param EEP_Date_Helper   $date_helper   Service for formatting dates in emails.
     */
    public function __construct($email_service, $date_helper) {
        $this->email_service = $email_service;
        $this->date_helper = $date_helper;
    }

    /**
     * Checks if a specific notification toggle is enabled in the platform settings.
     */
    public function is_notification_toggle_enabled($option_key, $default = '1', $compat_option = '') {
        $value = get_option($option_key, null);

        if ($value === null || $value === false || $value === '') {
            $value = $default;
        }
        
        return (string) $value === '1';
    }

    /**
     * Translates an internal post status to a human-readable badge/label for emails.
     */
    public function event_status_badge($status) {
        $labels = [
            'pending' => __('Pending Review', 'nexdirectory'),
            'publish' => __('Published', 'nexdirectory'),
            'draft'   => __('Draft', 'nexdirectory'),
            'trash'   => __('Deleted', 'nexdirectory'),
        ];

        return $labels[$status] ?? ucfirst($status);
    }

    /**
     * Notifies the platform administrator when a new listing is submitted and pending review.
     */
    public function notify_admin_submission($post_id) {
        $admin_email = get_option('admin_email');
        $post = get_post($post_id);
        
        if (!$post || !$admin_email) {
            return;
        }

        // Prevent duplicate emails for the same post entering pending status multiple times
        if (get_post_meta((int) $post_id, 'eep_admin_pending_notified', true) === '1') {
            return;
        }

        $pending_link = admin_url('admin.php?page=eep-moderation');
        $subject = sprintf(__('New event pending review: %s', 'nexdirectory'), $post->post_title);
        
        $fallback_text = sprintf(
            "A new event is waiting for review.\n\nTitle: %s\nAuthor: %s\nEdit: %s",
            $post->post_title,
            get_the_author_meta('user_email', (int) $post->post_author),
            admin_url('post.php?post=' . $post_id . '&action=edit')
        );
        $fallback_text .= "\nModeration Queue: " . $pending_link;

        $this->email_service->send_platform_email($admin_email, $subject, '', [
            'fallback_text' => $fallback_text,
        ]);

        update_post_meta((int) $post_id, 'eep_admin_pending_notified', '1');
    }

    /**
     * Notifies the listing author when their listing's moderation status changes.
     */
    public function notify_author_status($post_id, $status, $note = '') {
        $post = get_post($post_id);
        if (!$post) {
            return;
        }
        
        $author = get_user_by('id', (int) $post->post_author);
        if (!$author) {
            return;
        }

        // Check platform toggles based on the specific status transition
        if ($status === 'pending' && !$this->is_notification_toggle_enabled('eep_notify_author_confirmation', '1')) {
            return;
        }
        if ($status === 'publish' && !$this->is_notification_toggle_enabled('eep_notify_author_update', '1')) {
            return;
        }
        if ($status !== 'pending' && $status !== 'publish' && !$this->is_notification_toggle_enabled('eep_notify_author_cancellation', '1')) {
            return;
        }

        $status_label = $this->event_status_badge($status);
        $subject_default = sprintf(__('Your event status changed: %s', 'nexdirectory'), $post->post_title);
        $allow_event_template_override = (string) get_option('eep_enable_per_event_email_templates', '0') === '1';
        
        $subject_option = '';
        $body_option = '';
        $template_name = '';

        if ($status === 'pending') {
            $subject_option = $allow_event_template_override ? (string) get_post_meta($post_id, 'eep_email_subject_confirmation', true) : '';
            if ($subject_option === '') {
                $subject_option = (string) get_option('eep_email_subject_confirmation', $this->email_service->get_default_event_email_template_value('eep_email_subject_confirmation'));
            }
            $body_option = $allow_event_template_override ? (string) get_post_meta($post_id, 'eep_email_body_confirmation', true) : '';
            if ($body_option === '') {
                $body_option = (string) get_option('eep_email_body_confirmation', $this->email_service->get_default_event_email_template_value('eep_email_body_confirmation'));
            }
            $template_name = 'confirmation.php';
            
        } elseif ($status === 'publish') {
            $subject_option = $allow_event_template_override ? (string) get_post_meta($post_id, 'eep_email_subject_update', true) : '';
            if ($subject_option === '') {
                $subject_option = (string) get_option('eep_email_subject_update', $this->email_service->get_default_event_email_template_value('eep_email_subject_update'));
            }
            $body_option = $allow_event_template_override ? (string) get_post_meta($post_id, 'eep_email_body_update', true) : '';
            if ($body_option === '') {
                $body_option = (string) get_option('eep_email_body_update', $this->email_service->get_default_event_email_template_value('eep_email_body_update'));
            }
            $template_name = 'update.php';
            
        } else {
            $subject_option = $allow_event_template_override ? (string) get_post_meta($post_id, 'eep_email_subject_cancellation', true) : '';
            if ($subject_option === '') {
                $subject_option = (string) get_option('eep_email_subject_cancellation', $this->email_service->get_default_event_email_template_value('eep_email_subject_cancellation'));
            }
            $body_option = $allow_event_template_override ? (string) get_post_meta($post_id, 'eep_email_body_cancellation', true) : '';
            if ($body_option === '') {
                $body_option = (string) get_option('eep_email_body_cancellation', $this->email_service->get_default_event_email_template_value('eep_email_body_cancellation'));
            }
            $template_name = 'cancellation.php';
        }

        $rendered_subject = trim((string) $this->email_service->render_event_email_subject($subject_option, $post_id, (string) $status_label));
        $subject = $rendered_subject !== '' ? $rendered_subject : $subject_default;
        
        $custom_body_html = $this->email_service->render_event_email_body($body_option, $post_id, (string) $status_label, (string) $note);
        
        $fallback_text = sprintf(
            "Status: %s\nEvent: %s\nLink: %s\n\nModerator note: %s",
            $status_label,
            $post->post_title,
            get_permalink($post_id),
            $note ? $note : __('No note provided.', 'nexdirectory')
        );

        $this->email_service->send_platform_email($author->user_email, $subject, $template_name, [
            'user'             => $author,
            'post_id'          => $post_id,
            'event_title'      => get_the_title($post_id),
            'event_date'       => $this->date_helper->format_event_date($post_id),
            'event_url'        => get_permalink($post_id),
            'status_label'     => $status_label,
            'moderator_note'   => $note,
            'custom_body_html' => $custom_body_html,
            'fallback_text'    => $fallback_text,
        ]);
    }

    /**
     * Sends an email verification link to a user.
     */
    public function send_verification_email($user_id) {
        $user = get_user_by('id', (int) $user_id);
        if (!$user) {
            return false;
        }

        $token = wp_generate_password(48, false, false);
        update_user_meta($user_id, 'eep_email_verify_token', $token);
        update_user_meta($user_id, 'eep_email_verify_expires', (string) (time() + 2 * DAY_IN_SECONDS));

        $verify_url = eep_add_query_arg([
            'eep_verify_email' => (int) $user_id,
            'token'            => rawurlencode($token),
        ], home_url('/'));
        
        $subject = __('Verify your email before first event submission', 'nexdirectory');
        $fallback = sprintf(
            "Hi %s,\n\nPlease verify your email to enable your first event submission:\n%s\n\nThis link expires in 48 hours.",
            $user->display_name ?: $user->user_login,
            $verify_url
        );
        
        return $this->email_service->send_platform_email($user->user_email, $subject, 'verification.php', [
            'user'          => $user,
            'verify_url'    => $verify_url,
            'expires_label' => __('48 hours', 'nexdirectory'),
            'fallback_text' => $fallback,
        ]);
    }
}
