from datetime import datetime, timedelta
import random

# Your predefined variables…
duty_date = "2024-08-11"
date = datetime.strptime(duty_date, "%Y-%m-%d")

day_of_week = date.strftime("%A")

# Finding weekends
weekends = [date + timedelta(days=i) for i in range((5 - date.weekday()) % 7, 31, 7)] + \
           [date + timedelta(days=i) for i in range((6 - date.weekday()) % 7, 31, 7)]

# Ensure weekends include the 30th and 31st if they fall on a weekend
for i in range(30, 32):
    potential_weekend = datetime(date.year, date.month, i)
    if potential_weekend.weekday() in [5, 6]:  # Saturday or Sunday
        weekends.append(potential_weekend)

print(day_of_week)
print(weekends)

# Define the list of persons
primary_persons = ["NTALAMPEKOU", "MAFOUNI", "MEMIS", "RAISAKIS", "ENECHELIDOU", "DIMADIS"]
secondary_persons = ["SACHANIDOU", "VASILIADIS", "PAPAGEORGIOU", "KARAISKOS", "TSIPLAKIS", "SPANTIDAKIS", "PAPADOPOULOS"]

# Define the days they can’t be on duty
unavailable_days = {
    "NTALAMPEKOU": ["2024-08-12", "2024-08-13", "2024-08-14", "2024-08-15", "2024-08-16", "2024-08-17", "2024-08-18", "2024-08-19"],
    "MAFOUNI": ["2024-08-20", "2024-08-21", "2024-08-22", "2024-08-23", "2024-08-24", "2024-08-25"],
    "MEMIS": ["2024-08-01", "2024-08-02", "2024-08-03", "2024-08-04", "2024-08-05", "2024-08-06", "2024-08-07"],
    "RAISAKIS": ["2024-08-10", "2024-08-11", "2024-08-12", "2024-08-13", "2024-08-15", "2024-08-16", "2024-08-17"],
    "ENECHELIDOU": ["2024-08-12", "2024-08-13", "2024-08-14", "2024-08-15", "2024-08-16", "2024-08-17"],
    "DIMADIS": ["2024-08-05", "2024-08-06", "2024-08-07"],
    "SACHANIDOU": ["2024-08-21", "2024-08-22", "2024-08-23", "2024-08-24", "2024-08-25"],
    "VASILIADIS": ["2024-08-10", "2024-08-11", "2024-08-12", "2024-08-13", "2024-08-14", "2024-08-15"],
    "PAPAGEORGIOU": ["2024-08-01", "2024-08-02", "2024-08-03", "2024-08-04", "2024-08-05", "2024-08-07"],
    "KARAISKOS": ["2024-08-11", "2024-08-12", "2024-08-13", "2024-08-14", "2024-08-15"],
    "TSIPLAKIS": ["2024-08-15"],
    "SPANTIDAKIS": ["2024-08-14", "2024-08-15", "2024-08-16"],
    "PAPADOPOULOS": ["2024-08-12", "2024-08-13", "2024-08-14", "2024-08-15"]
}

# Define the history of previous months based on the table
previous_duties = {
    "NTALAMPEKOU": 24,
    "MAFOUNI": 22,
    "MEMIS": 22,
    "RAISAKIS": 24,
    "ENECHELIDOU": 0,
    "DIMADIS": 27,
    "SACHANIDOU": 9,
    "VASILIADIS": 12,
    "PAPAGEORGIOU": 11,
    "KARAISKOS": 11,
    "TSIPLAKIS": 8,
    "SPANTIDAKIS": 11,
    "PAPADOPOULOS": 22
}

# Define the history of duties on specific days of the week
weekly_duties = {
    "NTALAMPEKOU": {"Monday": 3, "Tuesday": 4, "Wednesday": 5, "Thursday": 5, "Friday": 1, "Saturday": 3, "Sunday": 3},
    "MAFOUNI": {"Monday": 2, "Tuesday": 5, "Wednesday": 5, "Thursday": 4, "Friday": 2, "Saturday": 2, "Sunday": 2},
    "MEMIS": {"Monday": 5, "Tuesday": 1, "Wednesday": 2, "Thursday": 2, "Friday": 4, "Saturday": 4, "Sunday": 4},
    "RAISAKIS": {"Monday": 2, "Tuesday": 3, "Wednesday": 6, "Thursday": 4, "Friday": 3, "Saturday": 4, "Sunday": 2},
    "ENECHELIDOU": {"Monday": 0, "Tuesday": 0, "Wednesday": 0, "Thursday": 0, "Friday": 0, "Saturday": 0, "Sunday": 0},
    "DIMADIS": {"Monday": 5, "Tuesday": 3, "Wednesday": 1, "Thursday": 3, "Friday": 5, "Saturday": 3, "Sunday": 7},
    "SACHANIDOU": {"Monday": 1, "Tuesday": 2, "Wednesday": 3, "Thursday": 0, "Friday": 1, "Saturday": 1, "Sunday": 1},
    "VASILIADIS": {"Monday": 1, "Tuesday": 2, "Wednesday": 0, "Thursday": 4, "Friday": 2, "Saturday": 1, "Sunday": 2},
    "PAPAGEORGIOU": {"Monday": 1, "Tuesday": 1, "Wednesday": 1, "Thursday": 2, "Friday": 2, "Saturday": 3, "Sunday": 1},
    "KARAISKOS": {"Monday": 1, "Tuesday": 3, "Wednesday": 2, "Thursday": 0, "Friday": 2, "Saturday": 2, "Sunday": 1},
    "TSIPLAKIS": {"Monday": 2, "Tuesday": 0, "Wednesday": 0, "Thursday": 1, "Friday": 2, "Saturday": 1, "Sunday": 2},
    "SPANTIDAKIS": {"Monday": 1, "Tuesday": 2, "Wednesday": 0, "Thursday": 2, "Friday": 3, "Saturday": 2, "Sunday": 1},
    "PAPADOPOULOS": {"Monday": 3, "Tuesday": 4, "Wednesday": 4, "Thursday": 3, "Friday": 2, "Saturday": 3, "Sunday": 3}
}

