modify the script to delete every RIFF (Resource Interchange File Format) image files before processing the images.

import os
import shutil
import re
import unicodedata
import logging
import csv
from PIL import Image, ExifTags
import piexif

# ----------------------------------------------------------------------------------------------------------------------
# Configuration
# ----------------------------------------------------------------------------------------------------------------------

# Configure logging
logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s')

# Define file paths (Update these paths as needed)
folder_path = r'C:\Users\anhb3\Desktop\long\test\Thời trang quyến rũ'       # For Image Processing
html_folder_path = r'C:\Users\anhb3\Desktop\long\test\Thời trang quyến rũ'            # For HTML Processing
csv_file_path = r'C:\Users\anhb3\Desktop\long\chen_anh.csv'                 # CSV for Image HTML
links_file_path = r'C:\Users\anhb3\Desktop\long\di_link.txt'                # TXT for Links

# ----------------------------------------------------------------------------------------------------------------------
# Image Processing Functions
# ----------------------------------------------------------------------------------------------------------------------

def is_image_readable(file_path):
    """
    Check if an image file is readable.

    Args:
        file_path (str): Path to the image file.

    Returns:
        bool: True if the image is readable, False otherwise.
    """
    try:
        with Image.open(file_path) as img:
            img.verify()
        return True
    except Exception:
        return False

def delete_unreadable_images(folder_path):
    """
    Delete unreadable image files within a folder.

    Args:
        folder_path (str): Path to the folder to scan.
    """
    supported_formats = ('.jpg', '.jpeg', '.png', '.bmp', '.gif', '.tiff', '.webp')
    deleted_files = 0
    for root, _, files in os.walk(folder_path):
        for file in files:
            if file.lower().endswith(supported_formats):
                file_path = os.path.join(root, file)
                if not is_image_readable(file_path):
                    try:
                        os.remove(file_path)
                        logging.info(f"Deleted unreadable image: {file_path}")
                        deleted_files += 1
                    except Exception as e:
                        logging.error(f"Error deleting {file_path}: {e}")
    logging.info(f"Total unreadable image files deleted: {deleted_files}")

def count_image_files(folder_path, extensions=('.jpg', '.jpeg', '.png', '.bmp', '.gif', '.tiff', '.webp')):
    """
    Count the number of image files in a folder.

    Args:
        folder_path (str): Path to the folder.
        extensions (tuple): Tuple of file extensions to count.

    Returns:
        int: Number of image files.
    """
    return len([f for f in os.listdir(folder_path) if f.lower().endswith(extensions)])

def delete_subfolders_with_few_images(folder_path, threshold=3):
    """
    Delete subfolders containing a number of image files less than or equal to a threshold.

    Args:
        folder_path (str): Path to the parent folder.
        threshold (int): Threshold number of images. Default is 3.
    """
    supported_formats = ('.jpg', '.jpeg', '.png', '.bmp', '.gif', '.tiff', '.webp')
    deleted_folders = 0
    for root, dirs, _ in os.walk(folder_path, topdown=False):
        for dir_name in dirs:
            subfolder_path = os.path.join(root, dir_name)
            try:
                image_count = count_image_files(subfolder_path, extensions=supported_formats)
                if image_count <= threshold:
                    shutil.rmtree(subfolder_path)
                    logging.info(f"Deleted subfolder: {subfolder_path} (contained {image_count} image files)")
                    deleted_folders += 1
            except Exception as e:
                logging.error(f"Error processing subfolder {subfolder_path}: {e}")
    logging.info(f"Total subfolders deleted: {deleted_folders}")

def trim_image_files(folder_path, target_count=4):
    """
    Trim the number of image files in subfolders to a target count.

    Args:
        folder_path (str): Path to the parent folder.
        target_count (int): Desired maximum number of images per subfolder. Default is 4.
    """

    supported_formats = ('.jpg', '.jpeg', '.png', '.bmp', '.gif', '.tiff', '.webp')

    # Improved sorting logic to prioritize lower indices
    def file_sort_key(x):
        """
        Extract the numerical index from the filename for sorting.

        Args:
            x (str): Filename.

        Returns:
            int: Extracted index or a large number if not found.
        """
        match = re.search(r'_(\d+).(jpg|jpeg|png|bmp|gif|tiff|webp)$', x, re.IGNORECASE)
        if match:
            return int(match.group(1))
        else:
            # If no index is found, assign a large number to push it to the end
            return float('inf')

    for root, _, files in os.walk(folder_path):
        image_files = [f for f in files if f.lower().endswith(supported_formats)]
        image_count = len(image_files)

        if image_count <= target_count:
            continue

        # Sort images in ascending order based on their numerical index
        image_files.sort(key=file_sort_key)

        # Select files to delete beyond the target count
        files_to_delete = image_files[target_count:]

        for file in files_to_delete:
            file_path = os.path.join(root, file)
            try:
                os.remove(file_path)
                logging.info(f"Deleted excess image: {file_path}")
            except Exception as e:
                logging.error(f"Error deleting {file_path}: {e}")

