import requests
import os
import zipfile
import pandas
import json

API_KEY = "API-KEY-GOES-HERE"
STUDY_ID = "STUDY-ID-GOES-HERE"
OUTPUT_DIR = "data"
BASE_URL = "http://localhost:8083"

def unzip_study_data(zip_path):
    try:
        with zipfile.ZipFile(zip_path, 'r') as zip_file:
            zip_file.extractall(OUTPUT_DIR)
    except Exception as e:
        print(f"An error occurred while unzipping the file: {e}")

def save_study_data(response):
    zip_path = os.path.join(OUTPUT_DIR, "study_data.zip")
    try:
        with open(zip_path, "wb") as f:
            f.write(response.content)
    except IOError as e:
        print(f"Error saving zip file: {e}")
        return None
    return zip_path

def get_participants():
    path = os.path.join(OUTPUT_DIR, "coupon.csv")
    return pandas.read_csv(path)

def get_active_participants(participants_df):
    active_states = ["verified1", "payoutAvailable", "payoutPending"]
    return participants_df[participants_df['consentstatus'].isin(active_states)]

def get_all_answers():
    path = os.path.join(OUTPUT_DIR, "answers.csv")
    return pandas.read_csv(path)

def get_answers_for_participant(all_answers, participant_id):
    return all_answers[all_answers["couponid"] == participant_id]

def send_message_to_participant(messages):
    url = f"{BASE_URL}/DataAnalysisService/rest/messages/sendNotifications?studyId={STUDY_ID}"
    headers = {
        "Content-Type": "application/json",
        "Authorization": f"Bearer {API_KEY}"
    }

    try:
        json_data = json.dumps(messages)

        print(f"calling {url}")
        response = requests.post(url=url, data=json_data, headers=headers)
        response.raise_for_status()
        print(f"status code: {response.status_code}")
        print(f"response body: {response.content}")
        resp_data = response.json()
        for resp in resp_data:
            print(f"participant: {resp.get('couponNumber')}, status: {resp.get('status')}")

    except requests.exceptions.RequestException as e:
        print(f"Failed to send notification: {e}")
    except json.JSONDecodeError:
        print("Failed to decode JSON response")

def generate_participant_message(participant, all_answers):
    participant_no = participant["couponNumber"]
    print(f"filtering answers for {participant_no}")
    answers_by_participant = get_answers_for_participant(all_answers, participant["couponid"])

    message = "Will be glad to know why you are not participating"
    if answers_by_participant.shape[0] > 0:
        message = "Well done, keep this up"

    return message


def download_study_data():
    url = f"{BASE_URL}/DataAnalysisService/rest/exportData/exportStudy?studyId={STUDY_ID}"
    headers = {
        "Content-Type": "application/zip",
        "Authorization": f"Bearer {API_KEY}"
    }
    try:
        print(f"calling {url}")
        response = requests.post(url, headers=headers)
        print(f"Status Code: {response.status_code}")
        response.raise_for_status()
        return response

    except requests.exceptions.RequestException as e:
        print(f"Error downloading study data: {e}")
        return None

def main() -> int:
    try:
        os.makedirs(OUTPUT_DIR, exist_ok=True)

        print(f"Downloading study data ({STUDY_ID})")
        response = download_study_data()

        if response == None:
            print("download failed")
            return 1
        
        print("saving study data")
        zip_path = save_study_data(response)
        if zip_path == None:
            print("saving study data failed")
            return 2

        print("unzipping study data")
        unzip_study_data(zip_path)

        print("Retrieving all participants")
        participants_df = get_participants()

        print("Retrieving active participants")
        active_participants_df = get_active_participants(participants_df)

        print("Getting all answers")
        all_answers = get_all_answers()

        messages = {}
        messages["couponToMessage"] = []
        for _, participant in active_participants_df.iterrows():
            message = generate_participant_message(participant, all_answers)
            messages["couponToMessage"].append({ "couponNumber": participant["couponNumber"], "message": message })

        send_message_to_participant(messages)

            
    except Exception as e:
        print(f"An error occurred: {e}")
        return 3

    return 0

if __name__ == "__main__":
    raise SystemExit(main())
