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

if (!current_user_can('manage_options')) {
    wp_die('Access denied.');
}

if (!function_exists('inception_techboost_notes_sanitize')) {
    function inception_techboost_notes_sanitize($notes) {
        $notes = is_string($notes) ? wp_unslash($notes) : '';

        $allowed_html = array(
        'a' => array(
            'href' => true,
            'title' => true,
            'target' => true,
            'rel' => true,
        ),
        'blockquote' => array(),
        'br' => array(),
        'code' => array(),
        'del' => array(),
        'div' => array(
            'class' => true,
            'style' => true,
        ),
        'em' => array(),
        'h1' => array(),
        'h2' => array(),
        'h3' => array(),
        'h4' => array(),
        'h5' => array(),
        'h6' => array(),
        'hr' => array(),
        'strong' => array(),
        'b' => array(),
        'i' => array(),
        'img' => array(
            'alt' => true,
            'class' => true,
            'decoding' => true,
            'height' => true,
            'loading' => true,
            'sizes' => true,
            'src' => true,
            'srcset' => true,
            'title' => true,
            'width' => true,
        ),
        'span' => array(
            'class' => true,
            'style' => true,
        ),
        'ul' => array(),
        'ol' => array(),
        'li' => array(),
        'p' => array(),
        'pre' => array(),
    );

        return wp_kses($notes, $allowed_html);
    }
}

if (!function_exists('inception_techboost_notes_has_content')) {
    function inception_techboost_notes_has_content($notes) {
        if (!is_string($notes)) {
            return false;
        }

        // An image-only note still counts as saved Notes content.
        if (preg_match('/<img\b/i', $notes)) {
            return true;
        }

        $text = html_entity_decode(wp_strip_all_tags($notes), ENT_QUOTES, get_bloginfo('charset'));
        $text = preg_replace('/\x{00a0}|\x{200b}/u', ' ', $text);

        return trim($text) !== '';
    }
}

if (!function_exists('inception_techboost_notes_make_links_new_tab')) {
    function inception_techboost_notes_make_links_new_tab($html) {
        if (trim($html) === '') {
            return '';
        }

        $html = make_clickable($html);

        return preg_replace_callback('/<a\s+([^>]*href=(["\'])(.*?)\2[^>]*)>/i', function ($matches) {
            $attrs = $matches[1];

            $attrs = preg_replace('/\s+target=(["\']).*?\1/i', '', $attrs);
            $attrs = preg_replace('/\s+rel=(["\']).*?\1/i', '', $attrs);

            return '<a ' . trim($attrs) . ' target="_blank" rel="noopener noreferrer">';
        }, $html);
    }
}

if (!function_exists('inception_techboost_notes_sanitize_url')) {
    function inception_techboost_notes_sanitize_url($url) {
        $url = is_string($url) ? trim(wp_unslash($url)) : '';
        if ($url === '') {
            return '';
        }

        if (preg_match('/^www\./i', $url)) {
            $url = 'https://' . $url;
        }

        return esc_url_raw($url);
    }
}

if (!function_exists('inception_techboost_notes_get_important_url')) {
    function inception_techboost_notes_get_important_url($option_name) {
        return inception_techboost_notes_sanitize_url(get_option($option_name, ''));
    }
}

if (!function_exists('inception_techboost_notes_get_important_urls')) {
    function inception_techboost_notes_get_important_urls($option_name) {
        $urls = get_option($option_name, array());
        if (!is_array($urls)) {
            $urls = array();
        }

        $clean_urls = array();
        foreach ($urls as $url) {
            $url = inception_techboost_notes_sanitize_url($url);
            if ($url !== '' && !in_array($url, $clean_urls, true)) {
                $clean_urls[] = $url;
            }
        }

        return $clean_urls;
    }
}

if (!function_exists('inception_techboost_notes_save_important_url')) {
    function inception_techboost_notes_save_important_url($option_name, $post_key) {
        $url = isset($_POST[$post_key]) ? inception_techboost_notes_sanitize_url($_POST[$post_key]) : '';
        update_option($option_name, $url, false);
        return $url;
    }
}