def convert_jpg_to_rgb(folder_path):
    """
    Convert all .jpg and .jpeg images to RGB mode.

    Args:
        folder_path (str): Path to the folder containing images.
    """
    for root, _, files in os.walk(folder_path):
        for file in files:
            if file.lower().endswith(('.jpg', '.jpeg')):
                file_path = os.path.join(root, file)
                try:
                    with Image.open(file_path) as img:
                        # Apply EXIF orientation to ensure correct dimensions
                        img = apply_exif_orientation(img)

                        # Check if image is not in RGB mode
                        if img.mode != 'RGB':
                            img = img.convert('RGB')
                            # Save the image back to the same file
                            img.save(file_path, format='JPEG', quality=85)
                            logging.info(f"Converted image to RGB: {file_path}")
                        else:
                            logging.debug(f"Image already in RGB mode: {file_path}")
                except Exception as e:
                    logging.error(f"Error processing {file_path}: {e}")

def is_image_all_white(img):
    """
    Check if an image is entirely white.

    Args:
        img (PIL.Image.Image): The image to check.

    Returns:
        bool: True if the image is all white, False otherwise.
    """
    try:
        if img.mode != 'RGB':
            img = img.convert('RGB')
        extrema = img.getextrema()
        # Extrema is a list where each item is a tuple of (min, max) for each channel
        # For white image, all channels should have min and max as 255
        return all(channel_extremum == (255, 255) for channel_extremum in extrema)
    except Exception as e:
        logging.error(f"Error checking if image is all white: {e}")
        return False

def delete_blank_images(folder_path):
    """
    Delete images that are entirely white.

    Args:
        folder_path (str): Path to the folder to scan.
    """
    supported_formats = ('.jpg', '.jpeg', '.png', '.bmp', '.gif', '.tiff', '.webp')
    deleted_files = 0
    for root, _, files in os.walk(folder_path):
        for file in files:
            if file.lower().endswith(supported_formats):
                file_path = os.path.join(root, file)
                try:
                    with Image.open(file_path) as img:
                        img = apply_exif_orientation(img)
                        if is_image_all_white(img):
                            os.remove(file_path)
                            logging.info(f"Deleted blank (all white) image: {file_path}")
                            deleted_files += 1
                except Exception as e:
                    logging.error(f"Error processing {file_path} for blank check: {e}")
    logging.info(f"Total blank images deleted: {deleted_files}")

def convert_and_resize_images(folder_path, target_width=1200):
    """
    Convert all images to JPG and resize them to a target width while maintaining aspect ratio.

    Args:
        folder_path (str): Path to the folder containing images.
        target_width (int): The target width for the resized images. Default is 1200 pixels.
    """
    # Define supported image formats excluding '.jpg' and '.jpeg'
    supported_formats = ('.png', '.bmp', '.gif', '.tiff', '.webp')

    for root, _, files in os.walk(folder_path):
        for file in files:
            file_lower = file.lower()
            file_path = os.path.join(root, file)

            try:
                # Handle .jpg and .jpeg files
                if file_lower.endswith(('.jpg', '.jpeg')):
                    with Image.open(file_path) as img:
                        img = apply_exif_orientation(img)

                        # Resize if necessary (regardless of size)
                        if img.width != target_width:
                            ratio = target_width / float(img.width)
                            new_size = (target_width, int(img.height * ratio))
                            img = img.resize(new_size, Image.LANCZOS)
                            img.save(file_path, format='JPEG', quality=85)
                            logging.info(f"Resized image: {file_path}")
                        else:
                            logging.info(f"Image already at target size: {file_path}")

                # Handle other supported formats
                elif file_lower.endswith(supported_formats):
                    with Image.open(file_path) as img:
                        img = apply_exif_orientation(img)

                        # Convert to RGB if necessary
                        if img.mode in ("RGBA", "P", "LA"):
                            img = img.convert("RGB")
                            logging.debug(f"Converted image mode to RGB: {file_path}")

                        # Resize if necessary (regardless of size)
                        if img.width != target_width:
                            ratio = target_width / float(img.width)
                            new_size = (target_width, int(img.height * ratio))
                            img = img.resize(new_size, Image.LANCZOS)
                            logging.info(f"Resized image: {file_path}")

                        # Save as JPG
                        new_file_path = os.path.splitext(file_path)[0] + '.jpg'
                        img.save(new_file_path, 'JPEG', quality=85)
                        logging.info(f"Converted and saved image as JPG: {new_file_path}")

                    # Remove the original file
                    os.remove(file_path)
                    logging.info(f"Removed original image: {file_path}")

                else:
                    logging.debug(f"Unsupported file format, skipping: {file_path}")

            except Exception as e:
                logging.error(f"Error processing {file_path}: {e}")

