import $ from 'jquery';


// Khai báo các biến trạng thái chính để quản lý lịch sử các trạng thái giao diện
let historyStates: string[] = [];  // Lưu trữ lịch sử HTML của trang
let currentStateIndex: number = -1;  // Chỉ số trạng thái hiện tại trong lịch sử
let currentElement: JQuery<HTMLElement> | null = null;  // Phần tử hiện đang chỉnh sửa
let isEditMode: boolean = false;  // Xác định chế độ chỉnh sửa có được bật không


// Định nghĩa kiểu dữ liệu cho phần tử giao diện
interface Elements {
    toggleEditModeButton: JQuery<HTMLElement>;
    tabBar: JQuery<HTMLElement>;
    textOptions: JQuery<HTMLElement>;
    imageOptions: JQuery<HTMLElement>;
    boxOptions: JQuery<HTMLElement>;
    bgOptions: JQuery<HTMLElement>;
    textColorInput: JQuery<HTMLInputElement>;
    textBackgroundInput: JQuery<HTMLInputElement>;
    textContentInput: JQuery<HTMLInputElement>;
    imageURLInput: JQuery<HTMLInputElement>;
    imageUploadInput: JQuery<HTMLInputElement>;
    logoSizeInput: JQuery<HTMLInputElement>;
    sizeValueSpan: JQuery<HTMLElement>;
    lineHeightInput: JQuery<HTMLInputElement>;
}

// Các phần tử giao diện được chọn từ DOM, chứa các thành phần tương tác trong giao diện chỉnh sửa
const $elements: Elements = {
    // Nút để bật hoặc tắt chế độ chỉnh sửa
    toggleEditModeButton: $('#toggleEditMode'),

    // Thanh công cụ hiển thị các tùy chọn khi chỉnh sửa phần tử
    tabBar: $('#tabBar'),

    // Phần tùy chọn cho chỉnh sửa văn bản, bao gồm các thiết lập màu, nội dung và khoảng cách dòng
    textOptions: $('#textOptions'),

    // Phần tùy chọn cho chỉnh sửa ảnh, bao gồm URL ảnh và kích thước
    imageOptions: $('#imageOptions'),

    // Phần tùy chọn cho chỉnh sửa hộp (box), có thể dùng để thay đổi kích thước hoặc màu nền
    boxOptions: $('#BoxOptions'),

    // Phần tùy chọn cho chỉnh sửa nền, cho phép thiết lập màu nền
    bgOptions: $('#bgOptions'),

    // Trường nhập liệu cho màu chữ, cho phép người dùng chọn màu chữ của tiêu đề hoặc văn bản
    textColorInput: $('#textColor'),

    // Trường nhập liệu cho màu nền của văn bản, cho phép người dùng thay đổi màu nền của tiêu đề
    textBackgroundInput: $('#textBackground'),

    // Trường nhập liệu cho nội dung văn bản, dùng để chỉnh sửa nội dung của tiêu đề
    textContentInput: $('#textContent'),

    // Trường nhập liệu URL của ảnh, cho phép người dùng nhập URL để thay đổi ảnh
    imageURLInput: $('#imageURL'),

    // Trường tải lên ảnh, cho phép người dùng tải ảnh trực tiếp từ máy tính
    imageUploadInput: $('#imageUpload'),

    // Trường nhập liệu cho kích thước logo, dùng để điều chỉnh kích thước ảnh hoặc logo
    logoSizeInput: $('#logoSize'),

    // Hiển thị giá trị kích thước hiện tại của ảnh, được cập nhật khi thay đổi kích thước logo
    sizeValueSpan: $('#sizeValue'),

    // Trường nhập liệu khoảng cách dòng, giúp người dùng điều chỉnh khoảng cách dòng của văn bản
    lineHeightInput: $('#lineHeight')
};

// Lắng nghe sự kiện scroll để chuyển chế độ cố định cho thanh công cụ khi cuộn xuống
$(window).scroll((): void => {
    const scrollTop: number = $(window).scrollTop() ?? 0;
    $(".mode-edit").toggleClass('fixed', scrollTop > 100);
});

/**
 * Bật/tắt chế độ chỉnh sửa.
 * Khi bật, các phần tử sẽ có thể chỉnh sửa, và ngược lại.
 */
$elements.toggleEditModeButton.on('click', function () {
    isEditMode = !isEditMode;
    $('.editable-element').toggleClass('editable', isEditMode);
    $elements.toggleEditModeButton.html(isEditMode ? '<i class="fas fa-sign-out-alt"></i> Thoát chỉnh sửa' : '<i class="far fa-edit"></i> Chỉnh sửa');
    $elements.tabBar.hide();
});

/**
 * Cập nhật màu sắc của phần tử hiện tại.
 * @param type - Loại màu sắc cần thay đổi ('text' hoặc 'bg').
 * @param color - Mã màu cần áp dụng cho phần tử.
 */
function updateElementColor(type: 'text' | 'bg', color: string): void {
    if (!currentElement) return;
    const className = type === 'text' ? `text-[${color}]` : `bg-[${color}]`;
    currentElement.find('.title').attr('class', function (i, c) {
        return c ? c.split(' ').filter(cls => !cls.startsWith(type)).concat(className).join(' ') : className;
    });
}

/**
 * Xử lý tải ảnh lên và gán ảnh mới cho phần tử.
 * @param event - Sự kiện thay đổi từ ô tải ảnh lên.
 */
function handleImageUpload(event: JQuery.ChangeEvent): void {
    const file = (event.target as HTMLInputElement).files?.[0];
    if (!file) return;
    const reader = new FileReader();
    reader.onload = function () {
        currentElement?.find('img').attr('src', reader.result as string);
    };
    reader.readAsDataURL(file);
}

