// Import external files first. Eventually this will be broken up in to smaller files.
import {
    clean_filename,
    format_bytes,
    guess_file_name,
    guess_file_extension,
    get_file_hash
} from './ae_utils__files';
import { get_obj_li_w_match_prop } from './ae_utils__get_obj_li_w_match_prop';
import { file_extension_icon } from './ae_utils__file_extension_icon';
import { file_extension_icon_lucide } from './ae_utils__file_extension_icon_lucide';
import {
    process_permission_checks,
    compare_access_levels
} from './ae_utils__perm_checks';
import { iso_datetime_formatter } from './ae_utils__datetime_format';
import { is_datetime_recent } from './ae_utils__is_datetime_recent';
import { extract_prefixed_form_data } from './ae_utils__extract_prefixed_form_data';
import { to_title_case } from './ae_utils__to_title_case';
import { process_data_string } from './ae_utils__process_data_string';
import { set_obj_prop_display_name } from './ae_utils__set_obj_prop_display_name';
import { return_obj_type_path } from './ae_utils__return_obj_type_path';
import { format_html } from './ae_utils__format_html';
import {
    combine_iv_and_base64,
    encrypt_content,
    encrypt_wrapper,
    decrypt_content,
    decrypt_wrapper
} from './ae_utils__crypto';

export type key_str = {
    [key: string]: string;
};

export type key_val = {
    [key: string]: any;
};

/* This utility function will add commas to a number. */
function number_w_commas(x: number | string) {
    if (!x) return '0';
    return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}

// This function will update the URL and send a message to the parent window (iframe).
// The name should be something like "example_id".
// Svelte specific:
// WARNING: Avoid using `history.pushState(...)` and `history.replaceState(...)` as these will conflict with SvelteKit's router. Use the `pushState` and `replaceState` imports from `$app/navigation` instead.
// Updated 2024-03-02
// import { pushState, replaceState } from '$app/navigation';

function handle_url_and_message(name: string, value: null | string) {
    console.log(`*** handle_url_and_message() *** name=${name} value=${value}`);

    const location = window.location.href;
    // console.log('location:', location);
    const url = new URL(location);
    // console.log('url:', url);

    if (value) {
        url.searchParams.set(name, value);
        history.pushState({}, '', url);

        // console.log('url:', url);
        // pushState(url.href, {});
        // pushState(url.search, {});
        // replaceState(url.href, {});

        const message = { name: value };
        window.parent.postMessage(message, '*');
    } else {
        url.searchParams.delete(name);
        history.pushState({}, '', url);

        // console.log('url:', url);
        // pushState({}, '', url.search);
        // pushState(url.href, {});
        // replaceState(url.href, {});

        const message = { name: null };
        window.parent.postMessage(message, '*');
    }
    // console.log('Message sent to parent (iframe):', message);
}

// ALERT: Not referenced anywhere -2026-02-03
function create_a_element({
    account_id,
    base_url,
    hosted_file_id,
    filename = null,
    extension = null,
    text = 'Download',
    class_li = 'text-blue-500'
}: {
    account_id: string;
    base_url: string;
    hosted_file_id: string;
    filename?: string | null;
    extension?: string | null;
    text?: string;
    class_li?: string;
}) {
    return `<a href="${base_url}/v3/action/hosted_file/${hosted_file_id}/download?key=${account_id}&filename=${filename}" class="${class_li}">${text}</a>`;
}

// ALERT: Not referenced anywhere -2026-02-03
function create_img_element({
    account_id,
    base_url,
    hosted_file_id,
    filename = null,
    extension = null,
    class_li = 'max-w-64',
    style = '',
    inc_link = false
}: {
    account_id: string;
    base_url: string;
    hosted_file_id: string;
    filename?: string | null;
    extension?: string | null;
    class_li?: string;
    style?: string;
    inc_link?: boolean;
}) {
    let img_html = '';
    if (filename) {
        img_html = `<img src="${base_url}/v3/action/hosted_file/${hosted_file_id}/download?key=${account_id}&filename=${filename}" class="${class_li}" style="${style}" />`;
    } else {
        img_html = `<img src="${base_url}/v3/action/hosted_file/${hosted_file_id}/download?key=${account_id}" class="${class_li}" style="${style}" />`;
    }

    if (inc_link) {
        const a_html = create_a_element({
            account_id: account_id,
            base_url: base_url,
            hosted_file_id: hosted_file_id,
            filename: filename,
            extension: extension
        });
        img_html = `<div class="ae_img ae_a">${img_html}${a_html}</div>`;
    }

    return img_html;
}

// ALERT: Not referenced anywhere -2026-02-03
function create_video_element({
    account_id,
    base_url,
    hosted_file_id,
    filename = null,
    extension = null,
    class_li = 'max-w-64',
    inc_link = false
}: {
    account_id: string;
    base_url: string;
    hosted_file_id: string;
    filename?: string | null;
    extension?: string | null;
    class_li?: string;
    inc_link?: boolean;
}) {
    let video_html = '';
    if (filename) {
        video_html = `<video src="${base_url}/v3/action/hosted_file/${hosted_file_id}/download?key=${account_id}&filename=${filename}" controls class="${class_li}"></video>`;
    } else {
        video_html = `<video src="${base_url}/v3/action/hosted_file/${hosted_file_id}/download?key=${account_id}" controls class="${class_li}"></video>`;
    }

    if (inc_link) {
        const a_html = create_a_element({
            account_id: account_id,
            base_url: base_url,
            hosted_file_id: hosted_file_id,
            filename: filename,
            extension: extension
        });
        video_html = `<div class="ae_video ae_a">${video_html}${a_html}</div>`;
    }

    return video_html;
}

