<?php
namespace TCA\Admin;
use TCA\DB\{EventsDAO, DaysDAO, SessionsDAO, SpeakersDAO};
if ( ! defined( 'ABSPATH' ) ) { exit; }

class Ajax {

    private static function canonical_session( array $s ): array {
        $s['json_id'] = $s['external_id'] ?? '';
        $s['date'] = $s['date_short'] ?? '';
        $s['code'] = $s['session_code'] ?? '';
        $s['type'] = $s['session_type'] ?? '';
        if ( ! empty( $s['speakers'] ) ) {
            foreach ( $s['speakers'] as &$sp ) {
                $sp['profile'] = $sp['profile_url'] ?? '';
                $sp['image'] = $sp['image_url'] ?? '';
                $sp['position'] = $sp['position'] ?? '';
                $sp['linkedin'] = $sp['linkedin_url'] ?? '';
            }
        }
        return $s;
    }

    public static function init(): void {
        $actions = [
            // Events
            'tca_get_events','tca_save_event','tca_delete_event','tca_set_event_status',
            // Days
            'tca_get_days','tca_save_day','tca_delete_day',
            // Sessions
            'tca_get_sessions','tca_save_session','tca_delete_session','tca_toggle_booking',
            'tca_get_session_speakers','tca_set_session_speakers',
            // Speakers
            'tca_get_speakers','tca_save_speaker','tca_delete_speaker','tca_clear_speakers_data',
            'tca_send_credentials','tca_send_credentials_bulk',
            'tca_get_speaker_password','tca_set_speaker_password',
            'tca_access_account','tca_link_speaker_event',
            // CSV import/export
            'tca_import_speakers','tca_import_sessions',
            'tca_export_speakers_template','tca_export_sessions_template','tca_export_partners_template','tca_export_speakers_csv','tca_export_sessions_csv',
            // Frontend data
            'tca_get_agenda',
            // Settings
            'tca_get_settings','tca_save_settings',
        ];
        foreach ( $actions as $a ) {
            add_action( 'wp_ajax_' . $a, [ self::class, 'dispatch' ] );
        }
        // Export templates are also accessible logged-out (GET requests).
        add_action( 'wp_ajax_nopriv_tca_get_agenda', [ self::class, 'dispatch' ] );
    }

