"""
Order of operations:
1. Get input of people and course
2. Create Project
3. Create Item with Course_attempt type
4. Create Course Attempt Resource with the same type.
5. Start Migration.
"""

from sys import argv
from utils import calls
import manage_csv
from datetime import datetime, timedelta
import uuid
import json
from urllib.parse import quote

baseurl = calls.BASEURL

probject = {}
items = {}
courses = {}
people = {}
miniattempt_loads = []
minienroll_loads = []


item_types = [
    "courses",
    "sections",
    "activities",
    "people",
    "enrollment_resources",
    "course_attempts",
    "quiz_attempts",
    "certificates",
    "learning_path_attempts",
]
project_name = argv[1]


def get_data():
    """
    Process CSV data to create course completion and enrollment records.

    Reads data from CSV, processes each row to get people and course information,
    and creates corresponding attempt and enrollment payloads.
    """
    df = manage_csv.import_as_dataframe()
    df.columns = df.columns.str.lower()
    # row_iterator = df.iterrows()
    # _, last = next(row_iterator)
    for i, row in df.iterrows():
        email = row["email address"]
        print(email)
        course = row["course name"]
        date = row["completion date"]
        print(date)
        people_tuple = get_people(email)
        if people_tuple is None:
            pass
        else:
            course_uuid = get_courses(course)
            attempt_payload = create_attempt_payload(course_uuid, people_tuple[0], date)
            enrollment_payload = create_enrollment_payload(
                course_uuid, people_tuple[0], date
            )
    create_attempt_resource(attempt_payload)
    create_enrollment_resource(enrollment_payload)


def get_people(email):
    """
    Retrieve person information by email address.

    Args:
        email (str): Email address of the person to look up

    Returns:
        tuple: (uuid, email) if person is found and activated
        None: if person is not found or not activated
    """
    url = f"{baseurl}/people?filter[email][eq]={email}"
    returned = calls.get(url)
    if returned["data"] == []:
        print("I couldn't find this user.")
    else:
        for api_items in returned["data"]:
            if api_items["attributes"]["registration_status"] == "activated":
                single_uuid = api_items["id"]
                single_email = api_items["attributes"]["email"]
                return (single_uuid, single_email)
            else:
                print(f"Person not found or activated. {email}")


def get_courses(course):
    """
    Retrieve course information by course name.

    Args:
        course (str): Name of the course to look up

    Returns:
        str: Course UUID if found
        None: if course is not found
    """
    print(f"LOOKING FOR COURSE {course}")
    encoded_course = quote(course)
    url = f"{baseurl}/courses?filter[name][eq]={encoded_course}"
    returned = calls.get(url)
    for items in returned["data"]:
        course_uuid = items["id"]
        course_name = items["attributes"]["name"]
        print(f"Cool. Course {course_uuid} - {course_name} exists.")
        return course_uuid


def create_attempt_payload(course_uuid, learner_uuid, date_str):
    """
    Create a course attempt payload for API submission.

    Args:
        course_uuid (str): UUID of the course
        learner_uuid (str): UUID of the learner
        date_str (str): Completion date string

    Returns:
        dict: Formatted payload for course attempt creation
    """
    print(f"Creating Course Attempt Payload")
    now = datetime.now()
    date_format = "%Y-%m-%d %H:%M:%S"
    if type(date_str) == str:
        if len(date_str) >= 8 and len(date_str) <= 10:
            date_str = f"{date_str} 00:00:00"
            formatted_date = datetime.strptime(date_str, date_format)
            formatted_date = str(formatted_date)
        else:
            formatted_date = datetime.strptime(date_str, date_format)
            formatted_date = str(formatted_date)
    mini_attempt_payload = {
        "type": "course_attempt_resources",
        "attributes": {
            "uuid": str(uuid.uuid4()),
            "display_name": f"{learner_uuid}s Attempt for course {course_uuid}",
            "data": {
                "learner_id": f"{learner_uuid}",
                "course_id": f"{course_uuid}",
                "progress": 100,
                "enrolled_at": formatted_date,
                "started_at": formatted_date,
                "completed_at": formatted_date,
                "completed_activities": [
                    {"id": str(uuid.uuid4()), "completed_at": formatted_date}
                ],
            },
        },
    }
    miniattempt_loads.append(mini_attempt_payload)
    attempt_payload = { "data": miniattempt_loads }
    return attempt_payload