def apply_exif_orientation(img):
    """
    Apply EXIF orientation to the image to ensure correct dimensions.

    Args:
        img (PIL.Image.Image): The image to be oriented.

    Returns:
        PIL.Image.Image: The oriented image.
    """
    try:
        exif = img._getexif()
        if exif is not None:
            for key, value in exif.items():
                tag = ExifTags.TAGS.get(key, key)
                if tag == 'Orientation':
                    orientation = value
                    break
            else:
                orientation = None

            if orientation == 3:
                img = img.rotate(180, expand=True)
                logging.debug("Applied EXIF orientation: rotated 180 degrees")
            elif orientation == 6:
                img = img.rotate(270, expand=True)
                logging.debug("Applied EXIF orientation: rotated 270 degrees")
            elif orientation == 8:
                img = img.rotate(90, expand=True)
                logging.debug("Applied EXIF orientation: rotated 90 degrees")
    except Exception as e:
        logging.warning(f"Could not apply EXIF orientation: {e}")
    return img


def rename_jpg_files(image_folder_path):
    """
    Rename .jpg files in each subfolder based on the subfolder name.

    Args:
        image_folder_path (str): Path to the parent folder containing subfolders with images.
    """

    def sanitize_filename(name):
        """
        Sanitize the folder name by replacing specific characters based on a mapping,
        converting to lowercase, and replacing spaces and special characters with hyphens.

        Args:
            name (str): Original folder name.

        Returns:
            str: Sanitized folder name.
        """
        # Define the character mapping based on the provided original and result lists
        char_map = {
            # Lowercase letters and their mappings
            'a': 'a', 'à': 'a', 'á': 'a', 'ả': 'a', 'ã': 'a', 'ạ': 'a',
            'ă': 'a', 'ằ': 'a', 'ắ': 'a', 'ẳ': 'a', 'ẵ': 'a', 'ặ': 'a',
            'â': 'a', 'ấ': 'a', 'ầ': 'a', 'ẩ': 'a', 'ẫ': 'a', 'ậ': 'a',

            # 'b' to 'c'
            'b': 'b', 'c': 'c',

            # 'd' mappings
            'd': 'd', 'đ': 'd',

            # 'e' mappings
            'e': 'e', 'é': 'e', 'è': 'e', 'ẻ': 'e', 'ẽ': 'e', 'ẹ': 'e',
            'ê': 'e', 'ế': 'e', 'ề': 'e', 'ể': 'e', 'ễ': 'e', 'ệ': 'e',

            # 'g' to 'h'
            'g': 'g', 'h': 'h',

            # 'i' mappings
            'i': 'i', 'í': 'i', 'ì': 'i', 'ỉ': 'i', 'ĩ': 'i', 'ị': 'i',

            # 'k' to 'm'
            'k': 'k', 'l': 'l', 'm': 'm',

            # 'n' mapping
            'n': 'n',

            # 'o' mappings
            'o': 'o', 'ó': 'o', 'ò': 'o', 'ỏ': 'o', 'õ': 'o', 'ọ': 'o',
            'ô': 'o', 'ố': 'o', 'ồ': 'o', 'ổ': 'o', 'ỗ': 'o', 'ộ': 'o',
            'ơ': 'o', 'ớ': 'o', 'ờ': 'o', 'ở': 'o', 'ỡ': 'o', 'ợ': 'o',

            # 'p' to 's'
            'p': 'p', 'q': 'q', 'r': 'r', 's': 's',

            # 't' mapping
            't': 't',

            # 'u' mappings
            'u': 'u', 'ú': 'u', 'ù': 'u', 'ủ': 'u', 'ũ': 'u', 'ụ': 'u',
            'ư': 'u', 'ứ': 'u', 'ừ': 'u', 'ử': 'u', 'ữ': 'u', 'ự': 'u',

            # 'v' to 'z'
            'v': 'v', 'x': 'x', 'y': 'y', 'z': 'z',

            # Special characters and their replacements
            # ' ': '-', '-': '-', '_': '-', '.': '-', ',': '-', '/': '-', '\': ' - ', ' & ': ' and ',

            # Numbers
                                                                                                 '0': '0', '1': '1',
            '2': '2', '3': '3', '4': '4',
            '5': '5', '6': '6', '7': '7', '8': '8', '9': '9',

            # Uppercase letters (convert to lowercase)
            **{c.upper(): v for c, v in {
                # Include uppercase mappings
                'a': 'a', 'à': 'a', 'á': 'a', 'ả': 'a', 'ã': 'a', 'ạ': 'a',
                'ă': 'a', 'ằ': 'a', 'ắ': 'a', 'ẳ': 'a', 'ẵ': 'a', 'ặ': 'a',
                'â': 'a', 'ấ': 'a', 'ầ': 'a', 'ẩ': 'a', 'ẫ': 'a', 'ậ': 'a',
                'b': 'b', 'c': 'c',
                'd': 'd', 'đ': 'd',
                'e': 'e', 'é': 'e', 'è': 'e', 'ẻ': 'e', 'ẽ': 'e', 'ẹ': 'e',
                'ê': 'e', 'ế': 'e', 'ề': 'e', 'ể': 'e', 'ễ': 'e', 'ệ': 'e',
                'g': 'g', 'h': 'h',
                'i': 'i', 'í': 'i', 'ì': 'i', 'ỉ': 'i', 'ĩ': 'i', 'ị': 'i',
                'k': 'k', 'l': 'l', 'm': 'm',
                'n': 'n',
                'o': 'o', 'ó': 'o', 'ò': 'o', 'ỏ': 'o', 'õ': 'o', 'ọ': 'o',
                'ô': 'o', 'ố': 'o', 'ồ': 'o', 'ổ': 'o', 'ỗ': 'o', 'ộ': 'o',
                'ơ': 'o', 'ớ': 'o', 'ờ': 'o', 'ở': 'o', 'ỡ': 'o', 'ợ': 'o',
                'p': 'p', 'q': 'q', 'r': 'r', 's': 's',
                't': 't',
                'u': 'u', 'ú': 'u', 'ù': 'u', 'ủ': 'u', 'ũ': 'u', 'ụ': 'u',
                'ư': 'u', 'ứ': 'u', 'ừ': 'u', 'ử': 'u', 'ữ': 'u', 'ự': 'u',
                'v': 'v', 'x': 'x', 'y': 'y', 'z': 'z'
            }.items()}
        }

        sanitized = ''
        for char in name:
            if char in char_map:
                sanitized += char_map[char]
            elif char.isalnum():
                # Keep alphanumeric characters not in char_map
                sanitized += char.lower()
            else:
                # Replace any other character with a hyphen
                sanitized += '-'

        # Replace multiple consecutive hyphens with a single hyphen
        sanitized = re.sub(r'-+', '-', sanitized)

        # Remove leading and trailing hyphens
        sanitized = sanitized.strip('-')

        return sanitized

    for root, dirs, files in os.walk(image_folder_path):
        for dir_name in dirs:
            subfolder_path = os.path.join(root, dir_name)
            sanitized_base = sanitize_filename(dir_name)

            if not sanitized_base:
                logging.warning(f"Subfolder '{dir_name}' results in an empty base name after sanitization. Skipping...")
                continue

            # Gather all .jpg and .jpeg files
            jpg_files = [f for f in os.listdir(subfolder_path) if f.lower().endswith(('.jpg', '.jpeg'))]

            # Sort files to ensure consistent renaming order
            jpg_files.sort()

            for index, filename in enumerate(jpg_files, start=1):
                original_file_path = os.path.join(subfolder_path, filename)

                # Define the new filename
                new_filename = f"{sanitized_base}-{index}.jpg"
                new_file_path = os.path.join(subfolder_path, new_filename)

                # Check if the new filename already exists to avoid overwriting
                if os.path.exists(new_file_path):
                    logging.warning(
                        f"Cannot rename '{original_file_path}' to '{new_file_path}': Target file already exists.")
                    continue

                try:
                    os.rename(original_file_path, new_file_path)
                    logging.info(f"Renamed '{original_file_path}' to '{new_file_path}'")
                except Exception as e:
                    logging.error(f"Error renaming '{original_file_path}' to '{new_file_path}': {e}")

