import json
from datetime import datetime


def format_timestamp(timestamp):
    return datetime.fromtimestamp(int(timestamp) / 1000).strftime('%Y-%m-%d %H:%M:%S')


# build proto
# protoc --python_out=./proto --proto_path souvla/api/src/main/proto/command_proto.proto'
# this doesn't work unless your CD is souvla
# if the message exists in on multiple devices in seperate mesh networks
#     if at least one of the devices is online in each mesh network, then the message its considered successful Front Haul
def get_front_haul_count(success_data, device_state):
    front_hauled_messages = []

    for identifier, success_android_ids in success_data.items():
        offline_devices_per_frequency = {}

        for android_id in success_android_ids:
            state = device_state.get(android_id, {})
            settings = state.get('settings', {})
            frequency = settings.get('highSpeedFrequencyHz')

            if frequency is not None:
                offline_devices_per_frequency.setdefault(frequency, set())
                if not state.get('hasConnectivity', False):
                    offline_devices_per_frequency[frequency].add(android_id)

        offline_count = sum(1 for devices in offline_devices_per_frequency.values() if len(devices) >= 1)

        if offline_count > 0:
            front_hauled_messages.append(success_data['messages'][identifier])

    return front_hauled_messages


def generate_report(success_data, failure_data, device_state, cell_backhaul_success, sat_backhaul_success):
    front_hauled_messages = get_front_haul_count(success_data, device_state)

    messages = success_data.get("messages", {})
    success_data.pop("messages")
    unique_messages = set(success_data.keys()).union(set(failure_data.keys()))

    total_success_count = sum(len(identifiers) for identifiers in success_data.values())
    total_failure_count = sum(len(identifiers) for identifiers in failure_data.values())
    total_transmissions = total_success_count + total_failure_count
    message_count = len(unique_messages)

    success_rate = (total_success_count / (total_success_count + total_failure_count)) * 100 if (
                                                                                                        total_success_count + total_failure_count) > 0 else 0
    failure_rate = (total_failure_count / (total_success_count + total_failure_count)) * 100 if (
                                                                                                        total_success_count + total_failure_count) > 0 else 0

    report = []
    report.append("Success Report:")
    report.append("------------------------------")
    for timestamp, identifiers in success_data.items():
        for identifier in identifiers:
            message_id = f"messageId: {timestamp}"  # Timestamp as messageId
            report.append(f"{message_id} - Android Serial: {identifier}")
        report.append("------------------------------")

    report.append("\nFailure Report:")
    report.append("\n\t- these messages are missing on specified android device")
    report.append("------------------------------")
    for timestamp, identifiers in failure_data.items():
        for identifier in identifiers:
            message_id = f"messageId: {timestamp}"  # Timestamp as messageId
            report.append(f"{message_id} - Android Serial: {identifier}")

    transmission_definition = """
    One Transmission is defined as a single message sent from one Android device to another.

    For example, if a workspace message is sent and is destined to 3 other Android devices 2 of which could be in 
    another mesh, this results in four transmission counts (the message in the sender's database is also counted as a 
    transmission) If any one of these transmissions fails, it is counted as a failure and contributes to the overall 
    failure rate."""

    report.append("\nOverall Statistics:")
    report.append("------------------------------")
    report.append(f"Total Transmissions: {total_transmissions}")
    report.append(f"")
    report.append(f"Total Success Transmissions: {total_success_count}")
    report.append(f"Success Rate: {success_rate:.2f}%")
    report.append(f"Total Failure Count: {total_failure_count}")
    report.append(f"Failure Rate: {failure_rate:.2f}%")
    report.append(f"Total Messages: {message_count}")
    report.append(f"Successful Front Haul Count: {len(front_hauled_messages)}")
    report.append(f"Cellular Backhaul Success Count: {len(cell_backhaul_success)}")
    report.append(f"Satellite Backhaul Success Count: {len(sat_backhaul_success)}")

    report.append(f"Definitions: {transmission_definition}")

    report.append("------------------------------")
    # print report
    print("\n".join(report))

    # report.append("Front Hauled Messages:")
    # for message in front_hauled_messages:
    #     report.append(f"text: {message['text']}, dateSent: {message['dateSent']} key: {message['key']}")
    # report.append("------------------------------")

    # create json object with all of this data
    report_json = {
        "devices": device_state,
        "success_count": total_success_count,
        "failure_count": total_failure_count,
        "success_rate": success_rate,
        "failure_rate": failure_rate,
        "total_messages": message_count,
        "front_hauled_messages": front_hauled_messages,
        "cell_backhaul_success": cell_backhaul_success,
        "sat_backhaul_success": sat_backhaul_success,
        "total_transmissions": total_transmissions,
        "failed_messages": failure_data,
        "successful_messages": success_data,
    }

    return report_json
