# Standard library imports
import glob
import json
import os
import warnings
from datetime import datetime, timedelta
from itertools import product

# Third-party imports
import dash
import dash_bootstrap_components as dbc
import numpy as np
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
from dash import callback, callback_context, ctx, dcc, html
from dash.dependencies import Input, Output

# Config import
from dashboard.config import (
    critical_color,
    fail_color,
    folder_path_overview,
    high_color,
    info_color,
    informational_color,
    low_color,
    manual_color,
    medium_color,
    muted_fail_color,
    muted_manual_color,
    muted_pass_color,
    pass_color,
)
from dashboard.lib.cards import create_provider_card
from dashboard.lib.dropdowns import (
    create_account_dropdown,
    create_date_dropdown,
    create_provider_dropdown,
    create_region_dropdown,
    create_service_dropdown,
    create_severity_dropdown,
    create_status_dropdown,
    create_table_row_dropdown,
)
from dashboard.lib.layouts import create_layout_overview
from prowler.lib.logger import logger

# Suppress warnings
warnings.filterwarnings("ignore")

# Global variables
# TODO: Create a flag to let the user put a custom path
csv_files = []

for file in glob.glob(os.path.join(folder_path_overview, "*.csv")):
    try:
        df = pd.read_csv(file, sep=";")
        num_rows = len(df)
        if num_rows > 1:
            csv_files.append(file)
    except Exception:
        logger.error(f"Error reading file {file}")


# Import logos providers
aws_provider_logo = html.Img(
    src="assets/images/providers/aws_provider.png", alt="aws provider"
)
azure_provider_logo = html.Img(
    src="assets/images/providers/azure_provider.png", alt="azure provider"
)
gcp_provider_logo = html.Img(
    src="assets/images/providers/gcp_provider.png", alt="gcp provider"
)
ks8_provider_logo = html.Img(
    src="assets/images/providers/k8s_provider.png", alt="k8s provider"
)
m365_provider_logo = html.Img(
    src="assets/images/providers/m365_provider.png", alt="m365 provider"
)


def load_csv_files(csv_files):
    """Load CSV files into a single pandas DataFrame."""
    dfs = []
    for file in csv_files:
        account_columns = ["ACCOUNT_ID", "ACCOUNT_UID", "SUBSCRIPTION"]

        df_sample = pd.read_csv(file, sep=";", on_bad_lines="skip", nrows=1)

        dtype_dict = {}
        for col in account_columns:
            if col in df_sample.columns:
                dtype_dict[col] = str

        # Read the full file with proper dtypes
        df = pd.read_csv(file, sep=";", on_bad_lines="skip", dtype=dtype_dict)

        if "CHECK_ID" in df.columns:
            if "TIMESTAMP" in df.columns or df["PROVIDER"].unique() == "aws":
                dfs.append(df.astype(str))
    # Handle the case where there are no files
    try:
        data = pd.concat(dfs, ignore_index=True)
    except ValueError:
        data = None
    return data


data = load_csv_files(csv_files)

if data is None:
    # Initializing the Dash App
    dash.register_page(__name__, path="/")

    layout = html.Div(
        [
            html.H1(
                "No data available",
                className="text-prowler-stone-900 text-2xxl font-bold",
            ),
            html.Div(className="flex justify-between border-b border-prowler-500 pb-3"),
            html.Div(
                [
                    html.Div(
                        "Check the data folder to see if the files are in the correct format",
                        className="text-prowler-stone-900 text-lg font-bold",
                    )
                ],
                className="grid gap-x-4 gap-y-4 sm:grid-cols-2 lg:grid-cols-3 lg:gap-y-0",
            ),
        ]
    )
