from flask import Flask, jsonify, request, send_from_directory, render_template
import os
from PIL import Image, ExifTags
from apscheduler.schedulers.background import BackgroundScheduler
from datetime import datetime, timedelta
import piexif
import io
import random
from colorthief import ColorThief
import colorsys

app = Flask(__name__)

IMAGE_FOLDER = '/home/dubey/projects/photoportfolio/pythonserver/images/'
THUMBS_FOLDER = '/home/dubey/projects/photoportfolio/pythonserver/thumbs/'
IMAGES_PER_PAGE = 5
THUMBNAIL_SIZES = [256, 512, 768, 1024, 1536, 2048]

scheduler = BackgroundScheduler()
scheduler.start()

def generate_thumbnails():
    for filename in os.listdir(IMAGE_FOLDER):
        if filename.lower().endswith(('.png', '.jpg', '.jpeg', '.gif')):
            original_path = os.path.join(IMAGE_FOLDER, filename)
            for size in THUMBNAIL_SIZES:
                thumb_path = os.path.join(THUMBS_FOLDER, f"{size}_{filename}")
                if not os.path.exists(thumb_path):
                    with Image.open(original_path) as img:
                        # Extract EXIF data
                        exif_data = None
                        if "exif" in img.info:
                            exif_data = img.info["exif"]

                        # Resize image
                        img.thumbnail((size, size), Image.LANCZOS)

                        # Save image with EXIF data
                        if exif_data:
                            img.save(thumb_path, exif=exif_data, optimize=True, quality=85)
                        else:
                            img.save(thumb_path, optimize=True, quality=85)

scheduler.add_job(generate_thumbnails, 'interval', minutes=5)
scheduler.add_job(generate_thumbnails, 'date', run_date=datetime.now() + timedelta(seconds=1))  # Run once at startup


def get_highlight_color(image_path):
    color_thief = ColorThief(image_path)
    palette = color_thief.get_palette(color_count=6, quality=1)
    
    # Convert RGB to HSV and find the color with the highest saturation
    highlight_color = max(palette, key=lambda rgb: colorsys.rgb_to_hsv(*rgb)[1])
    
    return '#{:02x}{:02x}{:02x}'.format(*highlight_color)

def get_image_info(filename):
    path = os.path.join(IMAGE_FOLDER, filename)
    thumb_path = os.path.join(THUMBS_FOLDER, f"256_{filename}")
    exif = None
    with Image.open(path) as img:
        width, height = img.size
        exif = {
            ExifTags.TAGS[k]: v
            for k, v in img._getexif().items()
            if k in ExifTags.TAGS
        }

    if str(exif['Orientation']) == "6" or str(exif['Orientation']) == "8":
        width, height = height, width

    exposure_time = exif['ExposureTime']
    if isinstance(exposure_time, tuple):
        exposure_fraction = f"{exposure_time[0]}/{exposure_time[1]}"
    else:
        exposure_fraction = f"1/{int(1/float(exposure_time))}"
    
    date_obj = datetime.strptime(exif['DateTime'], '%Y:%m:%d %H:%M:%S')
    date = date_obj.strftime('%y %m %d')  # Format: YY MM DD
    technical_info = f"{exif['FocalLengthIn35mmFilm']}MM | F/{exif['FNumber']} | {exposure_fraction} | ISO{exif['ISOSpeedRatings']}"

    factor = random.randint(2, 3)
    if height < 4000 or width < 4000:
        factor = 1

    highlight_color = get_highlight_color(thumb_path)

    return {
        'imgSrc': f'/thumbs/1536_{filename}',
        'fullSizeImgSrc': f'/images/{filename}',
        'date': date,
        'technicalInfo': technical_info,
        'width': width/factor,
        'height': height/factor,
        'highlightColor': highlight_color
    }

def get_image_taken_date(filename):
    path = os.path.join(IMAGE_FOLDER, filename)
    with Image.open(path) as img:
        exif = {
            ExifTags.TAGS[k]: v
            for k, v in img._getexif().items()
            if k in ExifTags.TAGS
        }
    date_str = exif.get('DateTime', exif.get('DateTimeOriginal', ''))
    if date_str:
        return datetime.strptime(date_str, '%Y:%m:%d %H:%M:%S')
    return datetime.fromtimestamp(os.path.getmtime(path))  # Fallback to file modification time

@app.route('/api/images')
def get_images():
    page = int(request.args.get('page', 1))
    all_images = sorted(
        [f for f in os.listdir(IMAGE_FOLDER) if f.lower().endswith(('.png', '.jpg', '.jpeg', '.gif'))],
        key=get_image_taken_date,
        reverse=True
    )
    start = (page - 1) * IMAGES_PER_PAGE
    end = start + IMAGES_PER_PAGE
    page_images = all_images[start:end]

    return jsonify({
        'images': [get_image_info(img) for img in page_images],
        'hasMore': end < len(all_images)
    })


@app.route('/images/<path:filename>')
def serve_image(filename):
    return send_from_directory(IMAGE_FOLDER, filename)


@app.route('/')
def index():
    return render_template('index.html')


@app.route('/thumbs/<path:filename>')
def serve_thumbnail(filename):
    return send_from_directory(THUMBS_FOLDER, filename)


if __name__ == '__main__':
    app.run(debug=True, port=5001, host='0.0.0.0')