def add_metadata_to_images(folder_path):
    """
    Add metadata (Title, Subject, Tags, Comments) to .jpg images based on their subfolder's name.

    Args:
        folder_path (str): Path to the parent folder containing subfolders with images.
    """
    supported_formats = ('.jpg', '.jpeg')

    for root, dirs, files in os.walk(folder_path):
        for dir_name in dirs:
            subfolder_path = os.path.join(root, dir_name)
            metadata_value = dir_name  # Using subfolder's name as the metadata value

            # Iterate through each .jpg file in the subfolder
            for file in os.listdir(subfolder_path):
                if file.lower().endswith(supported_formats):
                    file_path = os.path.join(subfolder_path, file)
                    try:
                        # Load existing EXIF data
                        exif_dict = {}
                        if os.path.exists(file_path):
                            try:
                                exif_dict = piexif.load(file_path)
                            except piexif.InvalidImageDataError:
                                exif_dict = {"0th": {}, "Exif": {}, "GPS": {}, "1st": {}, "thumbnail": None}

                        # Define the metadata fields
                        title = metadata_value
                        subject = metadata_value
                        tags = metadata_value
                        comments = metadata_value

                        # Update ImageDescription (0th IFD)
                        exif_dict["0th"][piexif.ImageIFD.ImageDescription] = title.encode('utf-8')

                        # Update XPSubject (0th IFD) - Requires UTF-16LE encoding
                        exif_dict["0th"][piexif.ImageIFD.XPSubject] = subject.encode('utf-16le')

                        # Update XPKeywords (0th IFD) - Requires UTF-16LE encoding
                        exif_dict["0th"][piexif.ImageIFD.XPKeywords] = tags.encode('utf-16le')

                        # Update UserComment (Exif IFD)
                        user_comment_prefix = b'ASCII\x00\x00\x00'  # ASCII encoding prefix
                        user_comment = user_comment_prefix + comments.encode('utf-8')
                        exif_dict["Exif"][piexif.ExifIFD.UserComment] = user_comment

                        # Dump the updated EXIF data to bytes
                        exif_bytes = piexif.dump(exif_dict)

                        # Save the image with updated EXIF data
                        piexif.insert(exif_bytes, file_path)

                        logging.info(f"Added metadata to image: {file_path}")

                    except Exception as e:
                        logging.error(f"Error adding metadata to {file_path}: {e}")

