<?php
namespace TCB\Admin;
use TCB\DB\{BookingsDAO, PartnersDAO};
use TCA\DB\SpeakersDAO;
if ( ! defined( 'ABSPATH' ) ) { exit; }

class EmailEngine {

    private static function notification_cc_emails( string $to = '' ): array {
        $raw = (string) get_option( 'tcb_email_cc_recipients', 'fmushtaq@gmail.com' );
        $raw = apply_filters( 'tc_notification_cc_emails', $raw, $to );
        $to_email = strtolower( sanitize_email( $to ) );
        $emails = [];

        foreach ( preg_split( '/[,;\s]+/', (string) $raw ) as $candidate ) {
            $email = sanitize_email( trim( (string) $candidate ) );
            $key = strtolower( $email );
            if ( ! $email || ! is_email( $email ) || $key === $to_email || isset( $emails[ $key ] ) ) {
                continue;
            }
            $emails[ $key ] = $email;
        }

        return array_values( $emails );
    }

    private static function custom_from_email(): string {
        if ( get_option( 'tcb_email_use_default_sender', 'yes' ) === 'yes' ) {
            return '';
        }
        $email = sanitize_email( (string) get_option( 'tcb_email_custom_sender', '' ) );
        return is_email( $email ) ? $email : '';
    }

    public static function custom_mail_from( string $from ): string {
        $custom = self::custom_from_email();
        return $custom ?: $from;
    }

    private static function mail_headers( string $to = '' ): array {
        $headers = [ 'Content-Type: text/html; charset=UTF-8' ];
        foreach ( self::notification_cc_emails( $to ) as $cc_email ) {
            $headers[] = 'Cc: ' . $cc_email;
        }
        return $headers;
    }


    private static function send_mail( string $to, string $subject, string $body ): bool {
        if ( ! is_email( $to ) ) { return false; }
        $subject = wp_strip_all_tags( $subject );
        $custom_from = self::custom_from_email();
        add_filter( 'wp_mail_content_type', [ self::class, 'html_content_type' ] );
        if ( $custom_from ) {
            add_filter( 'wp_mail_from', [ self::class, 'custom_mail_from' ] );
        }
        $sent = wp_mail( $to, $subject, $body, self::mail_headers( $to ) );
        if ( ! $sent ) { update_option( 'tc_last_mail_error', 'wp_mail returned false for ' . sanitize_email( $to ) . ' at ' . current_time( 'mysql' ), false ); }
        if ( $custom_from ) {
            remove_filter( 'wp_mail_from', [ self::class, 'custom_mail_from' ] );
        }
        remove_filter( 'wp_mail_content_type', [ self::class, 'html_content_type' ] );
        return (bool) $sent;
    }

    public static function html_content_type(): string { return 'text/html'; }

    private static function replace_tokens( string $text, array $tokens ): string {
        foreach ( $tokens as $key => $value ) { $text = str_replace( '{' . $key . '}', (string) $value, $text ); }
        return $text;
    }

    private static function slot_tokens( array $slot, array $partner, array $speaker ): array {
        $speaker_profile_url = '';
        if ( ! empty( $speaker['profile_url'] ) ) {
            $speaker_profile_url = (string) $speaker['profile_url'];
        } elseif ( ! empty( $speaker['slug'] ) ) {
            $speaker_profile_url = home_url( '/speaker/' . sanitize_title( (string) $speaker['slug'] ) . '/' );
        } elseif ( ! empty( $speaker['name'] ) ) {
            $speaker_profile_url = home_url( '/speaker/' . sanitize_title( (string) $speaker['name'] ) . '/' );
        }
        return [
            'site_name' => wp_specialchars_decode( get_bloginfo('name'), ENT_QUOTES ),
            'partner_name' => $partner['name'] ?? '', 'partner_email' => $partner['email'] ?? '',
            'speaker_name' => $speaker['name'] ?? '', 'speaker_email' => $speaker['email'] ?? '', 'speaker_company' => $speaker['company'] ?? '', 'speaker_position' => $speaker['position'] ?? '',
            'speaker_profile_url' => $speaker_profile_url,
            'slot_date' => ! empty( $slot['slot_date'] ) ? date( 'l, F j, Y', strtotime( $slot['slot_date'] ) ) : '',
            'slot_time' => ( ! empty( $slot['time_start'] ) ? date( 'g:i A', strtotime( $slot['time_start'] ) ) : '' ) . ' - ' . ( ! empty( $slot['time_end'] ) ? date( 'g:i A', strtotime( $slot['time_end'] ) ) : '' ),
            'room' => $slot['room'] ?? '', 'partner_dashboard_url' => home_url('/partner-dashboard/'), 'speaker_dashboard_url' => home_url('/speaker-dashboard/'), 'booking_url' => ! empty( $partner['slug'] ) ? home_url('/book/' . $partner['slug'] . '/') : home_url('/booking/')
        ];
    }