def create_enrollment_payload(course_uuid, learner_uuid, date_str):
    """
    Create an enrollment payload for API submission.

    Args:
        course_uuid (str): UUID of the course
        learner_uuid (str): UUID of the learner
        date_str (str): Enrollment date string

    Returns:
        dict: Formatted payload for enrollment creation
    """
    print(f"Creating Course Enrollment Payload")
    now = datetime.now()
    date_format = "%Y-%m-%d %H:%M:%S"
    if type(date_str) == str:
        if len(date_str) >= 8 and len(date_str) <= 10:
            date_str = f"{date_str} 00:00:00"
            formatted_date = datetime.strptime(date_str, date_format)
            formatted_date = str(formatted_date)
        else:
            formatted_date = datetime.strptime(date_str, date_format)
            formatted_date = str(formatted_date)
    mini_enrollment_payload = {
        "type": "enrollment_resource",
        "attributes": {
            "uuid": str(uuid.uuid4()),
            "display_name": f"{learner_uuid}s enrollment for course {course_uuid}",
            "data": {
                "enrolled_at": formatted_date,
                "course_id": course_uuid,
                "learner_id": learner_uuid
            }
        }
    }
    minienroll_loads.append(mini_enrollment_payload)
    enrollment_payload = {"data": minienroll_loads }
    return enrollment_payload


def create_enrollment_resource(enrollment_payload):
    """
    Submit enrollment resource creation request to API.

    Args:
        enrollment_payload (dict): Formatted enrollment payload

    Prints API response status code.
    """
    item = items["enrollments"]
    enrollment_url = f"{baseurl}/migration/projects/{list(probject.values())[0]}/items/{item}/enrollment_resources"
    print(enrollment_url)
    print(f"Enrollment Payload is: {enrollment_payload}")
    enrollment_call = calls.post(enrollment_url, enrollment_payload)
    print(
        f"In trying the enrollment resource, the following code was returned: {enrollment_call.status_code}"
    )


def create_attempt_resource(attempt_payload):
    """
    Submit course attempt resource creation request to API.

    Args:
        attempt_payload (dict): Formatted course attempt payload

    Prints API response status code.
    """
    item = items["course_attempts"]
    attempt_url = f"{baseurl}/migration/projects/{list(probject.values())[0]}/items/{item}/course_attempt_resources"
    print(attempt_url)
    print(f"Attempt Payload is: {attempt_payload}")
    # attempt_payload2 = json.dumps(attempt_payload)
    attempt_call = calls.post(attempt_url, attempt_payload)
    print(
        f"In trying the attempt resource, the following code was returned: {attempt_call.status_code}"
    )

def create_project(project_name):
    """
    Create a new migration project.

    Args:
        project_name (str): Name of the project to create

    Updates global probject dictionary with new project ID.
    """
    proj_payload = {
        "data": {
            "type": "migration_projects",
            "attributes": {"name": project_name},
        }
    }
    proj_full_url = f"{baseurl}/migration/projects"
    tmp_p = calls.post(proj_full_url, proj_payload)
    probject[project_name] = tmp_p["data"]["id"]
    print(f"Created Project: {probject}")


def create_item(i_type):
    """
    Create a new migration item.

    Args:
        i_type (str): Type of item to create (e.g., 'course_attempts', 'enrollments')

    Returns:
        str: Created item ID

    Updates global items dictionary with new item ID.
    """
    print("Creating Item")
    # Item Type Options: 'courses', 'sections', 'activities', 'people', 'enrollments', 'course_attempts', 'quiz_attempts', 'certificates', 'learning_path_attempts'
    item_full_url = f"{baseurl}/migration/projects/{list(probject.values())[0]}/items"
    item_type = i_type
    print(item_type)
    item_payload = {
        "data": {
            "attributes": {"type": item_type},
        }
    }
    # "type": "migration_items",
    item_return = calls.post(item_full_url, item_payload)
    items[item_type] = item_return["data"]["id"]
    item_id = item_return["data"]["id"]
    print(f"Created Item ID: { items[item_type] }")
    return item_id


def start_migration():
    """
    Start the migration process for the created project.

    Sends request to API to begin migration and prints response.
    """
    print("Starting Migration Function")
    start_url = (
        f"{baseurl}/migration/projects/{list(probject.values())[0]}/start_migration"
    )
    empty = ""
    mig = calls.post(start_url, empty)
    print(mig.text)
    print(mig)


if __name__ == "__main__":
    create_project(project_name)
    create_item("course_attempts")
    create_item("enrollments")
    print(items)
    print(probject)
    get_data()
    # start_migration()