# ----------------------------------------------------------------------------------------------------------------------
# HTML Processing Functions
# ----------------------------------------------------------------------------------------------------------------------

def delete_small_html_folders(folder_path, min_char_count=6000):
    """
    Delete folders containing .html files with content less than a minimum character count.

    Args:
        folder_path (str): Path to the parent folder.
        min_char_count (int): Minimum character count required. Default is 6000.
    """
    for dirpath, _, filenames in os.walk(folder_path, topdown=False):
        delete_folder = False

        for filename in filenames:
            if filename.lower().endswith('.html'):
                file_path = os.path.join(dirpath, filename)
                try:
                    with open(file_path, 'r', encoding='utf-8', errors='ignore') as file:
                        content = file.read()
                    if len(content) < min_char_count:
                        delete_folder = True
                        break
                except Exception as e:
                    logging.error(f"Error reading {file_path}: {e}")

        if delete_folder:
            try:
                shutil.rmtree(dirpath)
                logging.info(f"Deleted folder due to small HTML content: {dirpath}")
            except Exception as e:
                logging.error(f"Error deleting folder {dirpath}: {e}")

def remove_blank_lines(file_path):
    """
    Remove blank lines from a file.

    Args:
        file_path (str): Path to the file.
    """
    try:
        with open(file_path, 'r', encoding='utf-8') as file:
            lines = file.readlines()

        non_blank_lines = [line.rstrip() for line in lines if line.strip()]

        with open(file_path, 'w', encoding='utf-8') as file:
            file.write('\n'.join(non_blank_lines))
    except Exception as e:
        logging.error(f"Error processing {file_path}: {e}")

def remove_img_tags(file_path):
    """
    Remove all <img> tags from an HTML file.

    Args:
        file_path (str): Path to the HTML file.
    """
    try:
        with open(file_path, 'r', encoding='utf-8') as file:
            content = file.read()

        # Remove img tags using regex
        cleaned_content = re.sub(r'<img\b[^>]>', '', content, flags=re.IGNORECASE)

        with open(file_path, 'w', encoding='utf-8') as file:
            file.write(cleaned_content)
    except Exception as e:
        logging.error(f"Error processing {file_path}: {e}")

def replace_h1_tag(file_path):
    """
    Replace <h1 style="text-align: center;"> with <h1> in an HTML file.

    Args:
        file_path (str): Path to the HTML file.
    """
    try:
        with open(file_path, 'r', encoding='utf-8') as file:
            content = file.read()

        modified_content = content.replace('<h1 style="text-align: center;">', '<h1>')

        with open(file_path, 'w', encoding='utf-8') as file:
            file.write(modified_content)
    except Exception as e:
        logging.error(f"Error processing {file_path}: {e}")

def capitalize_first_letter_in_tags(content):
    """
    Capitalize the first letter of text inside HTML tags.

    Args:
        content (str): The HTML content as a string.

    Returns:
        str: Modified content with capitalized text.
    """
    # Function to capitalize text inside tags
    def capitalize_match(match):
        tag = match.group(1)
        text = match.group(2).strip()
        if text:
            return f"<{tag}>{text[0].upper()}{text[1:]}</{tag}>"
        else:
            return match.group(0)

    # Regex pattern to match tags and their content
    pattern = r'<([a-z0-9]+)(?:\s+[^>])?>([^<]+)</\1>'
    modified_content = re.sub(pattern, capitalize_match, content, flags=re.IGNORECASE)
    return modified_content

def combine_html_tags_into_same_line(content):
    """
    Combine specific HTML tags into the same line by removing unnecessary line breaks.

    Args:
    content (str): The HTML content as a string.

    Returns:
    str: Modified content with specific tags combined into the same line.
    """
    # Replace '>' followed by any whitespace and newline followed by '<' with '> <'
    content = re.sub(r'>\s*\n\s*<', '> <', content)
    return content