// // Clear the quick access type
// function clear_access_type() {
//     // NOTE: I think it makes since to reset this to anonymous even if logged in as an admin or similar.
//     window.localStorage.setItem('access_type', 'anonymous');

//     // $ae_loc.access_type = null; // 'anonymous';
//     $ae_loc.access_type = 'anonymous';
//     trigger = 'process_permission_check';

//     show_passcode_input = false;

//     // $ae_loc = $ae_loc; // Trigger Svelte just in case
//     // ae_loc.set($ae_loc);
//     // console.log($ae_loc);

// return true;
// }

// This function will take a long string (sentences or paragraphs) of text and return an estimated number of words.
function count_words(text: string) {
    if (!text || text.length < 1) {
        return 0;
    }
    const count = text.trim().split(/\s+/).length;

    return count;
}

// Updated 2024-06-19
// This function behaves weirdly. It needs to be reviewed and updated.
export const shorten_string = function shorten_string({
    string,
    max_length = 45,
    begin_length = 15,
    end_length = 5,
    wildcard_length = 3
}: {
    string: undefined | string;
    max_length?: number;
    begin_length?: number;
    end_length?: number;
    wildcard_length?: number;
}) {
    // console.log('*** shorten_filename() ***');

    if (!string || typeof string != 'string') {
        // console.log('Invalid string value passed');
        // return false;
        return '';
    }

    // NOTE: max_length is not the actual end result length. The actual max will be 45 characters.
    // 20 part 1 characters, 5 part 2 characters, 20 part 3 characters

    // let length = string.length;
    const char_over = string.length - max_length;
    let new_string = null;
    let wildcards = char_over;
    if (char_over > 0) {
        const part1 = string.slice(0, begin_length);

        let part2 = '';
        if (char_over > 5) {
            wildcards = 5;
        } else {
        }

        if (wildcard_length) {
            part2 = '.'.repeat(wildcard_length);
        } else {
            part2 = '.'.repeat(wildcards);
        }

        const part3 = string.slice(end_length * -1);

        new_string = part1 + part2 + part3;
    } else {
        new_string = string;
    }
    return new_string;
};

/**
 * Returns a partially-obscured email address for display to non-trusted users.
 * Shows the first 3 characters of the local part + *** + the full domain.
 * Example: "john.doe@example.com" → "joh***@example.com"
 * Trusted staff should receive the full address; pass it through unmodified.
 */
export function obscure_email(email: string | null | undefined): string {
    if (!email) return '';
    const at = email.indexOf('@');
    if (at < 0) return email;
    return `${email.slice(0, Math.min(3, at))}***${email.slice(at)}`;
}

/**
 * Strips HTML tags from a string.
 */
export function strip_html(html: string): string {
    if (!html) return '';
    return html.replace(/<[^>]*>?/gm, '');
}

// Svelte action to set focus on an element
function set_focus(node: HTMLElement, focus: boolean) {
    if (focus) {
        node.focus();
    }
    return {
        update(new_focus: boolean) {
            if (new_focus) {
                node.focus();
            }
        }
    };
}

// Updated 2024-06-19
// This function should return a shorted version of a filename if over the max length. It should always contain at least the first character of the original filename and the complete extension.
// Example 1: The Original Long File Name.pdf -> The Orig....pdf
// Example 2: The Original Long File Name.html -> The Ori....html
function shorten_filename({
    filename,
    max_length = 20,
    slice_end_at = 15,
    max_end_length = 5
}: {
    filename: string;
    max_length?: number;
    slice_end_at?: number;
    max_end_length?: number;
}) {
    // console.log('*** shorten_filename() ***');

    if (typeof filename !== 'string' || filename.length <= max_length) {
        return filename;
    }

    let new_filename = null;
    const char_over = filename.length - max_length;
    let wildcards = char_over - 4; // The number of characters over the max length
    if (wildcards < 1) {
        return filename; // No point in changing the filename?
    }

    const part_1 = filename.slice(0, slice_end_at);
    if (wildcards > 3) {
        wildcards = 3;
    } else {
    }
    const part_2 = '.'.repeat(wildcards);
    const part_3 = filename.slice(max_end_length * -1);

    new_filename = part_1 + part_2 + part_3;

    return new_filename;
}

export const ae_util = {
    is_datetime_recent: is_datetime_recent,
    process_permission_checks: process_permission_checks,
    compare_access_levels: compare_access_levels,
    iso_datetime_formatter: iso_datetime_formatter,
    clean_filename: clean_filename,
    format_bytes: format_bytes,
    number_w_commas: number_w_commas,
    guess_file_name: guess_file_name,
    guess_file_extension: guess_file_extension,
    get_file_hash: get_file_hash,
    get_obj_li_w_match_prop: get_obj_li_w_match_prop,
    extract_prefixed_form_data: extract_prefixed_form_data,
    process_data_string: process_data_string,
    handle_url_and_message: handle_url_and_message,
    create_a_element: create_a_element,
    create_img_element: create_img_element,
    create_video_element: create_video_element,
    count_words: count_words,
    to_title_case: to_title_case,
    shorten_string: shorten_string,
    shorten_filename: shorten_filename,
    obscure_email: obscure_email,
    strip_html: strip_html,
    file_extension_icon: file_extension_icon,
    file_extension_icon_lucide: file_extension_icon_lucide,
    format_html: format_html,
    set_obj_prop_display_name: set_obj_prop_display_name,
    return_obj_type_path: return_obj_type_path,
    combine_iv_and_base64: combine_iv_and_base64,
    encrypt_content: encrypt_content,
    encrypt_wrapper: encrypt_wrapper,
    decrypt_content: decrypt_content,
    decrypt_wrapper: decrypt_wrapper,
    set_focus: set_focus
};