if (!function_exists('inception_techboost_notes_save_important_urls')) {
    function inception_techboost_notes_save_important_urls($option_name, $post_key) {
        if (!isset($_POST[$post_key]) || !is_array($_POST[$post_key])) {
            update_option($option_name, array(), false);
            return array();
        }

        $urls = array();
        foreach ($_POST[$post_key] as $url) {
            $url = inception_techboost_notes_sanitize_url($url);
            if ($url !== '' && !in_array($url, $urls, true)) {
                $urls[] = $url;
            }
        }

        update_option($option_name, $urls, false);
        return $urls;
    }
}

if (!function_exists('inception_techboost_notes_link_items')) {
    function inception_techboost_notes_link_items() {
        $groups = array(
            array(
                'text' => 'Pages',
                'post_type' => 'page',
                'menu' => array(),
            ),
            array(
                'text' => 'Blogs',
                'post_type' => 'post',
                'menu' => array(),
            ),
            array(
                'text' => 'Themer Layouts',
                'post_type' => 'fl-theme-layout',
                'menu' => array(),
            ),
        );

        foreach ($groups as &$group) {
            $posts = get_posts(array(
                'post_type' => $group['post_type'],
                'post_status' => array('publish', 'draft', 'private', 'pending', 'future'),
                'posts_per_page' => -1,
                'orderby' => 'title',
                'order' => 'ASC',
            ));

            foreach ($posts as $post) {
                $url = get_permalink($post);
                if (!$url) {
                    continue;
                }

                $title = get_the_title($post);
                if ($title === '') {
                    $title = '(no title)';
                }

                $group['menu'][] = array(
                    'text' => $title . ' (' . $post->post_name . ')',
                    'value' => esc_url_raw($url),
                );
            }
        }
        unset($group);

        return array_values(array_filter($groups, function ($group) {
            return !empty($group['menu']);
        }));
    }
}

if (!function_exists('inception_techboost_notes_user_ip')) {
    function inception_techboost_notes_user_ip() {
        $candidates = array(
            isset($_SERVER['HTTP_CLIENT_IP']) ? $_SERVER['HTTP_CLIENT_IP'] : '',
            isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : '',
            isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '',
        );

        foreach ($candidates as $candidate) {
            $candidate = trim((string) $candidate);
            if ($candidate === '') {
                continue;
            }

            $parts = array_map('trim', explode(',', $candidate));
            foreach ($parts as $part) {
                if (filter_var($part, FILTER_VALIDATE_IP)) {
                    return $part;
                }
            }
        }

        return '';
    }
}

if (!function_exists('inception_techboost_notes_log_path')) {
    function inception_techboost_notes_log_path() {
        $upload_dir = wp_upload_dir();
        if (empty($upload_dir['basedir'])) {
            return '';
        }

        $log_dir = trailingslashit($upload_dir['basedir']) . 'inception-techboost';
        if (!wp_mkdir_p($log_dir)) {
            return '';
        }

        $index_file = trailingslashit($log_dir) . 'index.php';
        if (!file_exists($index_file)) {
            @file_put_contents($index_file, "<?php\n// Silence is golden.\n");
        }

        $htaccess_file = trailingslashit($log_dir) . '.htaccess';
        if (!file_exists($htaccess_file)) {
            @file_put_contents($htaccess_file, "Deny from all\n");
        }

        return trailingslashit($log_dir) . 'notes-log.jsonl';
    }
}