def combine_blockquote_lines_in_content(content):
    """
    Combine broken <blockquote> lines in HTML content.

    Args:
        content (str): HTML content as a string.

    Returns:
        str: Modified content with combined blockquotes.
    """
    lines = content.splitlines()
    combined_lines = []
    skip_next = False

    for i, line in enumerate(lines):
        if skip_next:
            skip_next = False
            continue

        line_stripped = line.strip()

        # Check for opening <blockquote> without closing tag
        if '<blockquote>' in line_stripped and '</blockquote>' not in line_stripped:
            if i + 1 < len(lines):
                next_line = lines[i + 1].strip()
                combined_line = line_stripped + ' ' + next_line
                combined_lines.append(combined_line)
                skip_next = True
            else:
                combined_lines.append(line_stripped)
        # Check for closing </blockquote> without opening tag
        elif '</blockquote>' in line_stripped and '<blockquote>' not in line_stripped:
            if combined_lines:
                combined_lines[-1] += ' ' + line_stripped
            else:
                combined_lines.append(line_stripped)
        else:
            combined_lines.append(line_stripped)

    return '\n'.join(combined_lines)

def process_html_file(file_path):
    """
    Apply processing functions to an HTML file.

    Args:
        file_path (str): Path to the HTML file.
    """
    try:
        with open(file_path, 'r', encoding='utf-8') as file:
            content = file.read()

        # Remove <img> tags
        content = re.sub(r'<img\b[^>]>', '', content, flags=re.IGNORECASE)

        # Replace <h1 style="text-align: center;"> with <h1>
        content = content.replace('<h1 style="text-align: center;">', '<h1>')

        # Capitalize first letter inside tags
        content = capitalize_first_letter_in_tags(content)

        # Combine <blockquote> lines
        content = combine_blockquote_lines_in_content(content)

        # Remove blank lines
        content = '\n'.join([line for line in content.splitlines() if line.strip()])

        # Combine specific HTML tags into the same line
        # content = combine_html_tags_into_same_line(content)

        with open(file_path, 'w', encoding='utf-8') as file:
            file.write(content)

        logging.info(f"Processed HTML file: {file_path}")
    except Exception as e:
        logging.error(f"Error processing {file_path}: {e}")

def read_image_html_from_csv(csv_file_path):
    """
    Read image HTML snippets from a CSV file.

    Args:
        csv_file_path (str): Path to the CSV file.

    Returns:
        dict: Dictionary mapping folder names to lists of image HTML lines.
    """
    image_html_dict = {}
    try:
        with open(csv_file_path, 'r', encoding='utf-8') as file:
            csv_reader = csv.reader(file)
            for row in csv_reader:
                if len(row) == 2:
                    folder_name = row[0].strip()
                    if folder_name not in image_html_dict:
                        image_html_dict[folder_name] = []
                    image_html_dict[folder_name].append(row[1].strip())
    except Exception as e:
        logging.error(f"Error reading CSV file {csv_file_path}: {e}")
    return image_html_dict

def read_links_from_txt(txt_file_path):
    """
    Read links from a TXT file.

    Args:
        txt_file_path (str): Path to the TXT file.

    Returns:
        list: List of links.
    """
    try:
        with open(txt_file_path, 'r', encoding='utf-8') as file:
            return [line.strip() for line in file if line.strip()]
    except Exception as e:
        logging.error(f"Error reading TXT file {txt_file_path}: {e}")
        return []

def insert_image_html(html_content, image_html_lines):
    """
    Insert image HTML lines into the HTML content at specified positions.

    Args:
        html_content (str): Original HTML content.
        image_html_lines (list): List of image HTML lines to insert.

    Returns:
        str: Modified HTML content with images inserted.
    """
    content_length = len(html_content)
    insertion_points = [
        int(content_length * 0.125),
        int(content_length * 0.375),
        int(content_length * 0.625),
        int(content_length * 0.875)
    ]

    for i, point in enumerate(insertion_points):
        start_of_line = html_content.rfind('\n', 0, point)
        end_of_line = html_content.find('\n', point)

        if start_of_line == -1:
            start_of_line = 0
        if end_of_line == -1:
            end_of_line = content_length

        if point - start_of_line <= end_of_line - point:
            insertion_index = start_of_line + 1
        else:
            insertion_index = end_of_line + 1

        if i < len(image_html_lines):
            html_content = html_content[:insertion_index] + image_html_lines[i] + '\n' + html_content[insertion_index:]

    return html_content

def insert_link_at_end(html_content, link):
    """
    Insert a link at the end of the "Xem thêm: " section in the HTML content.

    Args:
        html_content (str): Original HTML content.
        link (str): The link to insert.

    Returns:
        str: Modified HTML content with the link inserted.
    """
    last_xem_them = html_content.rfind("Xem thêm: ")
    if last_xem_them != -1:
        insertion_point = last_xem_them + len("Xem thêm: ")
        return html_content[:insertion_point] + link + html_content[insertion_point:]
    else:
        return html_content.rstrip() + "\nXem thêm: " + link