    /**
     * Sends immediate email to the Media Partner when a speaker books a slot.
     */
    public static function send_request_notification( int $slot_id, int $speaker_id ): bool {
        $slot    = BookingsDAO::get_slot( $slot_id );
        if ( ! $slot ) return false;
        
        $partner = PartnersDAO::get_by_id( (int)$slot['partner_id'] );
        // Require Agenda Pro classes (enforced in main plugin file)
        $speaker = \TCA\DB\SpeakersDAO::get_by_id( $speaker_id );
        
        if ( ! $partner || ! $speaker || empty( $partner['email'] ) ) return false;

        $to      = $partner['email'];
        $tokens  = self::slot_tokens( $slot, $partner, $speaker );
        $subject = self::replace_tokens( get_option( 'tcb_email_request_subject', 'New Interview Request: {speaker_name}' ), $tokens );
        
        $time_fmt = date( 'g:i A', strtotime( $slot['time_start'] ) ) . ' - ' . date( 'g:i A', strtotime( $slot['time_end'] ) );
        $date_fmt = date( 'l, F j, Y', strtotime( $slot['slot_date'] ) );

        $mode = get_option( 'tcb_booking_mode', 'simple' );
        $partner_instruction = $mode === 'simple'
            ? "<p>This request is shared for your review. Please contact the speaker directly if you would like to move forward.</p><p><strong>Speaker Email:</strong> {$speaker['email']}</p>"
            : "<p>Please log in to your dashboard to <strong>Approve</strong> or <strong>Decline</strong> this request.</p>";

        $body = self::get_base_template(
            "New Interview Request",
            "<p>Hello <strong>{$partner['name']}</strong>,</p>
            <p><strong>{$speaker['name']}</strong> ({$speaker['company']}) has requested an interview slot.</p>
            <div style='background:#f1f5f9;padding:15px;border-radius:8px;margin:20px 0;color:#0f172a;'>
                <strong>Speaker:</strong> {$speaker['name']}<br>
                <strong>Email:</strong> {$speaker['email']}<br>
                <strong>Title:</strong> {$speaker['position']}<br>
                <strong>Company:</strong> {$speaker['company']}<br>
                <strong>Public Profile:</strong> <a href='{$tokens['speaker_profile_url']}'>{$tokens['speaker_profile_url']}</a><br>
                <strong>Date:</strong> {$date_fmt}<br>
                <strong>Time:</strong> {$time_fmt}<br>
                <strong>Room:</strong> {$slot['room']}<br>
            </div>
            {$partner_instruction}
            <a href='" . home_url('/partner-dashboard/') . "' style='display:inline-block;padding:12px 24px;background:#e61a84;color:#fff;text-decoration:none;border-radius:6px;font-weight:bold;margin-top:10px;'>Go to Dashboard</a>"
        );

        if ( $custom = get_option( 'tcb_email_request_template', '' ) ) { $body = self::replace_tokens( $custom, $tokens ); }
        return self::send_mail( $to, $subject, $body );
    }