else:
    # This handles the case where we are using v3 outputs
    if "ASSESSMENT_START_TIME" in data.columns:
        data["ASSESSMENT_START_TIME"] = data["ASSESSMENT_START_TIME"].str.replace(
            "T", " "
        )
        data.rename(columns={"ASSESSMENT_START_TIME": "TIMESTAMP_AUX"}, inplace=True)
        # Unify the columns
        data["TIMESTAMP"] = data.apply(
            lambda x: (
                x["TIMESTAMP_AUX"] if pd.isnull(x["TIMESTAMP"]) else x["TIMESTAMP"]
            ),
            axis=1,
        )
    if "ACCOUNT_ID" in data.columns:
        data.rename(columns={"ACCOUNT_ID": "ACCOUNT_UID_AUX"}, inplace=True)
        data["ACCOUNT_UID"] = data.apply(
            lambda x: (
                x["ACCOUNT_UID_AUX"]
                if pd.isnull(x["ACCOUNT_UID"])
                else x["ACCOUNT_UID"]
            ),
            axis=1,
        )
    # Rename the column RESOURCE_ID to RESOURCE_UID
    if "RESOURCE_ID" in data.columns:
        data.rename(columns={"RESOURCE_ID": "RESOURCE_UID_AUX"}, inplace=True)
        data["RESOURCE_UID"] = data.apply(
            lambda x: (
                x["RESOURCE_UID_AUX"]
                if pd.isnull(x["RESOURCE_UID"])
                else x["RESOURCE_UID"]
            ),
            axis=1,
        )
    # Rename the column "SUBSCRIPTION" to "ACCOUNT_UID"
    if "SUBSCRIPTION" in data.columns:
        data.rename(columns={"SUBSCRIPTION": "ACCOUNT_UID_AUX"}, inplace=True)
        data["ACCOUNT_UID"] = data.apply(
            lambda x: (
                x["ACCOUNT_UID_AUX"]
                if pd.isnull(x["ACCOUNT_UID"])
                else x["ACCOUNT_UID"]
            ),
            axis=1,
        )

    # For the timestamp, remove the two columns and keep only the date
    data["TIMESTAMP"] = pd.to_datetime(data["TIMESTAMP"])
    # Handle findings from v3 outputs
    if "FINDING_UNIQUE_ID" in data.columns:
        data.rename(columns={"FINDING_UNIQUE_ID": "FINDING_UID"}, inplace=True)
    if "ACCOUNT_ID" in data.columns:
        data.rename(columns={"ACCOUNT_ID": "ACCOUNT_UID"}, inplace=True)
    if "ASSESSMENT_START_TIME" in data.columns:
        data.rename(columns={"ASSESSMENT_START_TIME": "TIMESTAMP"}, inplace=True)
    if "RESOURCE_ID" in data.columns:
        data.rename(columns={"RESOURCE_ID": "RESOURCE_UID"}, inplace=True)

    # Remove dupplicates on the finding_uid colummn but keep the last one taking into account the timestamp
    data["DATE"] = data["TIMESTAMP"].dt.date
    data = (
        data.sort_values("TIMESTAMP")
        .groupby(["DATE", "FINDING_UID"], as_index=False)
        .last()
    )
    data["TIMESTAMP"] = pd.to_datetime(data["TIMESTAMP"])

    data["ASSESSMENT_TIME"] = data["TIMESTAMP"].dt.strftime("%Y-%m-%d")
    data_valid = pd.DataFrame()
    for account in data["ACCOUNT_UID"].unique():
        all_times = data[data["ACCOUNT_UID"] == account]["ASSESSMENT_TIME"].unique()
        all_times.sort()
        all_times = all_times[::-1]
        times = []
        # select the last ASSESSMENT_TIME in the day for each account
        for time in all_times:
            if time.split(" ")[0] not in [
                times[i].split(" ")[0] for i in range(len(times))
            ]:
                times.append(time)
        # select the data from the last ASSESSMENT_TIME of the day
        data_valid = pd.concat(
            [
                data_valid,
                data[
                    (data["ACCOUNT_UID"] == account)
                    & (data["ASSESSMENT_TIME"].isin(times))
                ],
            ]
        )
    data = data_valid
    # Select only the day in the data
    data["ASSESSMENT_TIME"] = data["ASSESSMENT_TIME"].apply(lambda x: x.split(" ")[0])

    data["TIMESTAMP"] = data["TIMESTAMP"].dt.strftime("%Y-%m-%d")
    data["TIMESTAMP"] = pd.to_datetime(data["TIMESTAMP"])

    # Assessment Date Dropdown
    assesment_times = list(data["ASSESSMENT_TIME"].unique())
    assesment_times.sort()
    assesment_times.reverse()
    date_dropdown = create_date_dropdown(assesment_times)

    # Cloud Account Dropdown
    accounts = []
    if "ACCOUNT_NAME" in data.columns:
        for account in data["ACCOUNT_NAME"].unique():
            if "azure" in list(data[data["ACCOUNT_NAME"] == account]["PROVIDER"]):
                accounts.append(account + " - AZURE")
            if "gcp" in list(data[data["ACCOUNT_NAME"] == account]["PROVIDER"]):
                accounts.append(account + " - GCP")
            if "m365" in list(data[data["ACCOUNT_NAME"] == account]["PROVIDER"]):
                accounts.append(account + " - M365")

    if "ACCOUNT_UID" in data.columns:
        for account in data["ACCOUNT_UID"].unique():
            if "aws" in list(data[data["ACCOUNT_UID"] == account]["PROVIDER"]):
                accounts.append(account + " - AWS")
            if "kubernetes" in list(data[data["ACCOUNT_UID"] == account]["PROVIDER"]):
                accounts.append(account + " - K8S")

    account_dropdown = create_account_dropdown(accounts)

    # Region Dropdown
    # Handle the case where there is location column
    if "LOCATION" in data.columns:
        data["REGION"] = data["LOCATION"]
    # Handle the case where there is no region column
    if "REGION" not in data.columns:
        data["REGION"] = "-"
    # Handle the case where the region is null
    data["REGION"].fillna("-")
    regions = ["All"] + list(data["REGION"].unique())
    regions = [x for x in regions if str(x) != "nan" and x.__class__.__name__ == "str"]
    # Correct the values
    options = []
    for value in regions:
        if " " in value:
            options.append(value.split(" ")[1])
        else:
            options.append(value)
    regions = options
    region_dropdown = create_region_dropdown(regions)

    # Severity Dropdown
    severity = ["All"] + list(data["SEVERITY"].unique())
    severity = [
        x for x in severity if str(x) != "nan" and x.__class__.__name__ == "str"
    ]

    severity_dropdown = create_severity_dropdown(severity)

    # Service Dropdown
    services = []
    for service in data["SERVICE_NAME"].unique():
        if "aws" in list(data[data["SERVICE_NAME"] == service]["PROVIDER"]):
            services.append(service + " - AWS")
        if "kubernetes" in list(data[data["SERVICE_NAME"] == service]["PROVIDER"]):
            services.append(service + " - K8S")
        if "azure" in list(data[data["SERVICE_NAME"] == service]["PROVIDER"]):
            services.append(service + " - AZURE")
        if "gcp" in list(data[data["SERVICE_NAME"] == service]["PROVIDER"]):
            services.append(service + " - GCP")
        if "m365" in list(data[data["SERVICE_NAME"] == service]["PROVIDER"]):
            services.append(service + " - M365")

    services = ["All"] + services
    services = [
        x for x in services if str(x) != "nan" and x.__class__.__name__ == "str"
    ]

    service_dropdown = create_service_dropdown(services)

    # Provider Dropdown
    providers = ["All"] + list(data["PROVIDER"].unique())
    providers = [
        x for x in providers if str(x) != "nan" and x.__class__.__name__ == "str"
    ]
    provider_dropdown = create_provider_dropdown(providers)

    # Create the download button
    download_button_csv = html.Button(
        "Download this table as CSV",
        id="download_link_csv",
        n_clicks=0,
        className="border-solid border-2 border-prowler-stone-900/10 hover:border-solid hover:border-2 hover:border-prowler-stone-900/10 text-prowler-stone-900 inline-block px-4 py-2 text-xs font-bold uppercase transition-all rounded-lg text-gray-900 hover:bg-prowler-stone-900/10 flex justify-end w-fit",
    )
    download_button_xlsx = html.Button(
        "Download this table as XLSX",
        id="download_link_xlsx",
        n_clicks=0,
        className="border-solid border-2 border-prowler-stone-900/10 hover:border-solid hover:border-2 hover:border-prowler-stone-900/10 text-prowler-stone-900 inline-block px-4 py-2 text-xs font-bold uppercase transition-all rounded-lg text-gray-900 hover:bg-prowler-stone-900/10 flex justify-end w-fit",
    )

    # Create the table row dropdown
    table_row_values = [-1]
    table_row_dropdown = create_table_row_dropdown(table_row_values)

    # Create the status dropdown
    status = ["All"] + list(data["STATUS"].unique())
    status = [x for x in status if str(x) != "nan" and x.__class__.__name__ == "str"]

    status_dropdown = create_status_dropdown(status)
    table_div_header = []
    table_div_header.append(
        html.Div(
            [
                html.Div(
                    [
                        html.Span(
                            "Check Name",
                            className="text-prowler-stone-900 uppercase text-sm xl:text-md font-bold",
                        ),
                        html.Button(
                            html.Img(
                                src="assets/images/icons/arrows.svg",
                                style={
                                    "width": "1rem",
                                    "height": "1rem",
                                    "margin-left": "0.2rem",
                                    "margin-top": "0.2rem",
                                },
                            ),
                            id="sort_button_check_name",
                            n_clicks=0,
                        ),
                    ],
                    className="w-[40.5%] 2xl:w-[71.5%]",
                ),
                html.Div(
                    [
                        html.Span(
                            "Severity",
                            className="text-prowler-stone-900 uppercase text-sm xl:text-md font-bold",
                        ),
                        html.Button(
                            html.Img(
                                src="assets/images/icons/arrows.svg",
                                style={
                                    "width": "1rem",
                                    "height": "1rem",
                                    "margin-left": "0.2rem",
                                    "margin-top": "0.2rem",
                                },
                            ),
                            id="sort_button_severity",
                            n_clicks=0,
                        ),
                    ],
                    className="w-[11%] 2xl:w-[15.5%]",
                ),
                html.Div(
                    [
                        html.Span(
                            "Status",
                            className="text-prowler-stone-900 uppercase text-sm xl:text-md font-bold",
                        ),
                        html.Button(
                            html.Img(
                                src="assets/images/icons/arrows.svg",
                                style={
                                    "width": "1rem",
                                    "height": "1rem",
                                    "margin-left": "0.2rem",
                                    "margin-top": "0.2rem",
                                },
                            ),
                            id="sort_button_status",
                            n_clicks=0,
                        ),
                    ],
                    className="w-[9%] 2xl:w-[12.5%]",
                ),
                html.Div(
                    [
                        html.Span(
                            "Region",
                            className="text-prowler-stone-900 uppercase text-sm xl:text-md font-bold",
                        ),
                        html.Button(
                            html.Img(
                                src="assets/images/icons/arrows.svg",
                                style={
                                    "width": "1rem",
                                    "height": "1rem",
                                    "margin-left": "0.2rem",
                                    "margin-top": "0.2rem",
                                },
                            ),
                            id="sort_button_region",
                            n_clicks=0,
                        ),
                    ],
                    className="w-[10%] 2xl:w-[14%]",
                ),
                html.Div(
                    [
                        html.Span(
                            "Service",
                            className="text-prowler-stone-900 uppercase text-sm xl:text-md font-bold",
                        ),
                        html.Button(
                            html.Img(
                                src="assets/images/icons/arrows.svg",
                                style={
                                    "width": "1rem",
                                    "height": "1rem",
                                    "margin-left": "0.2rem",
                                    "margin-top": "0.2rem",
                                },
                            ),
                            id="sort_button_service",
                            n_clicks=0,
                        ),
                    ],
                    className="w-[13.5%] 2xl:w-[14%]",
                ),
                html.Div(
                    [
                        html.Span(
                            "Account",
                            className="text-prowler-stone-900 uppercase text-sm xl:text-md font-bold",
                        ),
                        html.Button(
                            html.Img(
                                src="assets/images/icons/arrows.svg",
                                style={
                                    "width": "1rem",
                                    "height": "1rem",
                                    "margin-left": "0.2rem",
                                    "margin-top": "0.2rem",
                                },
                            ),
                            id="sort_button_account",
                            n_clicks=0,
                        ),
                    ],
                    className="w-[15%] 2xl:w-[15.5%]",
                ),
            ],
            className="grid grid-cols-auto w-full",
            style={
                "display": "flex",
            },
        )
    )

    table_div_header = html.Div(table_div_header, id="table-div-header")

    # Initializing the Dash App
    dash.register_page(__name__, path="/")

    # Create the layout
    layout = create_layout_overview(
        account_dropdown,
        date_dropdown,
        region_dropdown,
        download_button_csv,
        download_button_xlsx,
        severity_dropdown,
        service_dropdown,
        provider_dropdown,
        table_row_dropdown,
        status_dropdown,
        table_div_header,
        len(data["PROVIDER"].unique()),
    )


