import streamlit as st
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns

#Load data
fraud = pd.read_csv('fraud_test.csv')

# Define the percentage of data you want to sample
sample_percentage = 50  # Adjust this percentage as needed

# Randomly sample the data based on the percentage
data = fraud.sample(frac=sample_percentage/100, random_state=22)

# def annotate_bar(ax, custom_y_func, font_size=14):

#     for p in ax.patches:
#         # Calculate annotation
#         value = str(round(p.get_height(), 1))
#         x = (p.get_x() + p.get_width() / 2) * 0.99
#         y = ((p.get_y() + p.get_height() / 2) * 0.99)
        
#         y = custom_y_func(y)
#         ax.annotate(
#             value,
#             (x, y),
#             color="black",
#             size=font_size, ha='center', va='center'
#         )

def eda_page():

    st.title("Eksploratory Data Analysis")
    st.write('Analyze the DataFrame for Better Understanding')
    st.markdown("<h2><b>Top 10 Transaction Amount</b></h2>", unsafe_allow_html=True)

    # TOP Transaction Amount
    columns = ['job', 'state', 'city', 'merchant']
    fraud_labels = ['Not Fraud', 'Fraud']

    for col in columns:
        st.subheader(f"Top 10 transaction amount by {col}")
        fig, ax = plt.subplots(1, 2, figsize=(30, 5))
        for i, fraud_label in enumerate(fraud_labels):
            temp_data = data[data['is_fraud'] == (0 if fraud_label == 'Not Fraud' else 1)]
            top = temp_data.groupby(col)['amt'].sum().nlargest(10)
            ax[i].bar(top.index, top.values, color='#a1c9f4')
            ax[i].set_title(fraud_label)
            ax[i].set_xlabel(col)
            ax[i].set_ylabel('Amount')
            if col == 'state':
                ax[i].tick_params(axis='x', rotation=0)
            else:
                ax[i].tick_params(axis='x', rotation=90)
        st.pyplot(fig)
    st.write("**Explanation**:")
    markdown_text = """
    * From the top 10 transaction amount by job we can see `Science Writer` have the most fraud with over 10.000 transaction amount meanwhile `Film/Video editor` are the most non fraud with almost 160.000 transaction
    * From the top 10 transaction amount by state we can see `NY` have the most fraud with almost 60.000 transaction amount meanwhile `TX`are the most non fraud with above 1.400.000 transaction
    * From the top 10 transaction amount by city we can see `Camden` have the most fraud with over 10.000 transaction amount meanwhile `Meridian` are the most non fraud with almost 100.000 transaction
    * From the top 10 transaction amount by merchant we can see `Heathcote, Yost and Kertzmann` have most fraud with almost 10.000 transaction amount meanwhile `Killback-LLC` are the most non fraud with over 80.000 transaction
    """
    st.markdown(markdown_text)

    st.markdown("<h2><b>Top 10 Transaction Count</b></h2>", unsafe_allow_html=True)
    # By Transaction count
    columns = ['job', 'state', 'city', 'merchant']
    columns_name = ['Job', 'State', 'City', 'Merchant']
    fraud = ['Not Fraud', 'Fraud']

    for col, name in zip(columns, columns_name):
        st.subheader(f"Top 10 transaction by {name}")
        fig, ax = plt.subplots(1, 2, figsize=(30, 5))
        sns.set_palette("pastel")
        for i, fraud_label in enumerate(fraud):
            temp_data = data[data['is_fraud'] == (0 if fraud_label == 'Not Fraud' else 1)]
            top = temp_data.groupby(col).size().nlargest(10)
            ax[i].bar(top.index, top.values, color='#a1c9f4')
            ax[i].set_title(fraud_label)
            ax[i].set_xlabel(name)
            ax[i].set_ylabel('Count')
            if col == 'state':
                ax[i].tick_params(axis='x', rotation=0)
            else:
                ax[i].tick_params(axis='x', rotation=90)
        st.pyplot(fig)

    st.write("")  # Add a blank line

    st.write("**Explanation**:")
    markdown_text = """
    * From the top 10 transaction by job we can see `Color Technologist` have the most fraud with over 20 transaction meanwhile `Film/Video editor` are the most not fraud with over 2.000 transaction
    * From the top 10 transaction by state we can see `NY` have the most fraud with over 80 transaction meanwhile `TX`are the most not fraud with 20.000 transaction
    * From the top 10 transaction by city we can see `Camden` have the most fraud over 20 transaction meanwhile `Birmingham` are the most not fraud with almost 1.200 transaction
    * From the top 10 transaction by merchant we can see `Healthcore LLC.` have most fraud with 10 transaction meanwhile `Killback LLC.` are the most not fraud with almost 1.000 transaction
    """
    st.markdown(markdown_text)

    st.markdown("<h2><b>Total Number and Amount for Fraud and Non Fraud Transaction</b></h2>", unsafe_allow_html=True)
    
    def annotate_bar(ax, custom_y_func, font_size=14):
        for p in ax.patches:
            value = str(round(p.get_height(), 1))
            x = (p.get_x() + p.get_width() / 2) * 0.99
            y = ((p.get_y() + p.get_height() / 2) * 0.99)
            y = custom_y_func(y)
            ax.annotate(value, (x, y), color="black", size=font_size, ha='center', va='center')

    # Fraud and Not Fraud Transactions
    st.header("Fraud and Not Fraud Transactions Count")
    data_fraud_count = data['is_fraud'].apply(lambda x: "Fraud" if x == 1 else 'Not Fraud').value_counts().reset_index()
    fig, ax = plt.subplots(figsize=(15, 5))
    sns.barplot(data=data_fraud_count, x='is_fraud', y='count', color='#c6def8', ax=ax)
    annotate_bar(ax, lambda y: 15000 if y < 10000 else y, font_size=14)
    ax.set_title("Total number of transaction for fraud and not fraud transaction", fontsize=12, fontweight='bold')
    ax.set_ylabel("Transaction count")
    ax.set_xticklabels(ax.get_xticklabels(), rotation=0)
    st.pyplot(fig)

    # Fraud and Not Fraud Amount
    st.header("Fraud and Not Fraud Transactions Amount")
    data_fraud_amount = data.groupby('is_fraud')['amt'].sum().reset_index()
    fig, ax = plt.subplots(figsize=(15, 5))
    sns.barplot(data=data_fraud_amount, x='is_fraud', y='amt', color='#c6def8', ax=ax)
    annotate_bar(ax, lambda y: 1900000 if y < 1200000 else y, font_size=12)
    ax.set_title("Total transaction amount for fraud and not fraud transaction", fontsize=12, fontweight='bold')
    ax.set_ylabel("Transaction amount")
    ax.set_xticklabels(['Not Fraud', 'Fraud'], rotation=0)
    st.pyplot(fig)

    st.write("**Explanation**:")
    markdown_text = """
    Based on visualisation above:
    * There is 276743 total number of transaction `not fraud` and 1117 `fraud` transaction
    * There is 18745296.5 total transaction amount of `not fraud` and 1117 `fraud` transaction
    """
    st.markdown(markdown_text)

    # Calculate age
    data['dob'] = pd.to_datetime(data['dob'])
    data['age'] = (2020 - data['dob'].dt.year)

    def apply_age_group(age):
        if age <= 18:
            return 'Teenager'
        elif age <= 25:
            return "Young Adult"
        elif age <= 64:
            return "Adult"
        else:
            return "Elder"

    data['age_group'] = data['age'].apply(apply_age_group)

    # Overview of dataset by month, gender, and category
    st.header("Overview of dataset by Age, gender, and category")
    columns = ['gender', 'category', 'age', 'age_group']
    columns_name = ['gender', 'category', 'age', 'age group']
    name = ['Not Fraud', 'Fraud']

    for col in columns:
        st.subheader("Distribution of transaction by " + columns_name[columns.index(col)])
        fig, ax = plt.subplots(1, 2, figsize=(15, 5))  # Create a subplot with 2 columns
        for i in range(0, 2):
            data_1 = data[data['is_fraud'] == i]
            if col == 'gender':
                ax[i].pie(data_1[col].value_counts(), labels=['Female', 'Male'], autopct='%1.1f%%')
            elif col == 'age_group':
                ax[i].pie(data_1[col].value_counts(), labels=data_1[col].value_counts().index, autopct='%1.1f%%')
            elif col == 'category':
                sns.countplot(data=data_1, y=col, order=data_1[col].value_counts().index, ax=ax[i])
            else:
                sns.histplot(data=data_1, x=col, ax=ax[i])
            ax[i].set_title(name[i])
            ax[i].set_xlabel(columns_name[columns.index(col)])
            if col == 'category':
                ax[i].set_xticklabels(ax[i].get_xticklabels(), rotation=90)
        st.pyplot(fig)

    st.write("**Explanation**:")
    markdown_text = """
    Based on visualisation above we can see:
    - There is 54,8% transaction of `female` and 45,2% transaction of `male` in `not fraud` and `fraud`
    - Most distribution of `not fraud` transaction by category is from `gas_transport` meanwhile in fraud is from shopping_net
    - In distribution transaction by age mostly between 30-40 in `fraud` and between 45-50 for `not fraud`
    - By age group mostly `not fraud` transaction is from Adult with 73,9% and `fraud` also from Adult with 74,6%
    """
    st.markdown(markdown_text)