/**
 * Bắt đầu chế độ chỉnh sửa cho phần tử được chọn.
 * @param event - Sự kiện click để bắt đầu chỉnh sửa.
 * @param button - Nút bấm để kích hoạt chỉnh sửa phần tử.
 */
function startEditing(event: JQuery.ClickEvent, button: HTMLElement): void {
    if (!isEditMode) return;
    event.stopPropagation();
    currentElement = $(button).closest('.editable-element');
    $elements.tabBar.show();
    setupOptions();
}

/**
 * Thiết lập các tùy chọn cho phần tử đang chỉnh sửa dựa trên loại của nó.
 */
function setupOptions(): void {
    if (!currentElement) return;
    const elementType = currentElement.data('type') as string;
    if (elementType === 'box') {
        showBoxOptions(currentElement);
    } else if (elementType === 'title') {
        showTextOptions(currentElement.find('.title'));
    } else if (elementType === 'background') {
        showBgOptions();
    } else if (elementType === 'image') {
        showImageOptions();
    }
}

// Các hàm hiển thị và xử lý tùy chọn (showTextOptions, showBgOptions, showImageOptions, showBoxOptions)
// Thêm vào TypeScript, định nghĩa tham số và chú thích

/**
 * Hiển thị các tùy chọn văn bản cho phần tử tiêu đề.
 * @param $title - Phần tử tiêu đề hiện tại.
 */
function showTextOptions($title: JQuery<HTMLElement>): void {
    // Hiển thị các tùy chọn và thiết lập giá trị hiện tại cho ô input
    $elements.textOptions.show();
    $elements.boxOptions.hide();
    $elements.imageOptions.hide();
    $elements.bgOptions.hide();
    $elements.textContentInput.val($title.text().trim());
    $elements.textColorInput.val(extractColor($title, 'text'));
    $elements.textBackgroundInput.val(extractColor($title, 'bg'));
    $elements.lineHeightInput.val(parseFloat($title.css('line-height')));
    $('#fontSize').val(parseFloat($title.css('font-size')));
    $('#fontFamily').val($title.css('font-family'));
    $('#BgcolorCode').val(extractColor($title, 'bg'));
    $('#colorCodeTitle').val(extractColor($title, 'text'));
}

/**
 * Trích xuất mã màu từ lớp CSS của phần tử.
 * @param $element - Phần tử để lấy mã màu.
 * @param type - Loại mã màu ('text' hoặc 'bg').
 * @returns Mã màu đã được trích xuất hoặc '#000000' nếu không có.
 */
function extractColor($element: JQuery<HTMLElement>, type: 'text' | 'bg'): string {
    const regex = new RegExp(`${type}-\\[([#0-9A-Fa-f]+)\\]`);
    const match = $element.attr('class')?.match(regex);
    return match ? match[1] : '#000000';
}

/**
 * Lưu trạng thái hiện tại vào lịch sử trạng thái.
 */
function saveCurrentState(): void {
    const currentHTML = document.documentElement.innerHTML;
    if (currentStateIndex < historyStates.length - 1) {
        historyStates = historyStates.slice(0, currentStateIndex + 1);
    }
    historyStates.push(currentHTML);
    currentStateIndex++;
}


// hàm xử lý chỉnh sửa box 
function showBoxOptions(currentElement: JQuery<HTMLElement>): void {
    // Đảm bảo $elements có kiểu chính xác
    // .show() và .hide() trả về đối tượng jQuery, nên không cần lưu giá trị trả về
    $elements.boxOptions.show();
    $elements.textOptions.hide();
    $elements.imageOptions.hide();

    // Lấy phần tử có class 'title' từ currentElement, với kiểu JQuery<HTMLElement>
    const $title: JQuery<HTMLElement> = currentElement.find('.title');

    // Sử dụng phương thức extractColor để lấy màu nền, và gán giá trị vào các input
    // Giả sử extractColor trả về kiểu string hoặc null
    $('#BackgroundColor').val(extractColor(currentElement, 'bg') ?? '');  // Gán giá trị mặc định nếu null
    $('#InputCodeBox').val(extractColor(currentElement, 'bg') ?? '');
    $('#changeInputBox').val(extractColor(currentElement, 'bg') ?? '');

    // Lấy và gán giá trị text của title vào input textContentInput
    // .text() trả về string
    $elements.textContentInput.val($title.text().trim());

    // Lấy màu sắc văn bản từ title và gán vào các input tương ứng
    $elements.textColorInput.val(extractColor($title, 'text') ?? '');
    $elements.textBackgroundInput.val(extractColor($title, 'bg') ?? '');

    // Lấy chiều cao dòng (line-height) của title, và ép kiểu sang float
    $elements.lineHeightInput.val(parseFloat($title.css('line-height') ?? '0'));

    // Lấy kích thước font của title, ép kiểu sang float
    $('#fontSize').val(parseFloat($title.css('font-size') ?? '0'));
   
    // Lấy font-family của title và gán vào input fontFamily
    $('#fontFamily').val($title.css('font-family') ?? '');

    // Gán màu nền của title vào input BgcolorCode
    const a: string | undefined = $('#BgcolorCode').val(extractColor($title, 'bg') ?? '') as string;
    console.log(a);  // In ra giá trị lấy từ extractColor

    // Gán màu sắc của title vào input colorCodeTitle
    $('#colorCodeTitle').val(extractColor($title, 'text') ?? '');

    // Gán màu biên của currentElement vào input borderColorBox
    $('#borderColorBox').val(extractColor(currentElement, 'border') ?? '');
}