# Callback to display selected value
@callback(
    [
        Output("status_graph", "children"),
        Output("two_pie_chart", "children"),
        Output("line_plot", "children"),
        Output("table", "children"),
        Output("download-data", "data"),
        Output("cloud-account-filter", "value"),
        Output("cloud-account-filter", "options"),
        Output("region-filter", "value"),
        Output("region-filter", "options"),
        Output("report-date-filter", "value"),
        Output("aws_card", "children"),
        Output("azure_card", "children"),
        Output("gcp_card", "children"),
        Output("k8s_card", "children"),
        Output("m365_card", "children"),
        Output("subscribe_card", "children"),
        Output("info-file-over", "title"),
        Output("severity-filter", "value"),
        Output("severity-filter", "options"),
        Output("service-filter", "value"),
        Output("provider-filter", "value"),
        Output("provider-filter", "options"),
        Output("service-filter", "options"),
        Output("table-rows", "value"),
        Output("table-rows", "options"),
        Output("status-filter", "value"),
        Output("status-filter", "options"),
        Output("aws_card", "n_clicks"),
        Output("azure_card", "n_clicks"),
        Output("gcp_card", "n_clicks"),
        Output("k8s_card", "n_clicks"),
        Output("m365_card", "n_clicks"),
    ],
    Input("cloud-account-filter", "value"),
    Input("region-filter", "value"),
    Input("report-date-filter", "value"),
    Input("download_link_csv", "n_clicks"),
    Input("download_link_xlsx", "n_clicks"),
    Input("severity-filter", "value"),
    Input("service-filter", "value"),
    Input("provider-filter", "value"),
    Input("table-rows", "value"),
    Input("status-filter", "value"),
    Input("search-input", "value"),
    Input("aws_card", "n_clicks"),
    Input("azure_card", "n_clicks"),
    Input("gcp_card", "n_clicks"),
    Input("k8s_card", "n_clicks"),
    Input("m365_card", "n_clicks"),
    Input("sort_button_check_name", "n_clicks"),
    Input("sort_button_severity", "n_clicks"),
    Input("sort_button_status", "n_clicks"),
    Input("sort_button_region", "n_clicks"),
    Input("sort_button_service", "n_clicks"),
    Input("sort_button_account", "n_clicks"),
)
def filter_data(
    cloud_account_values,
    region_account_values,
    assessment_value,
    n_clicks_csv,
    n_clicks_xlsx,
    severity_values,
    service_values,
    provider_values,
    table_row_values,
    status_values,
    search_value,
    aws_clicks,
    azure_clicks,
    gcp_clicks,
    k8s_clicks,
    m365_clicks,
    sort_button_check_name,
    sort_button_severity,
    sort_button_status,
    sort_button_region,
    sort_button_service,
    sort_button_account,
):
    # Use n_clicks for vulture
    n_clicks_csv = n_clicks_csv
    n_clicks_xlsx = n_clicks_xlsx
    # Filter the data
    filtered_data = data.copy()

    if aws_clicks > 0:
        filtered_data = data.copy()
        if aws_clicks % 2 != 0 and "aws" in list(data["PROVIDER"]):
            filtered_data = filtered_data[filtered_data["PROVIDER"] == "aws"]
            azure_clicks = 0
            gcp_clicks = 0
            k8s_clicks = 0
            m365_clicks = 0
    if azure_clicks > 0:
        filtered_data = data.copy()
        if azure_clicks % 2 != 0 and "azure" in list(data["PROVIDER"]):
            filtered_data = filtered_data[filtered_data["PROVIDER"] == "azure"]
            aws_clicks = 0
            gcp_clicks = 0
            k8s_clicks = 0
            m365_clicks = 0
    if gcp_clicks > 0:
        filtered_data = data.copy()
        if gcp_clicks % 2 != 0 and "gcp" in list(data["PROVIDER"]):
            filtered_data = filtered_data[filtered_data["PROVIDER"] == "gcp"]
            aws_clicks = 0
            azure_clicks = 0
            k8s_clicks = 0
            m365_clicks = 0
    if k8s_clicks > 0:
        filtered_data = data.copy()
        if k8s_clicks % 2 != 0 and "kubernetes" in list(data["PROVIDER"]):
            filtered_data = filtered_data[filtered_data["PROVIDER"] == "kubernetes"]
            aws_clicks = 0
            azure_clicks = 0
            gcp_clicks = 0
            m365_clicks = 0
    if m365_clicks > 0:
        filtered_data = data.copy()
        if m365_clicks % 2 != 0 and "m365" in list(data["PROVIDER"]):
            filtered_data = filtered_data[filtered_data["PROVIDER"] == "m365"]
            aws_clicks = 0
            azure_clicks = 0
            gcp_clicks = 0
            k8s_clicks = 0

    # For all the data, we will add to the status column the value 'MUTED (FAIL)' and 'MUTED (PASS)' depending on the value of the column 'STATUS' and 'MUTED'
    if "MUTED" in filtered_data.columns:
        filtered_data["STATUS"] = filtered_data.apply(
            lambda x: (
                "MUTED (FAIL)"
                if x["STATUS"] == "FAIL" and x["MUTED"] == "True"
                else x["STATUS"]
            ),
            axis=1,
        )
        filtered_data["STATUS"] = filtered_data.apply(
            lambda x: (
                "MUTED (PASS)"
                if x["STATUS"] == "PASS" and x["MUTED"] == "True"
                else x["STATUS"]
            ),
            axis=1,
        )
        filtered_data["STATUS"] = filtered_data.apply(
            lambda x: (
                "MUTED (MANUAL)"
                if x["STATUS"] == "MANUAL" and x["MUTED"] == "True"
                else x["STATUS"]
            ),
            axis=1,
        )

    # Take the latest date of de data
    account_date = filtered_data["ASSESSMENT_TIME"].unique()
    account_date.sort()
    account_date = account_date[::-1]

    start_date = datetime.strptime(account_date[0], "%Y-%m-%d") - timedelta(days=7)
    end_date = datetime.strptime(account_date[0], "%Y-%m-%d")

    filtered_data_sp = filtered_data[
        (filtered_data["TIMESTAMP"] >= start_date)
        & (filtered_data["TIMESTAMP"] <= end_date)
    ]
    # We are taking the latest date if there is only one account
    # Filter Assessment Time
    if assessment_value in account_date:
        updated_assessment_value = assessment_value
    else:
        updated_assessment_value = account_date[0]
        assessment_value = account_date[0]
    filtered_data = filtered_data[
        filtered_data["ASSESSMENT_TIME"] == updated_assessment_value
    ]

    # Select the files in the list_files that have the same date as the selected date
    list_files = []
    for file in csv_files:
        df = pd.read_csv(file, sep=";", on_bad_lines="skip")
        if "CHECK_ID" in df.columns:
            if "TIMESTAMP" in df.columns or df["PROVIDER"].unique() == "aws":
                # This handles the case where we are using v3 outputs
                if "TIMESTAMP" not in df.columns and df["PROVIDER"].unique() == "aws":
                    # Rename the column 'ASSESSMENT_START_TIME' to 'TIMESTAMP'
                    df["ASSESSMENT_START_TIME"] = df[
                        "ASSESSMENT_START_TIME"
                    ].str.replace("T", " ")
                    df.rename(
                        columns={"ASSESSMENT_START_TIME": "TIMESTAMP"}, inplace=True
                    )
                    df["TIMESTAMP"] = df["TIMESTAMP"].str.replace("T", " ")
                df["TIMESTAMP"] = pd.to_datetime(df["TIMESTAMP"])
                df["TIMESTAMP"] = df["TIMESTAMP"].dt.strftime("%Y-%m-%d")
                if df["TIMESTAMP"][0] == updated_assessment_value:
                    list_files.append(file)
    # append all the names of the files
    files_names = []
    for file in list_files:
        files_names.append(file.split("/")[-1])

    list_files = ",\n".join(files_names)
    list_files = "Files Scanned:\n" + list_files

    # Change the account selector to the values that are allowed
    filtered_data = filtered_data[
        filtered_data["ASSESSMENT_TIME"] == updated_assessment_value
    ]

    # fill all_account_ids with the account_uid for the provider aws and kubernetes
    all_account_ids = []
    if "ACCOUNT_UID" in filtered_data.columns:
        for account in filtered_data["ACCOUNT_UID"].unique():
            if "aws" in list(data[data["ACCOUNT_UID"] == account]["PROVIDER"]):
                all_account_ids.append(account)
            if "kubernetes" in list(data[data["ACCOUNT_UID"] == account]["PROVIDER"]):
                all_account_ids.append(account)

    all_account_names = []
    if "ACCOUNT_NAME" in filtered_data.columns:
        for account in filtered_data["ACCOUNT_NAME"].unique():
            if "azure" in list(data[data["ACCOUNT_NAME"] == account]["PROVIDER"]):
                all_account_names.append(account)
            if "gcp" in list(data[data["ACCOUNT_NAME"] == account]["PROVIDER"]):
                all_account_names.append(account)
            if "m365" in list(data[data["ACCOUNT_NAME"] == account]["PROVIDER"]):
                all_account_names.append(account)

    all_items = all_account_ids + all_account_names + ["All"]

    cloud_accounts_options = ["All"]
    for item in all_items:
        if item not in cloud_accounts_options and item.__class__.__name__ == "str":
            # append the provider name depending on the account
            if "ACCOUNT_UID" in filtered_data.columns:
                if "aws" in list(data[data["ACCOUNT_UID"] == item]["PROVIDER"]):
                    cloud_accounts_options.append(item + " - AWS")
                if "kubernetes" in list(data[data["ACCOUNT_UID"] == item]["PROVIDER"]):
                    cloud_accounts_options.append(item + " - K8S")
            if "ACCOUNT_NAME" in filtered_data.columns:
                if "azure" in list(data[data["ACCOUNT_NAME"] == item]["PROVIDER"]):
                    cloud_accounts_options.append(item + " - AZURE")
                if "gcp" in list(data[data["ACCOUNT_NAME"] == item]["PROVIDER"]):
                    cloud_accounts_options.append(item + " - GCP")
                if "m365" in list(data[data["ACCOUNT_NAME"] == item]["PROVIDER"]):
                    cloud_accounts_options.append(item + " - M365")

    # Filter ACCOUNT
    if cloud_account_values == ["All"]:
        updated_cloud_account_values = all_items
    elif "All" in cloud_account_values and len(cloud_account_values) > 1:
        updated_cloud_account_values = []
        # Remove 'All' from the list
        cloud_account_values.remove("All")
        for item in cloud_account_values:
            updated_cloud_account_values.append(item.split(" - ")[0])
    elif len(cloud_account_values) == 0:
        updated_cloud_account_values = all_items
        cloud_account_values = ["All"]
    else:
        updated_cloud_account_values = []
        for item in cloud_account_values:
            updated_cloud_account_values.append(item.split(" - ")[0])
    values_choice = []
    for item in updated_cloud_account_values:
        if item not in values_choice:
            values_choice.append(item)

    # Apply the filter
    if (
        "ACCOUNT_UID" in filtered_data.columns
        and "ACCOUNT_NAME" in filtered_data.columns
    ):
        filtered_data = filtered_data[
            filtered_data["ACCOUNT_UID"].isin(values_choice)
            | filtered_data["ACCOUNT_NAME"].isin(values_choice)
        ]
    elif "ACCOUNT_UID" in filtered_data.columns:
        filtered_data = filtered_data[filtered_data["ACCOUNT_UID"].isin(values_choice)]
    elif "ACCOUNT_NAME" in filtered_data.columns:
        filtered_data = filtered_data[filtered_data["ACCOUNT_NAME"].isin(values_choice)]

    # Filter REGION

    # Check if filtered data contains an aws account
    if "REGION" not in filtered_data.columns:
        filtered_data["REGION"] = "-"
    if "LOCATION" in filtered_data.columns:
        filtered_data.rename(columns={"LOCATION": "REGION"}, inplace=True)
    if region_account_values == ["All"]:
        updated_region_account_values = filtered_data["REGION"].unique()
    elif "All" in region_account_values and len(region_account_values) > 1:
        # Remove 'All' from the list
        region_account_values.remove("All")
        updated_region_account_values = region_account_values
    elif len(region_account_values) == 0:
        updated_region_account_values = filtered_data["REGION"].unique()
        region_account_values = ["All"]
    else:
        updated_region_account_values = region_account_values

    filtered_data = filtered_data[
        filtered_data["REGION"].isin(updated_region_account_values)
    ]

    region_filter_options = ["All"] + list(filtered_data["REGION"].unique())
    # clean the region_filter_options from null values
    region_filter_options = [
        x
        for x in region_filter_options
        if str(x) != "nan" and x.__class__.__name__ == "str"
    ]
    # Correct the values
    options = []
    for value in region_filter_options:
        if " " in value:
            options.append(value.split(" ")[1])
        else:
            options.append(value)

    region_filter_options = options

    # Filter Severity
    if severity_values == ["All"]:
        updated_severity_values = filtered_data["SEVERITY"].unique()
    elif "All" in severity_values and len(severity_values) > 1:
        # Remove 'All' from the list
        severity_values.remove("All")
        updated_severity_values = severity_values
    elif len(severity_values) == 0:
        updated_severity_values = filtered_data["SEVERITY"].unique()
        severity_values = ["All"]
    else:
        updated_severity_values = severity_values

    filtered_data = filtered_data[
        filtered_data["SEVERITY"].isin(updated_severity_values)
    ]

    severity_filter_options = ["All"] + list(filtered_data["SEVERITY"].unique())

    service_filter_options = ["All"]

    all_items = filtered_data["SERVICE_NAME"].unique()

    for item in all_items:
        if item not in service_filter_options and item.__class__.__name__ == "str":
            if "aws" in list(
                filtered_data[filtered_data["SERVICE_NAME"] == item]["PROVIDER"]
            ):
                service_filter_options.append(item + " - AWS")
            if "kubernetes" in list(
                filtered_data[filtered_data["SERVICE_NAME"] == item]["PROVIDER"]
            ):
                service_filter_options.append(item + " - K8S")
            if "azure" in list(
                filtered_data[filtered_data["SERVICE_NAME"] == item]["PROVIDER"]
            ):
                service_filter_options.append(item + " - AZURE")
            if "gcp" in list(
                filtered_data[filtered_data["SERVICE_NAME"] == item]["PROVIDER"]
            ):
                service_filter_options.append(item + " - GCP")
            if "m365" in list(
                filtered_data[filtered_data["SERVICE_NAME"] == item]["PROVIDER"]
            ):
                service_filter_options.append(item + " - M365")

    # Filter Service
    if service_values == ["All"]:
        updated_service_values = filtered_data["SERVICE_NAME"].unique()
    elif "All" in service_values and len(service_values) > 1:
        # Remove 'All' from the list
        updated_service_values = []
        service_values.remove("All")
        for item in service_values:
            updated_service_values.append(item.split(" - ")[0])
    elif len(service_values) == 0:
        updated_service_values = filtered_data["SERVICE_NAME"].unique()
        service_values = ["All"]
    else:
        updated_service_values = []
        for item in service_values:
            updated_service_values.append(item.split(" - ")[0])

    filtered_data = filtered_data[
        filtered_data["SERVICE_NAME"].isin(updated_service_values)
    ]

    provider_filter_options = ["All"] + list(filtered_data["PROVIDER"].unique())

    # Filter Provider
    if provider_values == ["All"]:
        updated_provider_values = filtered_data["PROVIDER"].unique()
    elif "All" in provider_values and len(provider_values) > 1:
        # Remove 'All' from the list
        provider_values.remove("All")
        updated_provider_values = provider_values
    elif len(provider_values) == 0:
        updated_provider_values = filtered_data["PROVIDER"].unique()
        provider_values = ["All"]
    else:
        updated_provider_values = provider_values

    filtered_data = filtered_data[
        filtered_data["PROVIDER"].isin(updated_provider_values)
    ]

    # Filter Status
    if status_values == ["All"]:
        updated_status_values = filtered_data["STATUS"].unique()
    elif "All" in status_values and len(status_values) > 1:
        # Remove 'All' from the list
        status_values.remove("All")
        updated_status_values = status_values
    elif len(status_values) == 0:
        updated_status_values = filtered_data["STATUS"].unique()
        status_values = ["All"]
    else:
        updated_status_values = status_values

    filtered_data = filtered_data[filtered_data["STATUS"].isin(updated_status_values)]

    status_filter_options = ["All"] + list(filtered_data["STATUS"].unique())

    if len(filtered_data_sp) == 0:
        fig = px.pie()
        fig.update_layout(
            paper_bgcolor="#FFF",
        )
        line_chart = dcc.Graph(figure=fig, config={"displayModeBar": False})
    else:
        try:
            ########################################################
            """Line  PLOT 1"""
            ########################################################
            # Formatting date columns
            filtered_data_sp["TIMESTAMP_formatted"] = pd.to_datetime(
                filtered_data_sp["TIMESTAMP"]
            ).dt.strftime("%Y-%m-%d")
            filtered_data_sp["TIMESTAMP_formatted"] = pd.to_datetime(
                filtered_data_sp["TIMESTAMP_formatted"]
            )
            # Generate a date range for the last 30 days
            date_range = pd.date_range(start=start_date, end=end_date)

            # Format the dates as '%Y-%m-%d'
            date_range.strftime("%Y-%m-%d").tolist()

            # Dataframe with count of PASS FAIL Statuses
            satus_df = (
                pd.DataFrame(
                    filtered_data_sp.groupby(["TIMESTAMP_formatted"])[
                        "STATUS"
                    ].value_counts()
                )
                .rename(columns={"STATUS": "Status_count"})
                .reset_index()
            )
            satus_df = satus_df.rename(columns={"TIMESTAMP_formatted": "date"})

            # Generate all possible combinations
            statuses = list(filtered_data_sp["STATUS"].unique())
            combinations = list(product(date_range, statuses))

            all_date_combinations = pd.DataFrame(
                combinations, columns=["date", "STATUS"]
            )

            result_df = all_date_combinations.merge(
                satus_df, on=["date", "STATUS"], how="left"
            )

            result_df.rename(columns={"count": "Status_count"}, inplace=True)

            result_df["Status_count"].fillna(0, inplace=True)

            color_mapping = {
                "FAIL": fail_color,
                "PASS": pass_color,
                "INFO": info_color,
                "MANUAL": manual_color,
                "MUTED (FAIL)": muted_fail_color,
                "MUTED (PASS)": muted_pass_color,
                "MUTED (MANUAL)": muted_manual_color,
            }

            # Create a single line plot for both 'FAIL' and 'PASS' statuses
            fig6 = px.line(
                result_df,
                x="date",
                y="Status_count",
                color="STATUS",
                color_discrete_map=color_mapping,
            )
            fig6.update_traces(mode="markers+lines", marker=dict(size=8))
            fig6.update_layout(
                margin=dict(l=0, r=0, t=0, b=0),
                xaxis_title="",
                yaxis_title="",
                template="plotly",
                legend=dict(x=0.02, y=0.98),
                paper_bgcolor="#FFF",
                font=dict(size=12, color="#292524"),
            )

            line_chart = dcc.Graph(
                figure=fig6,
                config={"displayModeBar": False, "scrollZoom": False},
                style={"height": "300px", "overflow-y": "auto"},
                className="max-h-[300px]",
            )
        except Exception:
            fig = px.pie()
            fig.update_layout(
                paper_bgcolor="#FFF",
            )
            line_chart = dcc.Graph(figure=fig, config={"displayModeBar": False})

    # If the data is out of range Make the while dashaboard empty
    if len(filtered_data) == 0:
        fig = px.pie()
        pie_2 = dcc.Graph(
            figure=fig,
            config={"displayModeBar": False},
        )
        table = dcc.Graph(figure=fig, config={"displayModeBar": False})

    else:
        # Status Pie Chart
        df1 = filtered_data[filtered_data["STATUS"] == "FAIL"]

        color_mapping_status = {
            "FAIL": fail_color,
            "PASS": pass_color,
            "LOW": info_color,
            "MANUAL": manual_color,
            "WARNING": muted_fail_color,
            "MUTED (FAIL)": muted_fail_color,
            "MUTED (PASS)": muted_pass_color,
            "MUTED (MANUAL)": "#b33696",
            "MUTED (WARNING)": "#c7a45d",
        }
        # Define custom colors
        color_mapping_severity = {
            "critical": critical_color,
            "high": high_color,
            "medium": medium_color,
            "low": low_color,
            "informational": informational_color,
        }

        # Use the color_discrete_map parameter to map categories to custom colors
        fig2 = px.pie(
            filtered_data,
            names="STATUS",
            hole=0.7,
            color="STATUS",
            color_discrete_map=color_mapping_status,
        )
        fig2.update_traces(
            hovertemplate=None,
            textposition="outside",
            textinfo="percent+label",
            rotation=50,
        )

        fig2.update_layout(
            margin=dict(l=0, r=0, t=50, b=0),
            autosize=True,
            showlegend=False,
            font=dict(size=14, color="#292524"),
            hoverlabel=dict(font_size=12),
            paper_bgcolor="#FFF",
        )

        pie_2 = dcc.Graph(
            figure=fig2,
            config={"displayModeBar": False},
            style={"height": "300px", "overflow-y": "auto"},
        )

        color_bars = [
            color_mapping_severity[severity]
            for severity in df1["SEVERITY"].value_counts().index
        ]

        figure_bars = go.Figure(
            data=[
                go.Bar(
                    x=df1["SEVERITY"]
                    .value_counts()
                    .index,  # assign x as the dataframe column 'x'
                    y=df1["SEVERITY"].value_counts().values,
                    marker=dict(color=color_bars),
                    textposition="auto",
                )
            ],
            layout=go.Layout(
                paper_bgcolor="#FFF",
                font=dict(size=12, color="#292524"),
                margin=dict(l=20, r=20, t=0, b=150),
            ),
        )

        pie_3 = dcc.Graph(
            figure=figure_bars,
            config={"displayModeBar": False},
            style={"height": "400px", "overflow-y": "auto", "margin-top": "0px"},
        )

        # TABLE
        severity_dict = {
            "critical": 4,
            "high": 3,
            "medium": 2,
            "low": 1,
            "informational": 0,
        }

        filtered_data["SEVERITY"] = filtered_data["SEVERITY"].map(severity_dict)
        filtered_data = filtered_data.sort_values(by=["SEVERITY"], ascending=False)
        filtered_data["SEVERITY"] = filtered_data["SEVERITY"].replace(
            {4: "critical", 3: "high", 2: "medium", 1: "low", 0: "informational"}
        )

        table_row_options = []

        # Calculate table row options as percentages
        percentages = [0.05, 0.10, 0.25, 0.50, 0.75, 1.0]
        total_rows = len(filtered_data)
        for pct in percentages:
            value = max(1, int(total_rows * pct))
            label = f"{int(pct * 100)}%"
            table_row_options.append({"label": label, "value": value})

        # Default to 25% if not set
        if table_row_values is None or table_row_values == -1:
            table_row_values = table_row_options[0]["value"]

        # For the values that are nan or none, replace them with ""
        filtered_data = filtered_data.replace({np.nan: ""})
        filtered_data = filtered_data.replace({None: ""})
        filtered_data = filtered_data.replace({"nan": ""})

        severity_mapping = {
            "low": 1,
            "medium": 2,
            "high": 3,
            "critical": 4,
            "informational": 0,
        }

        severity_mapping_reverse = {
            1: "low",
            2: "medium",
            3: "high",
            4: "critical",
            0: "informational",
        }

        status_mapping = {
            "MANUAL": 0,
            "INFO": 1,
            "MUTED (MANUAL)": 2,
            "MUTED (PASS)": 3,
            "PASS": 4,
            "MUTED (FAIL)": 5,
            "FAIL": 6,
        }

        status_mapping_reverse = {
            0: "MANUAL",
            1: "INFO",
            2: "MUTED (MANUAL)",
            3: "MUTED (PASS)",
            4: "PASS",
            5: "MUTED (FAIL)",
            6: "FAIL",
        }

        index_count = 0
        if search_value:
            search_value = search_value.lower()
            filtered_data = filtered_data[
                filtered_data["CHECK_TITLE"].str.lower().str.contains(search_value)
                | filtered_data["SERVICE_NAME"].str.lower().str.contains(search_value)
                | filtered_data["REGION"].str.lower().str.contains(search_value)
                | filtered_data["STATUS"].str.lower().str.contains(search_value)
            ]

        full_filtered_data = filtered_data.copy()
        filtered_data = filtered_data.head(table_row_values)
        # Sort the filtered_data
        if sort_button_check_name > 0:
            if sort_button_check_name % 2 != 0:
                filtered_data = filtered_data.sort_values(
                    by=["CHECK_TITLE"], ascending=True
                )
            else:
                filtered_data = filtered_data.sort_values(
                    by=["CHECK_TITLE"], ascending=False
                )
                sort_button_check_name = 0
            sort_button_severity = 0
            sort_button_status = 0
            sort_button_region = 0
            sort_button_service = 0
            sort_button_account = 0
        if sort_button_severity > 0:
            filtered_data["SEVERITY"] = filtered_data["SEVERITY"].map(severity_mapping)
            if sort_button_severity % 2 != 0:
                filtered_data = filtered_data.sort_values(
                    by=["SEVERITY"], ascending=True
                )
            else:
                filtered_data = filtered_data.sort_values(
                    by=["SEVERITY"], ascending=False
                )
                sort_button_severity = 0
            filtered_data["SEVERITY"] = filtered_data["SEVERITY"].map(
                severity_mapping_reverse
            )
            sort_button_check_name = 0
            sort_button_status = 0
            sort_button_region = 0
            sort_button_service = 0
            sort_button_account = 0
        if sort_button_status > 0:
            filtered_data["STATUS"] = filtered_data["STATUS"].map(status_mapping)
            if sort_button_status % 2 != 0:
                filtered_data = filtered_data.sort_values(by=["STATUS"], ascending=True)
            else:
                filtered_data = filtered_data.sort_values(
                    by=["STATUS"], ascending=False
                )
                sort_button_status = 0
            filtered_data["STATUS"] = filtered_data["STATUS"].map(
                status_mapping_reverse
            )
            sort_button_check_name = 0
            sort_button_severity = 0
            sort_button_region = 0
            sort_button_service = 0
            sort_button_account = 0
        if sort_button_region > 0:
            if sort_button_region % 2 != 0:
                filtered_data = filtered_data.sort_values(by=["REGION"], ascending=True)
            else:
                filtered_data = filtered_data.sort_values(
                    by=["REGION"], ascending=False
                )
                sort_button_region = 0
            sort_button_check_name = 0
            sort_button_severity = 0
            sort_button_status = 0
            sort_button_service = 0
            sort_button_account = 0
        if sort_button_service > 0:
            if sort_button_service % 2 != 0:
                filtered_data = filtered_data.sort_values(
                    by=["SERVICE_NAME"], ascending=True
                )
            else:
                filtered_data = filtered_data.sort_values(
                    by=["SERVICE_NAME"], ascending=False
                )
                sort_button_service = 0
            sort_button_check_name = 0
            sort_button_severity = 0
            sort_button_status = 0
            sort_button_region = 0
            sort_button_account = 0
        if sort_button_account > 0:
            if sort_button_account % 2 != 0:
                filtered_data = filtered_data.sort_values(
                    by=["ACCOUNT_UID"], ascending=True
                )
            else:
                filtered_data = filtered_data.sort_values(
                    by=["ACCOUNT_UID"], ascending=False
                )
                sort_button_account = 0
            sort_button_check_name = 0
            sort_button_severity = 0
            sort_button_status = 0
            sort_button_region = 0
            sort_button_service = 0

        # Remove column "assessment_time", this is done to undo the changes made in the data
        if "TIMESTAMP_AUX" in filtered_data.columns:
            filtered_data.drop(columns=["TIMESTAMP_AUX"], inplace=True)

        # For the account_id, we are going to add the provider name
        if "ACCOUNT_UID" in filtered_data.columns:
            for account in filtered_data["ACCOUNT_UID"].unique():
                if "aws" in list(data[data["ACCOUNT_UID"] == account]["PROVIDER"]):
                    filtered_data.loc[
                        filtered_data["ACCOUNT_UID"] == account, "ACCOUNT_UID"
                    ] = (account + " - AWS")
                if "kubernetes" in list(
                    data[data["ACCOUNT_UID"] == account]["PROVIDER"]
                ):
                    filtered_data.loc[
                        filtered_data["ACCOUNT_UID"] == account, "ACCOUNT_UID"
                    ] = (account + " - K8S")
                if "azure" in list(data[data["ACCOUNT_UID"] == account]["PROVIDER"]):
                    filtered_data.loc[
                        filtered_data["ACCOUNT_UID"] == account, "ACCOUNT_UID"
                    ] = (account + " - AZURE")
                if "gcp" in list(data[data["ACCOUNT_UID"] == account]["PROVIDER"]):
                    filtered_data.loc[
                        filtered_data["ACCOUNT_UID"] == account, "ACCOUNT_UID"
                    ] = (account + " - GCP")
                if "m365" in list(data[data["ACCOUNT_UID"] == account]["PROVIDER"]):
                    filtered_data.loc[
                        filtered_data["ACCOUNT_UID"] == account, "ACCOUNT_UID"
                    ] = (account + " - M365")

        table_collapsible = []
        for item in filtered_data.to_dict("records"):
            table_collapsible.append(
                generate_table(
                    item, index_count, color_mapping_severity, color_mapping_status
                )
            )
            index_count += 1

        table = html.Div(table_collapsible, id="table", className="overview-table")

    # Status Graphic
    status_graph = [
        html.Span(
            "Status",
            className="text-center text-prowler-stone-900 uppercase text-xs font-bold",
        ),
        html.Div(
            [
                pie_2,
            ],
            className="w-full",
        ),
    ]

    # Layout two pie charts
    two_pie_chart = [
        html.Span(
            "Severity",
            className="text-center text-prowler-stone-900 uppercase text-xs font-bold",
        ),
        html.Div(
            [
                pie_3,
            ],
            className="",
        ),
    ]

    # Layout Line PLOT
    line_plot = [
        html.Span(
            "Security Posture Evolution (last 7 days)",
            className="text-center text-prowler-stone-900 uppercase text-xs font-bold",
        ),
        html.Div([line_chart], className=""),
    ]

    # Table
    table_card = [
        html.Div([table], className="grid grid-cols-auto w-full"),
    ]

    # Create Provider Cards
    if "aws" in list(data["PROVIDER"].unique()):
        aws_card = create_provider_card(
            "aws", aws_provider_logo, "Accounts", full_filtered_data
        )
    else:
        aws_card = None
    if "azure" in list(data["PROVIDER"].unique()):
        azure_card = create_provider_card(
            "azure", azure_provider_logo, "Subscriptions", full_filtered_data
        )
    else:
        azure_card = None
    if "gcp" in list(data["PROVIDER"].unique()):
        gcp_card = create_provider_card(
            "gcp", gcp_provider_logo, "Projects", full_filtered_data
        )
    else:
        gcp_card = None
    if "kubernetes" in list(data["PROVIDER"].unique()):
        k8s_card = create_provider_card(
            "kubernetes", ks8_provider_logo, "Clusters", full_filtered_data
        )
    else:
        k8s_card = None
    if "m365" in list(data["PROVIDER"].unique()):
        m365_card = create_provider_card(
            "m365", m365_provider_logo, "Accounts", full_filtered_data
        )
    else:
        m365_card = None

    # Subscribe to Prowler Cloud card
    subscribe_card = [
        html.Div(
            html.A(
                [
                    html.Img(src="assets/favicon.ico", className="w-5 mr-3"),
                    html.Span("Subscribe to Prowler Cloud"),
                ],
                href="https://prowler.pro/",
                target="_blank",
                className="text-prowler-stone-900 inline-flex px-4 py-2 text-xs font-bold uppercase transition-all rounded-lg text-gray-900 hover:bg-prowler-stone-900/10 border-solid border-1 hover:border-prowler-stone-900/10 hover:border-solid hover:border-1 border-prowler-stone-900/10",
            ),
        )
    ]
    if (
        ctx.triggered_id == "download_link_csv"
        or ctx.triggered_id == "download_link_xlsx"
    ):
        if ctx.triggered_id == "download_link_csv":
            csv_data = dcc.send_data_frame(
                filtered_data.to_csv, "prowler-dashboard-export.csv", index=False
            )
        if ctx.triggered_id == "download_link_xlsx":
            csv_data = dcc.send_data_frame(
                filtered_data.to_excel,
                "prowler-dashboard-export.xlsx",
                index=False,
            )
        return (
            status_graph,
            two_pie_chart,
            line_plot,
            table_card,
            csv_data,
            cloud_account_values,
            cloud_accounts_options,
            region_account_values,
            region_filter_options,
            assessment_value,
            aws_card,
            azure_card,
            gcp_card,
            k8s_card,
            m365_card,
            subscribe_card,
            list_files,
            severity_values,
            severity_filter_options,
            service_values,
            service_filter_options,
            table_row_values,
            table_row_options,
            status_values,
            status_filter_options,
            aws_clicks,
            azure_clicks,
            gcp_clicks,
            k8s_clicks,
            m365_clicks,
        )
    else:
        return (
            status_graph,
            two_pie_chart,
            line_plot,
            table_card,
            None,
            cloud_account_values,
            cloud_accounts_options,
            region_account_values,
            region_filter_options,
            assessment_value,
            aws_card,
            azure_card,
            gcp_card,
            k8s_card,
            m365_card,
            subscribe_card,
            list_files,
            severity_values,
            severity_filter_options,
            service_values,
            provider_values,
            provider_filter_options,
            service_filter_options,
            table_row_values,
            table_row_options,
            status_values,
            status_filter_options,
            aws_clicks,
            azure_clicks,
            gcp_clicks,
            k8s_clicks,
            m365_clicks,
        )