    public static function dispatch(): void {
        $action = sanitize_key( $_REQUEST['action'] ?? '' );

        // Skip nonce for public agenda and direct-link export templates.
        $skip_nonce = [
            'tca_get_agenda',
            'tca_export_speakers_template',
            'tca_export_sessions_template',
            'tca_export_partners_template',
            'tca_export_speakers_csv',
            'tca_export_sessions_csv'
        ];

        if ( ! in_array( $action, $skip_nonce, true ) ) {
            if ( ! check_ajax_referer( 'tca-admin-nonce', 'nonce', false ) ) {
                wp_send_json_error( [ 'message' => 'Security check failed.' ], 403 );
            }
            if ( ! current_user_can( 'manage_options' ) ) {
                wp_send_json_error( [ 'message' => 'Insufficient permissions.' ], 403 );
            }
        }

        switch ( $action ) {

            /* ── Events ────────────────────────────────────────── */
            case 'tca_get_events':
                wp_send_json_success( EventsDAO::get_all() );

            case 'tca_save_event':
                $id  = (int)( $_POST['id'] ?? 0 );
                $res = $id ? EventsDAO::update( $id, $_POST ) : EventsDAO::insert( $_POST );
                $res ? wp_send_json_success( [ 'id' => $id ?: $res ] ) : wp_send_json_error();

            case 'tca_delete_event':
                EventsDAO::delete( (int)( $_POST['id'] ?? 0 ) )
                    ? wp_send_json_success() : wp_send_json_error();

            case 'tca_set_event_status':
                $status = in_array( $_POST['status'] ?? '', [ 'live','draft' ] ) ? $_POST['status'] : 'draft';
                EventsDAO::set_status( (int)( $_POST['id'] ?? 0 ), $status );
                wp_send_json_success();

            /* ── Days ──────────────────────────────────────────── */
            case 'tca_get_days':
                wp_send_json_success( DaysDAO::get_by_event( (int)( $_REQUEST['event_id'] ?? 0 ) ) );

            case 'tca_save_day':
                $id  = (int)( $_POST['id'] ?? 0 );
                $res = $id ? DaysDAO::update( $id, $_POST ) : DaysDAO::insert( $_POST );
                $res ? wp_send_json_success( [ 'id' => $id ?: $res ] ) : wp_send_json_error();

            case 'tca_delete_day':
                DaysDAO::delete( (int)( $_POST['id'] ?? 0 ) )
                    ? wp_send_json_success() : wp_send_json_error();

            /* ── Sessions ──────────────────────────────────────── */
            case 'tca_get_sessions':
                $event_id = (int)( $_REQUEST['event_id'] ?? 0 );
                $day_id   = (int)( $_REQUEST['day_id']   ?? 0 );
                $sessions = $day_id
                    ? SessionsDAO::get_by_day( $day_id )
                    : SessionsDAO::get_by_event( $event_id );
                // Attach speaker list to each session.
                foreach ( $sessions as &$s ) {
                    $s['speakers'] = SessionsDAO::get_with_speakers( (int)$s['id'] );
                    $s = self::canonical_session( $s );
                }
                wp_send_json_success( $sessions );

            case 'tca_save_session':
                $id  = (int)( $_POST['id'] ?? 0 );
                $res = $id ? SessionsDAO::update( $id, $_POST ) : SessionsDAO::insert( $_POST );
                if ( ! $res && ! $id ) { wp_send_json_error(); }
                $sid = $id ?: $res;
                // Handle speaker assignment.
                if ( isset( $_POST['speaker_ids'] ) ) {
                    $ids = array_filter( array_map( 'intval', (array)$_POST['speaker_ids'] ) );
                    SessionsDAO::set_speakers( (int)$sid, $ids );
                }
                wp_send_json_success( [ 'id' => $sid ] );

            case 'tca_delete_session':
                SessionsDAO::delete( (int)( $_POST['id'] ?? 0 ) )
                    ? wp_send_json_success() : wp_send_json_error();

            case 'tca_toggle_booking':
                SessionsDAO::toggle_booking( (int)( $_POST['id'] ?? 0 ), (bool)( $_POST['enabled'] ?? 0 ) );
                wp_send_json_success();

            case 'tca_get_session_speakers':
                wp_send_json_success( SessionsDAO::get_with_speakers( (int)( $_REQUEST['session_id'] ?? 0 ) ) );

            case 'tca_set_session_speakers':
                $ids = array_filter( array_map( 'intval', (array)( $_POST['speaker_ids'] ?? [] ) ) );
                SessionsDAO::set_speakers( (int)( $_POST['session_id'] ?? 0 ), $ids );
                wp_send_json_success();

            /* ── Speakers ──────────────────────────────────────── */
            case 'tca_get_speakers':
                $args = [
                    'search'   => sanitize_text_field( $_REQUEST['search']   ?? '' ),
                    'event_id' => (int)( $_REQUEST['event_id'] ?? 0 ),
                ];
                wp_send_json_success( SpeakersDAO::get_all( $args ) );

            case 'tca_save_speaker':
                $id  = (int)( $_POST['id'] ?? 0 );
                $res = $id ? SpeakersDAO::update( $id, $_POST ) : SpeakersDAO::insert( $_POST );
                if ( $res && ! $id ) {
                    if ( ! empty( $_POST['event_id'] ) ) SpeakersDAO::link_event( (int)$res, (int)$_POST['event_id'] );
                    wp_send_json_success( [ 'id' => $res ] );
                }
                $res !== false ? wp_send_json_success( [ 'id' => $id ] ) : wp_send_json_error();

            case 'tca_delete_speaker':
                SpeakersDAO::delete( (int)( $_POST['id'] ?? 0 ) )
                    ? wp_send_json_success() : wp_send_json_error();

            case 'tca_clear_speakers_data':
                if ( ! current_user_can( 'manage_options' ) ) wp_send_json_error( [ 'message' => 'Admin only.' ], 403 );
                global $wpdb;
                // Clear speaker-related data without deleting events/days/sessions.
                foreach ( [ \TCA\Installer::t_session_speakers(), \TCA\Installer::t_event_speakers(), \TCA\Installer::t_speakers() ] as $table ) {
                    $wpdb->query( "TRUNCATE TABLE $table" );
                }
                wp_send_json_success( [ 'message' => 'All speaker data and speaker assignments have been cleared.' ] );

            case 'tca_send_credentials':
                $ok = CredentialManager::send_credentials( (int)( $_POST['id'] ?? 0 ) );
                $ok ? wp_send_json_success( [ 'message' => 'Credentials sent!' ] )
                    : wp_send_json_error( [ 'message' => 'Unable to send email. Plugin tried wp_mail and fallback PHP mail. Please verify SMTP/from email if this continues.' ] );

            case 'tca_send_credentials_bulk':
                $ids = array_filter( array_map( 'intval', (array)( $_POST['ids'] ?? [] ) ) );
                $res = CredentialManager::send_bulk( $ids );
                wp_send_json_success( $res );

            case 'tca_get_speaker_password':
                if ( ! current_user_can( 'manage_options' ) ) wp_send_json_error( [], 403 );
                $pw = CredentialManager::get_plain_password( (int)( $_POST['id'] ?? 0 ) );
                wp_send_json_success( [ 'password' => $pw ?: '—' ] );

            case 'tca_set_speaker_password':
                if ( ! current_user_can( 'manage_options' ) ) wp_send_json_error( [], 403 );
                $id   = (int)( $_POST['id'] ?? 0 );
                $pass = $_POST['password'] ?? '';
                if ( ! $id || ! $pass ) wp_send_json_error( [ 'message' => 'Invalid data.' ] );
                $ok = CredentialManager::set_custom_password( $id, $pass );
                if ( $ok ) wp_send_json_success( [ 'message' => 'Password updated.' ] );
                wp_send_json_error( [ 'message' => 'Failed to update password. Ensure speaker has been provisioned first.' ] );

            case 'tca_access_account':
                wp_send_json_error( [ 'message' => 'Token access links are disabled. Please use speaker email/password credentials from /speaker-login/.' ], 403 );

            case 'tca_link_speaker_event':
                SpeakersDAO::link_event( (int)( $_POST['speaker_id'] ?? 0 ), (int)( $_POST['event_id'] ?? 0 ) );
                wp_send_json_success();

            /* ── CSV Import ────────────────────────────────────── */
            case 'tca_import_speakers':
                if ( empty( $_FILES['csv']['tmp_name'] ) ) wp_send_json_error( [ 'message' => 'No file.' ] );
                $report = CsvImporter::import_speakers( $_FILES['csv']['tmp_name'], (int)( $_POST['event_id'] ?? 0 ) );
                wp_send_json_success( $report );

            case 'tca_import_sessions':
                if ( empty( $_FILES['csv']['tmp_name'] ) ) wp_send_json_error( [ 'message' => 'No file.' ] );
                $eid = (int)( $_POST['event_id'] ?? 0 );
                if ( ! $eid ) wp_send_json_error( [ 'message' => 'Select an event first.' ] );
                $report = CsvImporter::import_sessions( $_FILES['csv']['tmp_name'], $eid );
                wp_send_json_success( $report );

            /* ── CSV Export Templates ──────────────────────────── */
            case 'tca_export_speakers_template':
                CsvImporter::export_speakers_template();

            case 'tca_export_sessions_template':
                CsvImporter::export_sessions_template();

            case 'tca_export_partners_template':
                CsvImporter::export_partners_template();

            case 'tca_export_speakers_csv':
                self::export_speakers_csv();

            case 'tca_export_sessions_csv':
                self::export_sessions_csv();

            /* ── Public agenda data ────────────────────────────── */
            case 'tca_get_agenda':
                $event_id = (int)( $_REQUEST['event_id'] ?? 0 );
                if ( ! $event_id ) wp_send_json_error( [ 'message' => 'Event ID required.' ] );
                $event = EventsDAO::get_by_id( $event_id );
                if ( ! $event ) wp_send_json_error( [ 'message' => 'Event not found.' ] );
                $days = DaysDAO::get_by_event( $event_id );
                foreach ( $days as &$day ) {
                    $sessions = SessionsDAO::get_by_day( (int)$day['id'] );
                    foreach ( $sessions as &$sess ) {
                        $sess['speakers'] = SessionsDAO::get_with_speakers( (int)$sess['id'] );
                        $sess = self::canonical_session( $sess );
                    }
                    $day['sessions'] = $sessions;
                }
                wp_send_json_success( [ 'event' => $event, 'days' => $days ] );

            /* ── Settings ────────────────────────────── */
            case 'tca_get_settings':
                $settings = [
                    'enable_profiles' => get_option( 'tca_enable_speaker_profiles', 'yes' ),
                    'enable_agenda_pages' => get_option( 'tca_enable_agenda_pages', 'yes' ),
                    'export_speakers_url' => admin_url( 'admin-ajax.php?action=tca_export_speakers_csv' ),
                    'export_sessions_url' => admin_url( 'admin-ajax.php?action=tca_export_sessions_csv' ),
                    'speaker_credentials_subject' => get_option( 'tca_speaker_credentials_subject', 'Your TechCon Speaker Portal Access - {site_name}' ),
                    'speaker_credentials_template' => get_option( 'tca_speaker_credentials_template', '' ),
                    'speaker_credentials_body_text' => get_option( 'tca_speaker_credentials_body_text', CredentialManager::default_speaker_credentials_body_text() ),
                    'speaker_credential_header_text' => get_option( 'tca_speaker_credential_header_text', 'Speaker Portal — Your Access Credentials' ),
                    'speaker_credential_button_text' => get_option( 'tca_speaker_credential_button_text', 'Sign In to Speaker Portal →' ),
                    'speaker_credential_password_note' => get_option( 'tca_speaker_credential_password_note', 'For security, you can {reset_link} after logging in. Your new password remains accessible to TechCon administrators.' ),
                    'credential_footer_techcon_text' => get_option( 'tca_credential_footer_techcon_text', 'TechCon Global' ),
                    'credential_footer_techcon_url' => get_option( 'tca_credential_footer_techcon_url', 'https://techconglobal.com/' ),
                    'credential_footer_powered_by_text' => get_option( 'tca_credential_footer_powered_by_text', 'Powered by' ),
                    'credential_footer_brilzen_text' => get_option( 'tca_credential_footer_brilzen_text', 'BRILZEN (SMC-PRIVATE) LIMITED' ),
                    'credential_footer_brilzen_url' => get_option( 'tca_credential_footer_brilzen_url', 'https://brilzen.com/' )
                ];
                wp_send_json_success( $settings );

            case 'tca_save_settings':
                update_option( 'tca_enable_speaker_profiles', sanitize_text_field( $_POST['enable_profiles'] ?? 'yes' ) );
                update_option( 'tca_enable_agenda_pages', sanitize_text_field( $_POST['enable_agenda_pages'] ?? 'yes' ) === 'yes' ? 'yes' : 'no' );
                update_option( 'tca_speaker_credentials_subject', sanitize_text_field( $_POST['speaker_credentials_subject'] ?? 'Your TechCon Speaker Portal Access - {site_name}' ) );
                update_option( 'tca_speaker_credentials_template', wp_kses_post( wp_unslash( $_POST['speaker_credentials_template'] ?? '' ) ) );
                $speaker_body_text = wp_kses_post( wp_unslash( $_POST['speaker_credentials_body_text'] ?? CredentialManager::default_speaker_credentials_body_text() ) );
                update_option( 'tca_speaker_credentials_body_text', trim( $speaker_body_text ) !== '' ? $speaker_body_text : CredentialManager::default_speaker_credentials_body_text() );
                update_option( 'tca_speaker_credential_header_text', sanitize_text_field( wp_unslash( $_POST['speaker_credential_header_text'] ?? 'Speaker Portal — Your Access Credentials' ) ) );
                update_option( 'tca_speaker_credential_button_text', sanitize_text_field( wp_unslash( $_POST['speaker_credential_button_text'] ?? 'Sign In to Speaker Portal →' ) ) );
                update_option( 'tca_speaker_credential_password_note', wp_kses_post( wp_unslash( $_POST['speaker_credential_password_note'] ?? 'For security, you can {reset_link} after logging in. Your new password remains accessible to TechCon administrators.' ) ) );
                update_option( 'tca_credential_footer_techcon_text', sanitize_text_field( wp_unslash( $_POST['credential_footer_techcon_text'] ?? 'TechCon Global' ) ) );
                update_option( 'tca_credential_footer_techcon_url', esc_url_raw( wp_unslash( $_POST['credential_footer_techcon_url'] ?? 'https://techconglobal.com/' ) ) );
                update_option( 'tca_credential_footer_powered_by_text', sanitize_text_field( wp_unslash( $_POST['credential_footer_powered_by_text'] ?? 'Powered by' ) ) );
                update_option( 'tca_credential_footer_brilzen_text', sanitize_text_field( wp_unslash( $_POST['credential_footer_brilzen_text'] ?? 'BRILZEN (SMC-PRIVATE) LIMITED' ) ) );
                update_option( 'tca_credential_footer_brilzen_url', esc_url_raw( wp_unslash( $_POST['credential_footer_brilzen_url'] ?? 'https://brilzen.com/' ) ) );
                wp_send_json_success();

            default:
                wp_send_json_error( [ 'message' => 'Unknown action.' ], 400 );
        }
    }

