import os
import json
import config
import imagehash
from PIL import Image
from funcs import get_files, calculate_file_hash, remove_empty_folders  # Assuming this is defined elsewhere

def generate_image_phash(filepath, hash_size=8):
    try:
        # Open the image using PIL
        pil_image = Image.open(filepath)
        
        # Compute pHash using the imagehash library
        phash = imagehash.phash(pil_image, hash_size=hash_size)
        return phash
    except Exception as e:
        print(f"Error processing image {filepath}: {e}")
        return None

def are_phashes_duplicates(phash1, phash2, threshold=5):
    try:
        # Compute the Hamming distance between the pHashes
        distance = phash1 - phash2
        return distance <= threshold
    except TypeError as e:
        print(f"Error comparing pHashes: {e}")
        return False

def get_media_by_phash(phash, username, existing_medias, threshold=5):
    for media in existing_medias:
        existing_phash_str = media[1]
        existing_username = media[2]
        
        if existing_username != username:
            continue
        
        # Convert stored pHash string to ImageHash object
        existing_phash = imagehash.hex_to_hash(existing_phash_str)

        # Check if the current pHash is a duplicate
        if are_phashes_duplicates(phash, existing_phash, threshold=threshold):
            return media
    return None

def get_media_by_hash(hash, existing_medias):
    for media in existing_medias:
        existing_hash = media[1]
        if hash == existing_hash:
            return media
    return None

def get_media_by_id(media_id, existing_medias):
    for media in existing_medias:
        existing_media_id = media[1]
        if media_id == existing_media_id:
            return media
    return None

def get_data_by_filename(filename, data):
    for item in data:
        if filename in item['filepath']:
            return item
    return None

directory = 'images'
data = json.load(open('pins.json'))

files = get_files(directory)
knownExtensions = ['jpg', 'png', 'jpeg', 'gif', 'webp']
for file in files:
    fileExt = file.split('.')[-1].lower()
    if fileExt not in knownExtensions:
        print(f"Data not found for {file}")
        filehash = calculate_file_hash(file)
        newfilename = f"{filehash}.jpg"
        currentDir = os.path.dirname(file)
        newfilepath = os.path.join(currentDir, newfilename)
        os.rename(file, newfilepath)

files = get_files(directory)

# Sort files by username and move them into the directory folder where each subfolder is a username
for file in files:
    item_data = get_data_by_filename(os.path.basename(file).split('.')[0], data)
    
    if not item_data:
        print(f"Data not found for {file}")
        continue
    
    username = item_data['username']
    newpath = os.path.join(directory, username, os.path.basename(file))

    if newpath == file:
        continue
    
    os.makedirs(os.path.dirname(newpath), exist_ok=True)
    os.rename(file, newpath)

# Database connection
db, cursor = config.gen_connection()

# now find dupes by media_id
cursor.execute("SELECT id, media_id, username FROM media WHERE media_type = %s AND media_id IS NOT NULL", ['image'])
items = cursor.fetchall()

media_ids = [item[1] for item in items]

files = get_files(directory)

for file in files:
    try:
        media_id = os.path.basename(file).split('.')[0]
        media_id = int(media_id)
    except:
        print(f"Error parsing media_id from {file}")
        continue
    
    if media_id in media_ids:
        media_item = get_media_by_id(media_id, items)
        print(f"Duplicate found: https://altpins.com/pin/{media_item[0]}")
        print(f"Duplicate file: {file}")
        newpath = os.path.join('duplicates', media_item[2], os.path.basename(file))
        os.makedirs(os.path.dirname(newpath), exist_ok=True)
        os.rename(file, newpath)
    else:
        print(f"Unique file: {file}")

        
cursor.execute("SELECT id, hash, username FROM media WHERE media_type = %s AND hash IS NOT NULL", ['image'])
items = cursor.fetchall()

hashes = [item[1] for item in items]

files = get_files(directory)

for file in files:
    hash = calculate_file_hash(file)
    if hash in hashes:
        media_item = get_media_by_hash(hash, items)
        print(f"Duplicate found: https://altpins.com/pin/{media_item[0]}")
        print(f"Duplicate file: {file}")
        newpath = os.path.join('duplicates', media_item[2], os.path.basename(file))
        os.makedirs(os.path.dirname(newpath), exist_ok=True)
        os.rename(file, newpath)
    else:
        print(f"Unique file: {file}")
    
    
# Fetch existing media with pHashes (assuming media are images, adjust media_type if needed)
cursor.execute("SELECT id, phash, username FROM media WHERE media_type = %s AND phash IS NOT NULL", ['image'])
existing_medias = cursor.fetchall()

# Go through the directory folder where each subfolder is a username
files = get_files(directory)

for filepath in files:
    image_filename = os.path.basename(filepath)
    print(f'Processing {image_filename}...')

    # Generate pHash for the image
    phash = generate_image_phash(filepath, hash_size=8)
    if phash is None:
        continue  # Skip this image if there's an issue

    phash_str = str(phash)

    item_data = get_data_by_filename(image_filename, data)
    if not item_data:
        print(f"Data not found for {image_filename}")
        continue
    username = item_data['username']

    # Check if the image is a duplicate of any in the database
    duplicate_media = get_media_by_phash(phash, username, existing_medias, threshold=5)
    if duplicate_media:
        print(f'Duplicate found: https://altpins.com/pin/{duplicate_media[0]}')
        print(f'Duplicate image path: {filepath}')
        newpath = os.path.join('duplicates', duplicate_media[2], image_filename)
        os.makedirs(os.path.dirname(newpath), exist_ok=True)
        os.rename(filepath, newpath)
        print(f'Moved {image_filename} to duplicates/')