import json

import pandas as pd
import requests
import streamlit as st

from src.utils import yaml_config_loader


def load_yaml_config(path: str = "configs/config.yaml") -> dict:
    return yaml_config_loader(path)


def get_labels(labels: dict, key: str) -> list:
    return list(labels[key].keys())


def main() -> None:
    CONFIG = load_yaml_config()["streamlit_app"]
    URL = CONFIG["inference_endpoint"]
    LABEL_ENCODER_INFO = load_yaml_config(CONFIG["encoded_labels"])

    st.set_page_config(layout="wide")
    st.title("Alarm Detection System")

    uploaded_file = st.file_uploader("Upload a CSV file containing alarms data to predict their relevance", type="csv")

    if uploaded_file:
        df = pd.read_csv(uploaded_file, header=0)
        df.fillna("", inplace=True)
        st.write(df)

        data_json = df.to_json(orient="records")

        response = requests.post(URL, headers={"Content-Type": "application/json"}, data=data_json)

        if response.status_code == 200:
            predictions = response.json().get("predictions")
            st.write("### Predictions:")
            predictions = map(lambda x: "Relevant" if x == 1 else "Irrelevant", predictions)
            st.write(list(predictions))
        else:
            st.write(f"Error in API call: {response.status_code}")
            st.write("Response body:", response.text)
        return

    st.write("Enter the alarm details to predict")
    st.warning("The following fields are case sensitive")
    col1, col2, col3 = st.columns(3)
    labels = LABEL_ENCODER_INFO

    with col1:
        severity = st.selectbox("Severity", get_labels(labels, "Severity"), index=None)
        alarm_name = st.selectbox("Alarm Name", get_labels(labels, "Alarm Name"), index=None)
        alarm_category = st.selectbox("Alarm Category", get_labels(labels, "Alarm Category"), index=None)
        technical_id = st.selectbox("Technical ID", get_labels(labels, "Technical ID"), index=None)
        ne_type = st.selectbox("NE Type", get_labels(labels, "NE Type"), index=None)

    with col2:
        ne_name = st.text_input("NE Name")
        source = st.text_input("Source")
        site_name = st.text_input("Site Name")
        site_id = st.text_input("Site ID")
        technology = st.selectbox("Technology", get_labels(labels, "Technology"), index=None)

    with col3:
        # date_format = "%m/%d/%Y %I:%M:%S %p"
        date_format = "MM/DD/YYYY"
        first_occurence_date = st.date_input("First Occurence Date", value=None, format=date_format)
        first_occurence_time = st.time_input("First Occurence Time", value=None)
        last_occurence_date = st.date_input("Last Occurence Date", value=None, format=date_format)
        last_occurence_time = st.time_input("Last Occurence Time", value=None)
        parent_node = st.selectbox("Parent Node", get_labels(labels, "Parent Node"), index=None)

        first_occurence = (
            f"{first_occurence_date.strftime('%m/%d/%Y')} {first_occurence_time.strftime('%I:%M:%S %p')}"
            if first_occurence_date and first_occurence_time
            else None
        )
        last_occurence = (
            f"{last_occurence_date.strftime('%m/%d/%Y')} {last_occurence_time.strftime('%I:%M:%S %p')}"
            if last_occurence_date and last_occurence_time
            else None
        )

    data = {
        "Severity": severity,
        "Alarm Name": alarm_name,
        "Technical ID": str(technical_id),
        "Site Name": site_name,
        "Site ID": str(site_id),
        "NE Name": ne_name,
        "Source": source,
        "NE Type": ne_type,
        "Technology": technology,
        "Alarm Category": alarm_category,
        "Parent Node": "" if pd.isna(parent_node) else parent_node,
        "First Occurence": first_occurence,
        "Last Occurence": last_occurence,
    }

    if st.button("Predict"):
        data_json = json.dumps(data)
        response = requests.post(URL, headers={"Content-Type": "application/json"}, data=data_json)

        st.write("<span style='color:#5497A7'>*The data that you entered has been saved to* `../data/external/raw_inference_data.csv`</span>", unsafe_allow_html=True)
        st.write(data_json)

        if response.status_code == 200:
            predictions = response.json().get("predictions")[0]
            if predictions == 0:
                st.write(">>> <span style='color:grey'>**Alarm is Irrelevant**</span>", unsafe_allow_html=True)
            else:
                st.write(">>> <span style='color:#799673'>**Alarm is Relevant**</span>", unsafe_allow_html=True)
        else:
            st.write(f"Error in API call: {response.status_code}")
            st.write("Response body:", response.text)  # Log the error message from the API


if __name__ == "__main__":
    main()