    private static function export_speakers_csv(): void {
        if ( ! current_user_can( 'manage_options' ) ) { wp_die( 'Forbidden', 403 ); }
        header( 'Content-Type: text/csv; charset=utf-8' );
        header( 'Content-Disposition: attachment; filename=techcon-speakers-' . date( 'Y-m-d' ) . '.csv' );
        $out = fopen( 'php://output', 'w' );
        fputcsv( $out, [ 'ID', 'Name', 'Email', 'Slug', 'Profile URL', 'Image URL', 'Company', 'Position', 'LinkedIn URL', 'Profile Tag', 'Bio' ] );
        foreach ( SpeakersDAO::get_all( [] ) as $sp ) {
            fputcsv( $out, [ $sp['id'] ?? '', $sp['name'] ?? '', $sp['email'] ?? '', $sp['slug'] ?? '', $sp['profile_url'] ?? '', $sp['image_url'] ?? '', $sp['company'] ?? '', $sp['position'] ?? '', $sp['linkedin_url'] ?? '', $sp['profile_tag'] ?? '', wp_strip_all_tags( $sp['bio'] ?? '' ) ] );
        }
        fclose( $out );
        exit;
    }

    private static function export_sessions_csv(): void {
        if ( ! current_user_can( 'manage_options' ) ) { wp_die( 'Forbidden', 403 ); }
        header( 'Content-Type: text/csv; charset=utf-8' );
        header( 'Content-Disposition: attachment; filename=techcon-sessions-' . date( 'Y-m-d' ) . '.csv' );
        $out = fopen( 'php://output', 'w' );
        fputcsv( $out, [ 'ID', 'Event ID', 'Day ID', 'Date Short', 'Time', 'Room', 'Code', 'Type', 'Title', 'Track', 'Description', 'Brief', 'Speaker Names' ] );
        $events = EventsDAO::get_all();
        foreach ( $events as $event ) {
            $sessions = SessionsDAO::get_by_event( (int) $event['id'] );
            foreach ( $sessions as $sess ) {
                $speakers = SessionsDAO::get_with_speakers( (int) $sess['id'] );
                $names = implode( ', ', array_filter( array_map( function( $sp ) { return $sp['name'] ?? ''; }, $speakers ) ) );
                fputcsv( $out, [ $sess['external_id'] ?? $sess['id'] ?? '', $sess['event_id'] ?? '', $sess['day_id'] ?? '', $sess['date_short'] ?? '', $sess['time_string'] ?? '', $sess['room'] ?? '', $sess['session_code'] ?? '', $sess['session_type'] ?? '', $sess['title'] ?? '', $sess['track'] ?? '', $sess['description'] ?? '', $sess['brief'] ?? '', $names ] );
            }
        }
        fclose( $out );
        exit;
    }

}