def insert_formatted_title(html_content):
    """
    Insert a formatted title after the first </blockquote> tag.

    Args:
        html_content (str): Original HTML content.

    Returns:
        str: Modified HTML content with the formatted title inserted.
    """
    # Find the title
    title_match = re.search(r'<h1\b[^>]><strong>(.?)</strong></h1>', html_content, re.IGNORECASE)
    if not title_match:
        return html_content  # No title found, return unchanged content

    title = title_match.group(1)

    # Prepare the formatted title
    if '?' in title:
        formatted_title = f'<h2><strong>{title} Bài viết dưới đây sẽ giải thích cho bạn:</strong></h2>'
    else:
        formatted_title = f'<h2><strong>{title} là gì? Bài viết dưới đây sẽ giải thích cho bạn:</strong></h2>'

    # Find the first </blockquote> and insert the formatted title after it
    blockquote_end = html_content.find('</blockquote>')
    if blockquote_end != -1:
        # Find the end of the line containing </blockquote>
        end_of_line = html_content.find('\n', blockquote_end)
        if end_of_line == -1:
            end_of_line = len(html_content)
        insertion_point = end_of_line + 1
        return html_content[:insertion_point] + formatted_title + '\n' + html_content[insertion_point:]
    else:
        return html_content  # No </blockquote> found, return unchanged content

def insert_title_in_blockquote(html_content):
    """
    Insert the title followed by " - " immediately after the opening <blockquote> tag.

    Args:
        html_content (str): Original HTML content.

    Returns:
        str: Modified HTML content with the title inserted in blockquote.
    """
    # Find the title
    title_match = re.search(r'<h1\b[^>]><strong>(.*?)</strong></h1>', html_content, re.IGNORECASE)
    if not title_match:
        return html_content  # No title found, return unchanged content

    title = title_match.group(1)

    # Find the first <blockquote> tag
    blockquote_start = html_content.find('<blockquote>')
    if blockquote_start == -1:
        return html_content  # No <blockquote> found, return unchanged content

    # Insert the title followed by " - " just after the opening <blockquote> tag
    insertion_point = blockquote_start + len('<blockquote>')
    return html_content[:insertion_point] + f'{title} - ' + html_content[insertion_point:]

def remove_h1_strong_tags(folder_path):
    """
    Remove <h1><strong> and </strong></h1> tags from the first line of HTML files.

    Args:
        folder_path (str): Path to the folder.
    """
    for subdir, _, files in os.walk(folder_path):
        for file in files:
            if file.lower().endswith('.html'):
                file_path = os.path.join(subdir, file)
                try:
                    with open(file_path, 'r', encoding='utf-8') as file_obj:
                        lines = file_obj.readlines()

                    if lines:
                        lines[0] = lines[0].replace('<h1><strong>', '').replace('</strong></h1>', '')

                    with open(file_path, 'w', encoding='utf-8') as file_obj:
                        file_obj.writelines(lines)

                    logging.info(f"Removed <h1><strong> tags in: {file_path}")
                except Exception as e:
                    logging.error(f"Error processing {file_path}: {e}")

def add_xem_them_to_html(folder_path):
    """
    Add the string "Xem thêm: " at the end of each HTML file.

    Args:
        folder_path (str): Path to the folder.
    """
    for root, _, files in os.walk(folder_path):
        for file in files:
            if file.lower().endswith('.html'):
                file_path = os.path.join(root, file)
                try:
                    # Ensure we append to the file
                    with open(file_path, 'a', encoding='utf-8') as f:
                        f.write('\n\nXem thêm: ')
                    logging.info(f"Added 'Xem thêm: ' to {file_path}")
                except Exception as e:
                    logging.error(f"Error processing {file_path}: {e}")

def remove_quotes_from_html(folder_path):
    """
    Remove all quotation marks from HTML files.

    Args:
        folder_path (str): Path to the folder.
    """
    for root, _, files in os.walk(folder_path):
        for file in files:
            if file.lower().endswith('.html'):
                file_path = os.path.join(root, file)
                try:
                    with open(file_path, 'r', encoding='utf-8') as f:
                        content = f.read()

                    # Remove all quotation marks
                    content = content.replace('"', '').replace('“', '').replace('”', '')

                    with open(file_path, 'w', encoding='utf-8') as f:
                        f.write(content)

                    logging.info(f"Removed quotation marks from: {file_path}")
                except Exception as e:
                    logging.error(f"Error processing {file_path}: {e}")

def capitalize_after_colon_in_html(folder_path):
    """
    Capitalize the first letter after a colon in HTML files.

    Args:
        folder_path (str): Path to the folder.
    """
    pattern = re.compile(r'(: )([a-z])')

    for root, _, files in os.walk(folder_path):
        for file in files:
            if file.lower().endswith('.html'):
                file_path = os.path.join(root, file)
                try:
                    with open(file_path, 'r', encoding='utf-8') as f:
                        content = f.read()

                    # Capitalize first letter after ": "
                    modified_content = pattern.sub(lambda m: m.group(1) + m.group(2).upper(), content)

                    if content != modified_content:
                        with open(file_path, 'w', encoding='utf-8') as f:
                            f.write(modified_content)
                        logging.info(f"Capitalized text after colon in: {file_path}")
                except Exception as e:
                    logging.error(f"Error processing {file_path}: {e}")

