from aiogram import Bot
from dbase.db import DataBase
import cfg
import aiogram
from core.keyboard import *
import source_dir
from dbase.db import DataBase
from PIL import Image, ImageDraw, ImageFont
from contextlib import suppress
import re

db = DataBase(file=cfg.DATABASE_URL)
bot = Bot(token=cfg.TOKEN)

def clean_coordinate_string(coord_str):
    """
    Clean coordinate string by removing invalid characters and ensuring proper format.
    Expected format: 'x, y' where x and y are integers.
    """
    if coord_str is None:
        return "0, 0"
    
    # Convert to string if it's not already
    coord_str = str(coord_str)
    
    # Remove any non-digit, non-comma, non-space characters
    cleaned = re.sub(r'[^\d,\s]', '', coord_str)
    
    # Split by comma and clean each part
    parts = cleaned.split(',')
    
    if len(parts) != 2:
        return "0, 0"
    
    # Clean each coordinate (remove spaces and ensure it's a valid integer)
    try:
        x = int(parts[0].strip())
        y = int(parts[1].strip())
        return f"{x}, {y}"
    except ValueError:
        return "0, 0"

async def set_default_params(menu_id=1):
    key_list = ['up_font', 'main_font', 'celsius_font', 'price_font']
    value_list = [48, 90, 70, 90]

    for i in range(4):
        await db.update_column(key=key_list[i], value=value_list[i], menu_id=menu_id)

    key_list = ['main_xy', 'up_xy', 'celsius_xy', 'price_xy']

    value_dict = {'value_list_1': ['50, 710', '50, 660', '650, 720', '820, 700'], 
                  'value_list_2': ['50, 890', '50, 840', '650, 900', '820, 880'],
                  'value_list_3': ['50, 1070', '50, 1020', '650, 1080', '820, 1070'],
                  'value_list_4': ['50, 1260', '50, 1210', '659, 1270', '820, 1260'],
                  'value_list_5': ['55, 1440', '55, 1390', '664, 1450', '820, 1440'],
                  'value_list_6': ['1150, 665', '1150, 610', '1770, 690', '1940, 680'],
                  'value_list_7': ['1150, 860', '1150, 810', '1770, 875', '1940, 860'],
                  'value_list_8': ['1150, 1040', '1150, 990', '1770, 1055', '1940, 1040'],
                  'value_list_9': ['1150, 1230', '1150, 1190', '1770, 1230', '1940, 1235'],
                  'value_list_10': ['1150, 1415', '1150, 1375', '1770, 1430', '1940, 1420'],
                  'value_list_11': ['55, 1790', '55, 1740', '670, 1810', '860, 1800'],
                  'value_list_12': ['55, 1990', '55, 1940', '670, 2010', '860, 2000'],
                  'value_list_13': ['55, 2165', '55, 2115', '670, 2180', '860, 2165'],
                  'value_list_14': ['55, 2360', '55, 2320', '670, 2380', '860, 2365'],
                  'value_list_15': ['55, 2540', '55, 2500', '670, 2560', '860, 2545'],
                  'value_list_16': ['55, 2735', '55, 2695', '670, 2750', '860, 2735'],
                  'value_list_17': ['55, 2940', '55, 2895', '670, 2950', '860, 2935'],
                  'value_list_18': ['1165, 1815', '1165, 1775', '1770, 1830', '1940, 1820'],
                  'value_list_19': ['1165, 2020', '1165, 1980', '1770, 2035', '1940, 2020'],
                  'value_list_20': ['1165, 2220', '1165, 2180', '1770, 2235', '1940, 2220']}

    if menu_id == 1:
        for i in range(1, 21):
            for obj, j in zip(key_list, range(4)):
                await db.update_position(index=i, 
                                         key=obj, 
                                         value=value_dict[f'value_list_{i}'][j],
                                         menu_id=menu_id)
    else:
        for i in range(1, 17):
            for obj, j in zip(key_list, range(4)):
                await db.update_position(index=i, 
                                         key=obj, 
                                         value=value_dict[f'value_list_{i}'][j],
                                         menu_id=menu_id)
        for i in range(18, 20):
            for obj, j in zip(key_list, range(4)):
                await db.update_position(index=i, 
                                         key=obj, 
                                         value=value_dict[f'value_list_{i}'][j],
                                         menu_id=menu_id)
        