if (!function_exists('inception_techboost_notes_write_log')) {
    function inception_techboost_notes_write_log($notes, $updated_by) {
        $log_path = inception_techboost_notes_log_path();
        if ($log_path === '') {
            return false;
        }

        $current_user = wp_get_current_user();
        $entry = array(
            'timestamp' => current_time('mysql'),
            'timestamp_gmt' => current_time('mysql', true),
            'entered_name' => (string) $updated_by,
            'wp_user_id' => ($current_user && $current_user->exists()) ? (int) $current_user->ID : 0,
            'wp_user_login' => ($current_user && $current_user->exists()) ? (string) $current_user->user_login : '',
            'ip_address' => inception_techboost_notes_user_ip(),
            'notes' => (string) $notes,
        );

        $encoded = wp_json_encode($entry);
        if (!$encoded) {
            return false;
        }

        return false !== @file_put_contents($log_path, $encoded . PHP_EOL, FILE_APPEND | LOCK_EX);
    }
}

add_filter('mce_external_plugins', function ($plugins) {
    $plugins['inceptionTechBoostNotes'] = plugins_url('notes-editor.js', __FILE__);
    return $plugins;
});

add_filter('tiny_mce_before_init', function ($init) {
    $plugins = !empty($init['plugins']) ? array_map('trim', explode(',', $init['plugins'])) : array();

    foreach (array('inceptionTechBoostNotes') as $plugin) {
        if (!in_array($plugin, $plugins, true)) {
            $plugins[] = $plugin;
        }
    }

    $init['plugins'] = implode(',', array_filter($plugins));
    return $init;
});

$saved_notice = '';
$saved_notice_type = 'success';

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['inception_techboost_notes_nonce'])) {
    check_admin_referer('inception_techboost_save_notes', 'inception_techboost_notes_nonce');

    $raw_notes = isset($_POST['inception_techboost_notes']) ? wp_unslash($_POST['inception_techboost_notes']) : '';
    $notes = inception_techboost_notes_sanitize(inception_techboost_notes_make_links_new_tab($raw_notes));
    $updated_by = isset($_POST['inception_techboost_notes_updated_by']) ? sanitize_text_field(wp_unslash($_POST['inception_techboost_notes_updated_by'])) : '';

    if (strlen($updated_by) < 2) {
        $saved_notice = 'Please enter your name before saving.';
        $saved_notice_type = 'error';
    } else {
        update_option('inception_techboost_notes', $notes, false);
        update_option('inception_techboost_notes_updated_at', current_time('mysql'), false);
        update_option('inception_techboost_notes_updated_by', $updated_by, false);
        inception_techboost_notes_save_important_url('inception_techboost_notes_onedrive_link', 'inception_techboost_notes_onedrive_link');
        inception_techboost_notes_save_important_url('inception_techboost_notes_box_link', 'inception_techboost_notes_box_link');
        inception_techboost_notes_save_important_urls('inception_techboost_notes_highlevel_links', 'inception_techboost_notes_highlevel_links');
        inception_techboost_notes_write_log($notes, $updated_by);

        $saved_notice = 'Notes saved.';
    }
}

$notes = get_option('inception_techboost_notes', '');
$updated_at = get_option('inception_techboost_notes_updated_at', '');
$updated_by = get_option('inception_techboost_notes_updated_by', '');
$onedrive_link = inception_techboost_notes_get_important_url('inception_techboost_notes_onedrive_link');
$box_link = inception_techboost_notes_get_important_url('inception_techboost_notes_box_link');
$highlevel_links = inception_techboost_notes_get_important_urls('inception_techboost_notes_highlevel_links');
$link_items = inception_techboost_notes_link_items();
$has_notes = inception_techboost_notes_has_content($notes);
?>

