import re
from datetime import datetime, timedelta, timezone
from typing import Optional

import pytz
from dateutil.relativedelta import relativedelta

from src.config import TIMEZONE


def parse_relative_expression(date_str: str) -> Optional[datetime]:
    """
    Parse relative date expressions using T (days), M (months), and Y (years)
    Returns tuple of (datetime, type_description) or None if not a relative date
    """
    pattern = r"^([HTMY])([+-]\d+)?$"
    match = re.match(pattern, date_str)

    if not match:
        return None

    unit, offset = match.groups()
    offset = int(offset) if offset else 0
    # Use UTC timezone for consistency
    today = datetime.now(timezone.tzname("Asia/Jakarta"))
    if unit == "H":
        # For hours, keep minutes and seconds
        result_time = today + timedelta(hours=offset)
        return result_time
    elif unit == "T":
        return today + timedelta(days=offset)
    elif unit == "M":
        return today + relativedelta(months=offset)
    elif unit == "Y":
        return today + relativedelta(years=offset)


def parse_date_string(date_str: str) -> Optional[datetime]:
    """
    Parse date strings in various formats including relative expressions
    Returns tuple of (datetime, type)
    """
    # Try parsing as relative expression first
    relative_result = parse_relative_expression(date_str)
    if relative_result:
        return relative_result

    # Try different date formats
    date_formats = [
        ("%Y-%m-%d", "iso"),  # 2024-11-08
        ("%Y/%m/%d", "slash"),  # 2024/11/08
        ("%d-%m-%Y", "european"),  # 08-11-2024
        ("%d/%m/%Y", "european_slash"),  # 08/11/2024
        ("%Y.%m.%d", "dot"),  # 2024.11.08
        ("%d.%m.%Y", "european_dot"),  # 08.11.2024
    ]

    for fmt, type_name in date_formats:
        try:
            # Parse the date and set it to start of day in UTC
            dt = datetime.strptime(date_str, fmt)
            dt = dt.replace(
                hour=0,
                minute=0,
                second=0,
                microsecond=0,
                tzinfo=timezone.tzname("Asia/Jakarta"),
            )
            return dt
        except ValueError:
            continue

    raise ValueError(
        "Invalid date format. Supported formats:\n"
        "Relative formats:\n"
        "- T (days): T, T-n, T+n\n"
        "- M (months): M, M-1, M+2\n"
        "- Y (years): Y, Y-1, Y+1\n"
        "Regular formats:\n"
        "- YYYY-MM-DD\n"
        "- YYYY/MM/DD\n"
        "- DD-MM-YYYY\n"
        "- DD/MM/YYYY\n"
        "- YYYY.MM.DD\n"
        "- DD.MM.YYYY"
    )


def time_now():
    return datetime.now(pytz.timezone(TIMEZONE))


import requests


def get_latest_numOfFail(location_tag, token) -> float:
    today = datetime.today().strftime("%Y-%m-%d")
    url_today = f"http://192.168.1.82:8000/reliability/main/number-of-failures/{location_tag}/2016-01-01/{today}"

    try:
        response = requests.get(
            url_today,
            {
                "Content-Type": "application/json",
                "Authorization": f"Bearer {token}",
            },
        )
        data = response.json()

        raise Exception(data)

        latest_num = data["data"][-1]["num_fail"]

        raise Exception(latest_num)

        if not latest_num:
            latest_num = 0

        return latest_num
    except requests.exceptions.RequestException as e:
        print(f"Error fetching data: {e}")
        return 0



PASTEBIN_API_KEY = 'G9uCTzoI1CJWCupt5lcZRpijondt5jwA'  # Replace this with your actual API key

def save_to_pastebin(data, title="Result Log", expire_date="1H"):
    url = "https://pastebin.com/api/api_post.php"
    payload = {
        'api_dev_key': PASTEBIN_API_KEY,
        'api_option': 'paste',
        'api_paste_code': data,
        'api_paste_name': title,
        'api_paste_expire_date': expire_date,  # Example: 10M, 1H, 1D, N (never)
    }
    response = requests.post(url, data=payload)
    if response.status_code == 200:
        return response.text  # This will be the paste URL
    else:
        return f"Error: {response.status_code} - {response.text}"