async def generate_image(menu_id=1):
    if menu_id == 1:
        source_image = f'{cfg.SOURCE_DIR}/source.png'
    elif menu_id == 2:
        source_image = f'{cfg.SOURCE_DIR}/source-promotion.png'
    else:  # menu_id == 3
        source_image = f'{cfg.SOURCE_DIR}/source-promotion-2.png'
    
    image = Image.open(source_image)
    draw = ImageDraw.Draw(image)
    fillColor = "#ffffff"
    maler = f'{cfg.SOURCE_DIR}/Maler.ttf'

    if menu_id == 1:
        positions = list(range(1, 21))
    else:
        positions = list(range(1, 17)) + list(range(18, 20))

    for position in positions:
        text = await db.get_position_info(index=position, value='main_text', menu_id=menu_id)

        if text != None:
            with suppress(TypeError):
                celcius = await db.get_position_info(index=position, value='celsius_text', menu_id=menu_id)

                up_text = await db.get_position_info(index=position, value='up_text', menu_id=menu_id)

                price = await db.get_position_info(index=position, value='price_text', menu_id=menu_id)

                if up_text == None:
                    up_text = ''

                if celcius == None:
                    celcius = ''

                font_size = await db.get_position_info(index=position, value='main_font', menu_id=menu_id)
                main_font = ImageFont.truetype(maler, font_size)

                font_size = await db.get_position_info(index=position, value='up_font', menu_id=menu_id)
                up_font = ImageFont.truetype(maler, font_size)

                font_size = await db.get_position_info(index=position, value='celsius_font', menu_id=menu_id)
                cel_font = ImageFont.truetype(maler, font_size)

                font_size = await db.get_position_info(index=position, value='price_font', menu_id=menu_id)
                price_font = ImageFont.truetype(maler, font_size)


                main_xy = await db.get_position_info(index=position, value='main_xy', menu_id=menu_id)
                main_xy = clean_coordinate_string(main_xy).split(', ')

                up_xy = await db.get_position_info(index=position, value='up_xy', menu_id=menu_id)
                up_xy = clean_coordinate_string(up_xy).split(', ')

                cel_xy = await db.get_position_info(index=position, value='celsius_xy', menu_id=menu_id)
                cel_xy = clean_coordinate_string(cel_xy).split(', ')

                price_xy = await db.get_position_info(index=position, value='price_xy', menu_id=menu_id)
                price_xy = clean_coordinate_string(price_xy).split(', ')

                # Convert coordinates to integers with error handling
                try:
                    main_coords = (int(main_xy[0]), int(main_xy[1]))
                    up_coords = (int(up_xy[0]), int(up_xy[1]))
                    cel_coords = (int(cel_xy[0]), int(cel_xy[1]))
                    price_coords = (int(price_xy[0]), int(price_xy[1]))

                    draw.text(text=text, font=main_font, fill=fillColor, direction=None, xy=main_coords)
                    draw.text(text=up_text, font=up_font, fill=fillColor, direction=None, xy=up_coords)
                    draw.text(text=celcius, font=cel_font, fill=fillColor, direction=None, xy=cel_coords)
                    draw.text(text=price, font=price_font, fill=fillColor, direction=None, xy=price_coords)
                except (ValueError, IndexError) as e:
                    print(f"Error processing coordinates for position {position}: {e}")
                    continue

                image.save(f'{cfg.SOURCE_DIR}/demo.png')
        
        else:
            pass