<div class="wrap inception-techboost-notes-wrap">
    <h1>Notes</h1>

    <?php if ($saved_notice !== '') : ?>
        <div class="notice notice-<?php echo esc_attr($saved_notice_type); ?> is-dismissible">
            <p><?php echo esc_html($saved_notice); ?></p>
        </div>
    <?php endif; ?>

    <style>
        .inception-techboost-notes-wrap form {
            display: grid;
            grid-template-columns: minmax(0, 1fr) 380px;
            gap: 0 24px;
            align-items: start;
            max-width: 1500px;
        }

        .inception-techboost-notes-wrap .inception-notes-editor-wrap {
            grid-column: 1;
            grid-row: 3;
            max-width: none;
        }

        .inception-techboost-notes-wrap .wp-editor-area {
            min-height: 420px;
        }

        .inception-techboost-notes-wrap .wp-editor-tabs {
            display: none;
        }

        .inception-techboost-notes-wrap .inception-notes-meta {
            grid-column: 1 / -1;
            margin: 8px 0 14px;
            color: #646970;
        }

        .inception-techboost-notes-wrap .inception-notes-links {
            grid-column: 2;
            grid-row: 3;
            max-width: none;
            margin: 0;
        }

        .inception-techboost-notes-wrap .inception-notes-links h2 {
            margin-top: 0;
        }

        .inception-techboost-notes-wrap .inception-notes-links .form-table,
        .inception-techboost-notes-wrap .inception-notes-links .form-table tbody,
        .inception-techboost-notes-wrap .inception-notes-links .form-table tr,
        .inception-techboost-notes-wrap .inception-notes-links .form-table th,
        .inception-techboost-notes-wrap .inception-notes-links .form-table td {
            display: block;
        }

        .inception-techboost-notes-wrap .inception-notes-links .form-table th {
            width: auto;
            padding: 14px 0 4px;
        }

        .inception-techboost-notes-wrap .inception-notes-links .form-table td {
            padding: 0;
        }

        .inception-techboost-notes-wrap .inception-notes-link-row {
            display: flex;
            gap: 8px;
            align-items: center;
            max-width: none;
            margin-bottom: 8px;
        }

        .inception-techboost-notes-wrap .inception-notes-link-row input[type="url"],
        .inception-techboost-notes-wrap .inception-notes-link-row input[type="text"] {
            flex: 1;
            max-width: none;
            min-width: 0;
        }

        .inception-techboost-notes-wrap .inception-notes-links-note {
            margin: 4px 0 0;
            color: #646970;
        }

        .inception-techboost-notes-wrap form > p:last-child {
            grid-column: 1 / -1;
        }

        .inception-notes-name-warning {
            position: fixed;
            inset: 0;
            z-index: 100000;
            display: flex;
            align-items: center;
            justify-content: center;
            background: rgba(0, 0, 0, 0.35);
        }

        .inception-notes-name-warning-box {
            width: min(360px, calc(100vw - 40px));
            padding: 20px;
            background: #fff;
            border: 1px solid #c3c4c7;
            box-shadow: 0 12px 30px rgba(0, 0, 0, 0.22);
        }

        .inception-notes-name-warning-box p {
            margin: 0 0 16px;
        }

        @media (max-width: 1200px) {
            .inception-techboost-notes-wrap form {
                display: block;
                max-width: 1100px;
            }

            .inception-techboost-notes-wrap .inception-notes-links {
                margin: 18px 0;
            }
        }

    </style>

    <form method="post">
        <?php wp_nonce_field('inception_techboost_save_notes', 'inception_techboost_notes_nonce'); ?>

        <p class="inception-notes-meta">
            <strong>Last saved/edited:</strong>
            <?php
            if ($updated_at) {
                echo esc_html(mysql2date(get_option('date_format') . ' ' . get_option('time_format'), $updated_at));
                if ($updated_by !== '') {
                    echo ' by ' . esc_html($updated_by);
                }
            } else {
                echo 'Never';
            }
            ?>
        </p>

        <input type="hidden" id="inception_techboost_notes_updated_by" name="inception_techboost_notes_updated_by" value="">

        <div class="inception-notes-links">
            <h2>Important Links</h2>
            <p class="description">Save frequently used project links here for quick access.</p>

            <table class="form-table" role="presentation">
                <tbody>
                    <tr>
                        <th scope="row"><label for="inception_techboost_notes_onedrive_link">OneDrive Link</label></th>
                        <td>
                            <div class="inception-notes-link-row">
                                <input type="url" id="inception_techboost_notes_onedrive_link" name="inception_techboost_notes_onedrive_link" value="<?php echo esc_attr($onedrive_link); ?>" class="regular-text" placeholder="https://">
                                <button type="button" class="button inception-notes-open-link">Open</button>
                            </div>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row"><label for="inception_techboost_notes_box_link">Box Link</label></th>
                        <td>
                            <div class="inception-notes-link-row">
                                <input type="url" id="inception_techboost_notes_box_link" name="inception_techboost_notes_box_link" value="<?php echo esc_attr($box_link); ?>" class="regular-text" placeholder="https://">
                                <button type="button" class="button inception-notes-open-link">Open</button>
                            </div>
                        </td>
                    </tr>
                    <tr>
                        <th scope="row">Doctible/HighLevel Links</th>
                        <td>
                            <div id="inception-techboost-highlevel-links">
                                <?php foreach ($highlevel_links as $index => $highlevel_link) : ?>
                                    <div class="inception-notes-link-row">
                                        <input type="url" id="inception_techboost_notes_highlevel_link_<?php echo esc_attr($index); ?>" name="inception_techboost_notes_highlevel_links[]" value="<?php echo esc_attr($highlevel_link); ?>" class="regular-text" placeholder="https://">
                                        <button type="button" class="button inception-notes-open-link">Open</button>
                                    </div>
                                <?php endforeach; ?>

                                <div class="inception-notes-link-row">
                                    <input type="url" name="inception_techboost_notes_highlevel_links[]" value="" class="regular-text" placeholder="https://">
                                    <button type="button" class="button inception-notes-open-link">Open</button>
                                </div>
                            </div>

                            <button type="button" class="button" id="inception-techboost-add-highlevel-link">Add HighLevel Link</button>
                            <p class="inception-notes-links-note">Use additional fields for multi-location websites.</p>
                        </td>
                    </tr>
                </tbody>
            </table>
        </div>

        <div class="inception-notes-editor-wrap">
            <?php
            wp_editor($notes, 'inception_techboost_notes', array(
                'textarea_name' => 'inception_techboost_notes',
                'textarea_rows' => 18,
                'media_buttons' => false,
                'teeny' => false,
                'default_editor' => 'tinymce',
                'tinymce' => array(
                    'height' => 420,
                    'toolbar1' => 'formatselect,bold,italic,bullist,numlist,blockquote,alignleft,aligncenter,alignright,inceptionnotesphoto,inceptionnoteslink,link,unlink,undo,redo',
                    'toolbar2' => 'strikethrough,hr,forecolor,pastetext,removeformat,charmap,outdent,indent',
                    'relative_urls' => false,
                    'remove_script_host' => false,
                    'convert_urls' => false,
                ),
                'quicktags' => false,
            ));
            ?>
        </div>

        <p>
            <button type="submit" class="button button-primary">Save Notes</button>
        </p>
    </form>