def process_html_files(folder_path):
    """
    Process all HTML files in a folder, applying several cleaning functions.

    Args:
        folder_path (str): Path to the folder.
    """
    for subdir, _, files in os.walk(folder_path):
        for file in files:
            if file.lower().endswith('.html'):
                file_path = os.path.join(subdir, file)
                process_html_file(file_path)

# ----------------------------------------------------------------------------------------------------------------------
# Script 2: Image and Link Insertion into HTML
# ----------------------------------------------------------------------------------------------------------------------

def insert_image_and_links_into_html(html_folder_path, csv_file_path, links_file_path):
    """
    Insert image HTML snippets and links into HTML files based on CSV and TXT inputs.

    Args:
        html_folder_path (str): Path to the folder containing HTML files.
        csv_file_path (str): Path to the CSV file containing image HTML snippets.
        links_file_path (str): Path to the TXT file containing links.
    """
    image_html_dict = read_image_html_from_csv(csv_file_path)
    links = read_links_from_txt(links_file_path)
    link_index = 0

    all_html_files = []
    for root, dirs, files in os.walk(html_folder_path):
        for file in files:
            if file.lower().endswith('.html'):
                all_html_files.append(os.path.join(root, file))
    all_html_files.sort()

    for file_path in all_html_files:
        folder_name = os.path.basename(os.path.dirname(file_path))

        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                html_content = f.read()

            # Insert title in blockquote
            html_content = insert_title_in_blockquote(html_content)

            # Insert formatted title
            html_content = insert_formatted_title(html_content)

            # Insert image HTML if the folder name matches
            if folder_name in image_html_dict:
                html_content = insert_image_html(html_content, image_html_dict[folder_name])

            # Insert link at the end
            if link_index < len(links):
                html_content = insert_link_at_end(html_content, links[link_index])
                link_index += 1

            # Save the modified content
            with open(file_path, 'w', encoding='utf-8') as f:
                f.write(html_content)

            # Reset link index if we've used all links
            if link_index >= len(links):
                link_index = 0

            logging.info(f"Inserted images and links into: {file_path}")

        except Exception as e:
            logging.error(f"Error processing {file_path}: {e}")

# ----------------------------------------------------------------------------------------------------------------------
# Main Execution Flow
# ----------------------------------------------------------------------------------------------------------------------

def main(image_folder_path, html_folder_path, csv_file_path, links_file_path):
    """
    Main function to execute all processing steps.

    Args:
        image_folder_path (str): Path to the folder to process images.
        html_folder_path (str): Path to the folder to process HTML files.
        csv_file_path (str): Path to the CSV file for image HTML snippets.
        links_file_path (str): Path to the TXT file containing links.
    """

    # ------------------------------
    # Image Processing
    # ------------------------------
    logging.info("Starting image processing...")

    # Step 1: Delete unreadable image files
    delete_unreadable_images(image_folder_path)

    # Step 2: Delete blank (all white) images
    delete_blank_images(image_folder_path)

    # Step 3: Delete subfolders with few images
    delete_subfolders_with_few_images(image_folder_path, threshold=3)

    # Step 4: Trim image files in remaining subfolders
    trim_image_files(image_folder_path, target_count=4)

    # Step 5: Convert all .jpg images to RGB mode
    convert_jpg_to_rgb(image_folder_path)

    # Step 6: Convert and resize images
    convert_and_resize_images(image_folder_path, target_width=1200)

    # Step 7: Rename .jpg files based on subfolder names
    rename_jpg_files(image_folder_path)

    # Step 8: Add metadata to images based on subfolder names
    add_metadata_to_images(image_folder_path)

    logging.info("Image processing completed.")

    # ------------------------------
    # HTML Processing
    # ------------------------------
    logging.info("Starting HTML processing...")

    # Step 6: Delete small HTML folders
    delete_small_html_folders(html_folder_path, min_char_count=6000)

    # Step 7: Process HTML files (cleaning)
    process_html_files(html_folder_path)

    # Step 8: Additional HTML modifications
    capitalize_after_colon_in_html(html_folder_path)
    # Uncomment the following lines if needed
    # add_xem_them_to_html(html_folder_path)
    # remove_h1_strong_tags(html_folder_path)
    # remove_quotes_from_html(html_folder_path)

    # Step 9: Insert images and links into HTML files
    insert_image_and_links_into_html(html_folder_path, csv_file_path, links_file_path)

    logging.info("HTML processing completed.")

if __name__ == "__main__":
    main(folder_path, html_folder_path, csv_file_path, links_file_path)