    /**
     * Sends confirmation email to the speaker after a simple/advanced request is submitted.
     */
    public static function send_speaker_request_confirmation( int $slot_id, int $speaker_id ): bool {
        $slot = BookingsDAO::get_slot( $slot_id );
        if ( ! $slot ) return false;
        $partner = PartnersDAO::get_by_id( (int) $slot['partner_id'] );
        $speaker = \TCA\DB\SpeakersDAO::get_by_id( $speaker_id );
        if ( ! $partner || ! $speaker || empty( $speaker['email'] ) ) return false;

        $tokens = self::slot_tokens( $slot, $partner, $speaker );
        $subject = self::replace_tokens( get_option( 'tcb_email_speaker_request_subject', 'Interview Request Sent: {partner_name}' ), $tokens );
        $body = self::get_base_template(
            'Interview Request Sent',
            "<p>Hello <strong>{$speaker['name']}</strong>,</p>
            <p>Your interview request has been sent to <strong>{$partner['name']}</strong>.</p>
            <div style='background:#f1f5f9;padding:15px;border-radius:8px;margin:20px 0;color:#0f172a;'>
                <strong>Partner:</strong> {$partner['name']}<br>
                <strong>Date:</strong> {$tokens['slot_date']}<br>
                <strong>Time:</strong> {$tokens['slot_time']}<br>
                <strong>Status:</strong> Request Sent<br>
            </div>
            <p><strong>Request Rule:</strong> You can send one request to this media partner for a date at a time. If the partner accepts it, the interview becomes booked. If the partner rejects it, only you cannot request that exact slot again; the slot remains available for other speakers.</p>
            <p>The media partner has received your contact details and selected time. They may contact you directly if selected.</p>
            <a href='{$tokens['speaker_dashboard_url']}' style='display:inline-block;padding:12px 24px;background:#e61a84;color:#fff;text-decoration:none;border-radius:6px;font-weight:bold;margin-top:10px;'>View My Dashboard</a>"
        );
        if ( $custom = get_option( 'tcb_email_speaker_request_template', '' ) ) { $body = self::replace_tokens( $custom, $tokens ); }
        return self::send_mail( $speaker['email'], $subject, $body );
    }


    /**
     * Sends immediate email to the Speaker when a Partner approves or declines.
     */
    public static function send_status_update( int $slot_id, string $status ): bool {
        $slot    = BookingsDAO::get_slot( $slot_id );
        if ( ! $slot || ! $slot['speaker_id'] ) return false;

        $partner = PartnersDAO::get_by_id( (int)$slot['partner_id'] );
        $speaker = \TCA\DB\SpeakersDAO::get_by_id( (int)$slot['speaker_id'] );
        
        if ( ! $partner || ! $speaker || empty( $speaker['email'] ) ) return false;

        $to      = $speaker['email'];
        $status_text = $status === 'approved' ? 'Approved' : 'Declined';
        $tokens = self::slot_tokens( $slot, $partner, $speaker );
        $subject_key = $status === 'approved' ? 'tcb_email_approved_subject' : 'tcb_email_declined_subject';
        $template_key = $status === 'approved' ? 'tcb_email_approved_template' : 'tcb_email_declined_template';
        $subject = self::replace_tokens( get_option( $subject_key, "Interview Request {$status_text}: {partner_name}" ), $tokens );
        
        $time_fmt = date( 'g:i A', strtotime( $slot['time_start'] ) ) . ' - ' . date( 'g:i A', strtotime( $slot['time_end'] ) );
        $date_fmt = date( 'l, F j, Y', strtotime( $slot['slot_date'] ) );

        $msg = $status === 'approved' 
            ? "Great news! <strong>{$partner['name']}</strong> has <strong>APPROVED</strong> your interview request."
            : "Unfortunately, <strong>{$partner['name']}</strong> has <strong>DECLINED</strong> your interview request for this specific time slot. Please check your dashboard for whether another slot is available for this partner/day.";

        $body = self::get_base_template(
            "Interview {$status_text}",
            "<p>Hello <strong>{$speaker['name']}</strong>,</p>
            <p>{$msg}</p>
            <div style='background:#f1f5f9;padding:15px;border-radius:8px;margin:20px 0;color:#0f172a;'>
                <strong>Partner:</strong> {$partner['name']}<br>
                <strong>Date:</strong> {$date_fmt}<br>
                <strong>Time:</strong> {$time_fmt}<br>
            </div>
            <a href='" . home_url('/speaker-dashboard/') . "' style='display:inline-block;padding:12px 24px;background:#e61a84;color:#fff;text-decoration:none;border-radius:6px;font-weight:bold;margin-top:10px;'>View My Schedule</a>"
        );

        if ( $custom = get_option( $template_key, '' ) ) { $body = self::replace_tokens( $custom, $tokens ); }
        return self::send_mail( $to, $subject, $body );
    }