</div>

<script>
window.inceptionTechBoostNotesLinks = <?php echo wp_json_encode($link_items); ?>;
window.inceptionTechBoostNotesHasNotes = <?php echo $has_notes ? 'true' : 'false'; ?>;
window.inceptionTechBoostNotesPhotoUpload = <?php echo wp_json_encode(array(
    'url' => admin_url('admin-ajax.php'),
    'nonce' => wp_create_nonce('inception_techboost_notes_upload_photo'),
)); ?>;

document.addEventListener('DOMContentLoaded', function() {
    const form = document.querySelector('.inception-techboost-notes-wrap form');
    const nameInput = document.getElementById('inception_techboost_notes_updated_by');
    const highLevelLinks = document.getElementById('inception-techboost-highlevel-links');
    const addHighLevelLink = document.getElementById('inception-techboost-add-highlevel-link');
    const notesWrap = document.querySelector('.inception-techboost-notes-wrap');
    let allowValidatedSubmit = false;

    function normalizeOpenUrl(url) {
        url = String(url || '').trim();

        if (url !== '' && /^www\./i.test(url)) {
            url = 'https://' + url;
        }

        return url;
    }

    function submitAfterNameValidation() {
        // Wait until the original submit event has finished. Calling
        // requestSubmit() from inside that event can be ignored as a
        // re-entrant submission by the browser.
        window.setTimeout(function() {
            allowValidatedSubmit = true;

            if (typeof form.requestSubmit === 'function') {
                form.requestSubmit();
            } else {
                form.submit();
            }
        }, 0);
    }

    function hideNameRetryNotice() {
        const notice = document.querySelector('.inception-notes-name-warning');
        if (notice) {
            notice.remove();
        }
    }

    function showNameRetryNotice() {
        hideNameRetryNotice();

        const notice = document.createElement('div');
        notice.className = 'inception-notes-name-warning';
        notice.innerHTML = '<div class="inception-notes-name-warning-box" role="alertdialog" aria-modal="true"><p>Please enter your name before saving.</p><button type="button" class="button button-primary">Retry</button></div>';

        notice.querySelector('button').addEventListener('click', function() {
            const nameWasEntered = promptForEditorName();

            if (nameWasEntered) {
                hideNameRetryNotice();
                submitAfterNameValidation();
            }
        });

        (notesWrap || document.body).appendChild(notice);
        notice.querySelector('button').focus();
    }

    function promptForEditorName() {
        const editorName = window.prompt('Who is saving these notes?');

        if (editorName === null) {
            return false;
        }

        const cleanedName = editorName.trim();
        if (cleanedName.length < 2) {
            showNameRetryNotice();
            return false;
        }

        nameInput.value = cleanedName;
        return true;
    }

    function updateNotesMenuBadge() {
        const hasNotes = window.inceptionTechBoostNotesHasNotes === true;
        const notesLink = Array.from(document.querySelectorAll('#adminmenu a')).find((link) => {
            return link.href && link.href.indexOf('page=inception-notes') !== -1;
        });

        if (notesLink) {
            notesLink.querySelectorAll('.update-plugins').forEach((badge) => badge.remove());
            notesLink.textContent = 'Notes';

            if (hasNotes) {
                notesLink.insertAdjacentHTML('beforeend', ' <span class="update-plugins count-1 inception-techboost-notes-badge"><span class="plugin-count">!</span></span>');
            }
        }

        const adminBarLink = document.querySelector('#wp-admin-bar-inception-notes > .ab-item');
        if (adminBarLink) {
            adminBarLink.textContent = hasNotes ? 'Notes (!)' : 'Notes';
        }
    }

    updateNotesMenuBadge();

    if (highLevelLinks && addHighLevelLink) {
        addHighLevelLink.addEventListener('click', function() {
            const row = document.createElement('div');
            row.className = 'inception-notes-link-row';
            row.innerHTML = '<input type="url" name="inception_techboost_notes_highlevel_links[]" value="" class="regular-text" placeholder="https://"><button type="button" class="button inception-notes-open-link">Open</button>';
            highLevelLinks.appendChild(row);
            row.querySelector('input').focus();
        });
    }

    document.addEventListener('click', function(e) {
        const button = e.target.closest('.inception-notes-open-link');
        if (!button) {
            return;
        }

        const row = button.closest('.inception-notes-link-row');
        const input = row ? row.querySelector('input[type="url"]') : null;
        const url = input ? normalizeOpenUrl(input.value) : '';

        if (url === '') {
            if (input) {
                input.focus();
            }
            return;
        }

        window.open(url, '_blank', 'noopener,noreferrer');
    });

    if (!form || !nameInput) return;

    form.addEventListener('submit', function(e) {
        if (allowValidatedSubmit) {
            allowValidatedSubmit = false;
            return;
        }

        e.preventDefault();

        if (promptForEditorName()) {
            submitAfterNameValidation();
        }
    });
});
</script>