@callback(
    Output({"type": "collapse", "index": dash.dependencies.ALL}, "is_open"),
    [Input({"type": "toggle-collapse", "index": dash.dependencies.ALL}, "n_clicks")],
    [
        dash.dependencies.State(
            {"type": "collapse", "index": dash.dependencies.ALL}, "is_open"
        )
    ],
)
def toggle_collapse(n_clicks, is_open):
    n_clicks = n_clicks or 0
    triggered = callback_context.triggered[0]["prop_id"].split(".")[0]
    if triggered:
        idx = json.loads(triggered)["index"]
        is_open[idx] = not is_open[idx]
    return is_open


def generate_table(data, index, color_mapping_severity, color_mapping_status):
    return html.Div(
        [
            dbc.Card(
                [
                    dbc.CardHeader(
                        dbc.Row(
                            [
                                dbc.Col(
                                    [
                                        html.Button(
                                            html.Img(
                                                src="assets/images/icons/dropdown.svg",
                                                className="w-3",
                                            ),
                                            id={
                                                "type": "toggle-collapse",
                                                "index": index,
                                            },
                                            className="btn",
                                            style={
                                                "position": "relative",
                                                "top": "3px",
                                                "padding": "0",
                                            },
                                        ),
                                    ],
                                    width=1,
                                    className="w-[4%] 2xl:w-[2%]",
                                ),
                                dbc.Col(
                                    [
                                        html.H5(
                                            data["CHECK_TITLE"],
                                            className="card-title mb-0",
                                        ),
                                    ],
                                    width=4,
                                    className="pr-2 w-[36%] 2xl:w-[48%]",
                                ),
                                dbc.Col(
                                    [
                                        html.Span(
                                            data["SEVERITY"],
                                            className="text-white uppercase text-xs font-bold rounded-lg px-2 py-1",
                                            style={
                                                "background-color": color_mapping_severity[
                                                    data["SEVERITY"]
                                                ],
                                            },
                                        ),
                                    ],
                                    className="w-[11%]",
                                    width=1,
                                ),
                                dbc.Col(
                                    [
                                        html.Span(
                                            data["STATUS"],
                                            className="text-white uppercase text-xs font-bold rounded-lg px-2 py-1",
                                            style={
                                                "background-color": color_mapping_status[
                                                    data["STATUS"]
                                                ],
                                            },
                                        ),
                                    ],
                                    className="w-[9.5%] 2xl:w-[9%]",
                                    width=1,
                                ),
                                dbc.Col(
                                    [
                                        html.Span(
                                            data["REGION"],
                                            className="uppercase text-xs font-bold",
                                            style={
                                                "display": "flex",
                                                "align-items": "center",
                                            },
                                        ),
                                    ],
                                    className="w-[10.5%] 2xl:w-[10%]",
                                    width=1,
                                ),
                                dbc.Col(
                                    [
                                        html.Span(
                                            data["SERVICE_NAME"],
                                            className="uppercase text-xs font-bold",
                                            style={
                                                "display": "flex",
                                                "align-items": "center",
                                            },
                                        ),
                                    ],
                                    className="w-[14.5%] 2xl:w-[10%]",
                                    width=1,
                                ),
                                dbc.Col(
                                    [
                                        html.Span(
                                            data["ACCOUNT_UID"],
                                            className="uppercase text-xs font-bold",
                                            style={
                                                "display": "flex",
                                                "align-items": "center",
                                            },
                                        ),
                                    ],
                                    className="w-[14.5%] 2xl:w-[10%]",
                                    width=2,
                                ),
                            ],
                            align="center",
                            className="g-0",
                        ),
                    ),
                    dbc.Collapse(
                        dbc.CardBody(
                            [
                                html.H5(
                                    "Details",
                                    className="card-title",
                                    style={"font-weight": "bold"},
                                ),
                                html.Div(
                                    [
                                        html.Div(
                                            [
                                                html.Div(
                                                    [
                                                        html.P(
                                                            html.Strong(
                                                                "ResourceUid: ",
                                                                style={
                                                                    "margin-right": "5px"
                                                                },
                                                            )
                                                        ),
                                                        html.P(
                                                            str(
                                                                data.get(
                                                                    "RESOURCE_UID", ""
                                                                )
                                                            )
                                                        ),
                                                    ],
                                                    style={"display": "flex"},
                                                ),
                                                html.Div(
                                                    [
                                                        html.P(
                                                            html.Strong(
                                                                "FindingUid: ",
                                                                style={
                                                                    "margin-right": "5px"
                                                                },
                                                            )
                                                        ),
                                                        html.P(
                                                            str(
                                                                data.get(
                                                                    "FINDING_UID", ""
                                                                )
                                                            ),
                                                            style={
                                                                "margin-left": "5px"
                                                            },
                                                        ),
                                                    ],
                                                    style={"display": "flex"},
                                                ),
                                                html.Div(
                                                    [
                                                        html.P(
                                                            html.Strong(
                                                                "CheckId: ",
                                                                style={
                                                                    "margin-right": "5px"
                                                                },
                                                            )
                                                        ),
                                                        html.P(
                                                            str(
                                                                data.get("CHECK_ID", "")
                                                            )
                                                        ),
                                                    ],
                                                    style={"display": "flex"},
                                                ),
                                                html.Div(
                                                    [
                                                        html.P(
                                                            html.Strong(
                                                                "Type: ",
                                                                style={
                                                                    "margin-right": "5px"
                                                                },
                                                            )
                                                        ),
                                                        html.P(
                                                            str(
                                                                data.get(
                                                                    "RESOURCE_TYPE", ""
                                                                )
                                                            )
                                                        ),
                                                    ],
                                                    style={"display": "flex"},
                                                ),
                                                html.Div(
                                                    [
                                                        html.P(
                                                            html.Strong(
                                                                "Details: ",
                                                                style={
                                                                    "margin-right": "5px"
                                                                },
                                                            )
                                                        ),
                                                        html.P(
                                                            str(
                                                                data.get(
                                                                    "RESOURCE_DETAILS",
                                                                    "",
                                                                )
                                                            )
                                                        ),
                                                    ],
                                                    style={"display": "flex"},
                                                ),
                                                html.Div(
                                                    [
                                                        html.P(
                                                            html.Strong(
                                                                "StatusExtended: ",
                                                                style={
                                                                    "margin-right": "5px"
                                                                },
                                                            )
                                                        ),
                                                        html.P(
                                                            str(
                                                                data.get(
                                                                    "STATUS_EXTENDED",
                                                                    "",
                                                                )
                                                            ),
                                                            style={
                                                                "margin-left": "5px"
                                                            },
                                                        ),
                                                    ],
                                                    style={"display": "flex"},
                                                ),
                                            ],
                                            style={
                                                "width": "50%",
                                                "display": "inline-block",
                                            },
                                        ),
                                        html.Div(
                                            [
                                                html.Div(
                                                    [
                                                        html.P(
                                                            html.Strong(
                                                                "Risk: ",
                                                                style={
                                                                    "margin-right": "5px"
                                                                },
                                                            )
                                                        ),
                                                        html.P(
                                                            str(data.get("RISK", "")),
                                                            style={
                                                                "margin-left": "5px"
                                                            },
                                                        ),
                                                    ],
                                                    style={"display": "flex"},
                                                ),
                                                html.Div(
                                                    [
                                                        html.P(
                                                            html.Strong(
                                                                "Notes: ",
                                                                style={
                                                                    "margin-right": "5px"
                                                                },
                                                            )
                                                        ),
                                                        html.P(
                                                            str(data.get("NOTES", ""))
                                                        ),
                                                    ],
                                                    style={"display": "flex"},
                                                ),
                                                html.Div(
                                                    [
                                                        html.P(
                                                            html.Strong(
                                                                "Provider: ",
                                                                style={
                                                                    "margin-right": "5px"
                                                                },
                                                            )
                                                        ),
                                                        html.P(
                                                            str(
                                                                data.get("PROVIDER", "")
                                                            )
                                                        ),
                                                    ],
                                                    style={"display": "flex"},
                                                ),
                                                html.Div(
                                                    [
                                                        html.P(
                                                            html.Strong(
                                                                "Recommendation: ",
                                                                style={
                                                                    "margin-right": "5px"
                                                                },
                                                            )
                                                        ),
                                                        html.P(
                                                            str(
                                                                data.get(
                                                                    "REMEDIATION_RECOMMENDATION_TEXT",
                                                                    "",
                                                                )
                                                            ),
                                                            style={
                                                                "margin-left": "5px"
                                                            },
                                                        ),
                                                    ],
                                                    style={"display": "flex"},
                                                ),
                                                html.Div(
                                                    [
                                                        html.P(
                                                            html.Strong(
                                                                "RecommendationUrl: ",
                                                                style={
                                                                    "margin-right": "5px"
                                                                },
                                                            )
                                                        ),
                                                        html.A(
                                                            str(
                                                                data.get(
                                                                    "REMEDIATION_RECOMMENDATION_URL",
                                                                    "",
                                                                )
                                                            ),
                                                            href=str(
                                                                data.get(
                                                                    "REMEDIATION_RECOMMENDATION_URL",
                                                                    "",
                                                                )
                                                            ),
                                                            style={
                                                                "color": "#3182ce",
                                                                "margin-left": "5px",
                                                            },
                                                        ),
                                                    ],
                                                    style={"display": "flex"},
                                                ),
                                                html.Div(
                                                    [
                                                        html.P(
                                                            html.Strong(
                                                                "Scan Day: ",
                                                                style={
                                                                    "margin-right": "5px"
                                                                },
                                                            )
                                                        ),
                                                        html.P(
                                                            str(
                                                                data.get(
                                                                    "ASSESSMENT_TIME",
                                                                    "",
                                                                )
                                                            )
                                                        ),
                                                    ],
                                                    style={"display": "flex"},
                                                ),
                                            ],
                                            style={
                                                "width": "50%",
                                                "display": "inline-block",
                                            },
                                        ),
                                    ],
                                    style={"display": "flex", "width": "100%"},
                                ),
                            ]
                        ),
                        id={"type": "collapse", "index": index},
                        is_open=False,
                    ),
                ]
            )
        ]
    )