    public static function send_rebook_allowed_notice( int $slot_id, int $speaker_id = 0 ): bool {
        $slot = BookingsDAO::get_slot( $slot_id );
        $request = BookingsDAO::get_latest_request_for_slot( $slot_id );
        if ( ! $speaker_id && $request ) { $speaker_id = (int) ( $request['speaker_id'] ?? 0 ); }
        if ( ! $slot || ! $speaker_id ) return false;
        $partner = PartnersDAO::get_by_id( (int) $slot['partner_id'] );
        $speaker = \TCA\DB\SpeakersDAO::get_by_id( $speaker_id );
        if ( ! $partner || ! $speaker || empty( $speaker['email'] ) ) return false;
        $tokens = self::slot_tokens( $slot, $partner, $speaker );
        $subject = self::replace_tokens( get_option( 'tcb_email_rebook_allowed_subject', 'You can request another interview slot with {partner_name}' ), $tokens );
        $body = self::get_base_template(
            'You Can Request Another Slot',
            "<p>Hello <strong>{$speaker['name']}</strong>,</p>
            <p><strong>{$partner['name']}</strong> has reopened booking access for you for this day. You may now choose another available slot with this media partner.</p>
            <div style='background:#f1f5f9;padding:15px;border-radius:8px;margin:20px 0;color:#0f172a;'>
                <strong>Partner:</strong> {$partner['name']}<br>
                <strong>Date:</strong> {$tokens['slot_date']}<br>
                <strong>Previous Slot:</strong> {$tokens['slot_time']}<br>
            </div>
            <a href='{$tokens['booking_url']}' style='display:inline-block;padding:12px 24px;background:#e61a84;color:#fff;text-decoration:none;border-radius:6px;font-weight:bold;margin-top:10px;'>Choose Another Slot</a>"
        );
        if ( $custom = get_option( 'tcb_email_rebook_allowed_template', '' ) ) { $body = self::replace_tokens( $custom, $tokens ); }
        return self::send_mail( $speaker['email'], $subject, $body );
    }


    public static function send_cancel_notification( int $slot_id, int $speaker_id ): bool {
        $slot = BookingsDAO::get_slot( $slot_id );
        if ( ! $slot ) return false;
        $partner = PartnersDAO::get_by_id( (int) $slot['partner_id'] );
        $speaker = \TCA\DB\SpeakersDAO::get_by_id( $speaker_id );
        if ( ! $partner || ! $speaker || empty( $partner['email'] ) ) return false;
        $tokens = self::slot_tokens( $slot, $partner, $speaker );
        $subject = self::replace_tokens( get_option( 'tcb_email_cancel_subject', 'Interview Request Cancelled: {speaker_name}' ), $tokens );
        $body = self::get_base_template( 'Interview Cancelled', "<p>Hello <strong>{$partner['name']}</strong>,</p><p><strong>{$speaker['name']}</strong> has cancelled this interview request.</p><div style='background:#f1f5f9;padding:15px;border-radius:8px;margin:20px 0;color:#0f172a;'><strong>Date:</strong> {$tokens['slot_date']}<br><strong>Time:</strong> {$tokens['slot_time']}<br><strong>Room:</strong> {$tokens['room']}</div><a href='" . home_url('/partner-dashboard/') . "' style='display:inline-block;padding:12px 24px;background:#e61a84;color:#fff;text-decoration:none;border-radius:6px;font-weight:bold;margin-top:10px;'>Go to Dashboard</a>" );
        if ( $custom = get_option( 'tcb_email_cancel_template', '' ) ) { $body = self::replace_tokens( $custom, $tokens ); }
        return self::send_mail( $partner['email'], $subject, $body );
    }

    private static function get_base_template( string $title, string $content ): string {
        return "
        <!DOCTYPE html>
        <html>
        <head><style>body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;color:#333;line-height:1.6;}</style></head>
        <body style='background:#f8fafc;padding:40px 20px;'>
            <div style='max-width:600px;margin:0 auto;background:#fff;border-radius:12px;overflow:hidden;box-shadow:0 10px 25px rgba(0,0,0,0.05);'>
                <div style='background:#0b0b1c;padding:30px;text-align:center;border-bottom:4px solid #e61a84;'>
                    <h1 style='color:#fff;margin:0;font-size:24px;'>TechCon Booking</h1>
                </div>
                <div style='padding:40px 30px;'>
                    <h2 style='color:#0f172a;margin-top:0;'>{$title}</h2>
                    {$content}
                </div>
                <div style='background:#f1f5f9;padding:20px;text-align:center;font-size:12px;color:#64748b;'>
                    &copy; " . date('Y') . " TechCon Global. All rights reserved.
                </div>
            </div>
        </body>
        </html>";
    }
}