# Define the predefined duties
predefined_duties = {
    "2024-08-10": "RAISAKIS",
    "2024-08-11": "KARAISKOS"  # Adjust as needed
}

# Function to check availability
def is_available(person, date, predefined_duties, unavailable_days):
    return date not in unavailable_days.get(person, []) and date not in predefined_duties

# Modified Generate Schedule Function
def generate_schedule(month, year):
    schedule = {}
    date = datetime(year, month, 1)
    primary_duties = {p: 0 for p in primary_persons}
    secondary_duties = {p: 0 for p in secondary_persons}
    
    # Assign predefined duties
    for duty_date, person in predefined_duties.items():
        schedule[duty_date] = person
        if person in primary_duties:
            primary_duties[person] += 1
        else:
            secondary_duties[person] += 1

        previous_duties[person] += 1
        day_of_week = datetime.strptime(duty_date, "%Y-%m-%d").strftime("%A")
        weekly_duties[person][day_of_week] += 1

    # Shuffle weekends
    random.shuffle(weekends)
    
    # Assign duties on weekends
    for person in primary_persons:
        for weekend in weekends:
            weekend_date = weekend.strftime("%Y-%m-%d")
            if is_available(person, weekend_date, predefined_duties, unavailable_days):                    
                schedule[weekend_date] = person
                primary_duties[person] += 1
                previous_duties[person] += 1
                day_of_week = weekend.strftime("%A")
                weekly_duties[person][day_of_week] += 1
                weekends.remove(weekend)  # Remove the weekend once assigned
                break

    # Main scheduling loop
    while date.month == month:
        date_str = date.strftime("%Y-%m-%d")
        if date_str not in schedule:
            available_primary = [p for p in primary_persons if is_available(p, date_str, predefined_duties, unavailable_days) and primary_duties[p] < 3]
            available_secondary = [p for p in secondary_persons if is_available(p, date_str, predefined_duties, unavailable_days) and secondary_duties[p] < 2]
            
            if available_primary:
                available_primary.sort(key=lambda p: (previous_duties.get(p, 0), weekly_duties[p][date.strftime("%A")]))
                person = available_primary[0]
                primary_duties[person] += 1
            elif available_secondary:
                available_secondary.sort(key=lambda p: (previous_duties.get(p, 0), weekly_duties[p][date.strftime("%A")]))
                person = available_secondary[0]
                secondary_duties[person] += 1
            else:
                person = None  # Handle the case where nobody is available
                print(f"No available duty person on {date_str}")  # Logging
            
            if person:
                schedule[date_str] = person
        
        date += timedelta(days=1)
    
    return schedule, primary_duties, secondary_duties  # Return the duty counts as well

# Generate the schedule and also get the primary and secondary duties
schedule, primary_duties, secondary_duties = generate_schedule(8, 2024)  # August 2024

# Now you can check availability for specific dates
dates_to_check = ["2024-08-29", "2024-08-30"]
for date_str in dates_to_check:
    available_primary = [p for p in primary_persons if is_available(p, date_str, predefined_duties, unavailable_days) and primary_duties[p] < 3]
    available_secondary = [p for p in secondary_persons if is_available(p, date_str, predefined_duties, unavailable_days) and secondary_duties[p] < 2]
    
    print(f"Date: {date_str}")
    print(f"Available Primary: {available_primary}")
    print(f"Available Secondary: {available_secondary}")

# Print the final schedule
for day, person in sorted(schedule.items()):
    print(f"{day}: {person}")
i want to add a third group ,      LAZARIDOU		0 Monday,	0 Tuesday,	0 Wednesday,	1 Thursday,	0 Friday,	1 Saturday, 	0 Sunday ,
KIKINIS	0 Monday,	0 Tuesday,	0 Wednesday,	0 Thursday,	5  Friday,	 0 Saturday, 	0 Sunday
GRIGORIADIS	1 Monday,	0 Tuesday,	1 Wednesday,	1 Thursday,	1 Friday,	0 Saturday, 	0 Sunday
KOMNINOS	0 Monday,	0 Tuesday,	1 Wednesday,	2 Thursday,	0 Friday,	2  Saturday, 	0 Sunday
KITSIS	0 Monday,	0 Tuesday,	0 Wednesday,	0 Thursday,	0 Friday,	0  Saturday, 	0 Sunday . from this group they will participitate persons only if is needed and the will take stricly only one day each month. LAZARIDOU cant do on 1 august, KIKINIScant do on 2 August, GRIGORIADIS cant do on 3 August, KOMNINOS cant do on 4 August, Kitsis cant do on 5 August. please do the code with new facts .please use straight quotes for python.