import base64
import io
from fastapi import FastAPI, Response
from utils.utils import handle_response
from utils.generic_base64_image import GenericImageGenerator
from services.ec2_metrics import EC2Metrics
from services.load_balancer_metrics import LoadBalancerMetrics
from services.vpn_metrics import VPNMetrics
from services.ebs_metrics import EBSMetrics
from services.waf_metrics import WAFMetrics
from services.waf_metric import WafMetricsR
from models.metricsrquest import MetricsRequest
from models.requests.ec2request import EC2Request
from models.requests.wafrequest import WAFRequest
from models.requests.loadbalancerrequest import LoadBalancerRequest
from models.requests.vpnrequest import VPNRequest
from models.requests.ebsrequest import EBSRequest
from models.requests.credentialRequest import CredentiaRequest
from metrics.waf import waf
from models.requests.wafrequestImage import WafRequestImage
import matplotlib.pyplot as plt
import boto3
from datetime import datetime, timedelta

app = FastAPI()

@app.post("/metrics")
async def get_metrics(request: MetricsRequest):
    # Extraer los valores del modelo Pydantic
    access_key = request.access_key
    secret_key = request.secret_key
    region = request.region
    start_time = request.start_time
    end_time = request.end_time
    services = request.services
    
    metrics_results = {}

    # EC2 Metrics
    if services.EC2:
        instance_id = services.EC2.instance_id
        ec2_metrics = EC2Metrics(access_key, secret_key, region, instance_id)
        metrics_results['cpu_utilization'] = ec2_metrics.get_cpu_utilization(start_time, end_time)

    # Load Balancer Metrics
    if services.LoadBalancer:
        load_balancer_arn = services.LoadBalancer.load_balancer_arn
        lb_metrics = LoadBalancerMetrics(access_key, secret_key, region, load_balancer_arn)
        metrics_results['request_count'] = lb_metrics.get_request_count(start_time, end_time)
        metrics_results['active_connection_count'] = lb_metrics.get_active_connection_count(start_time, end_time)

    # VPN Metrics
    if services.VPN:
        vpn_id = services.VPN.vpn_id
        vpn_metrics = VPNMetrics(access_key, secret_key, region, vpn_id)
        metrics_results['tunnel_data_in'] = vpn_metrics.get_tunnel_data_in(start_time, end_time)
        metrics_results['tunnel_data_out'] = vpn_metrics.get_tunnel_data_out(start_time, end_time)

    # EBS Metrics
    if services.EBS:
        volume_id = services.EBS.volume_id
        ebs_metrics = EBSMetrics(access_key, secret_key, region, volume_id)
        metrics_results['volume_read_bytes'] = ebs_metrics.get_volume_read_bytes(start_time, end_time)
        metrics_results['volume_read_ops'] = ebs_metrics.get_volume_read_ops(start_time, end_time)

    # WAF Metrics
    if services.WAF:
        web_acl_id = services.WAF.web_acl_id
        waf_metrics = WAFMetrics(access_key, secret_key, region, web_acl_id)
        metrics_results['waf_allowed_requests'] = waf_metrics.get_allowed_requests(start_time, end_time)
        metrics_results['waf_blocked_requests'] = waf_metrics.get_blocked_requests(start_time, end_time)
    
    return {"metrics_results": metrics_results}

@app.post("/metrics/ec2")
async def get_ec2_metrics(request: EC2Request, response: Response):
    # Verificar si la instancia EC2 es válida o está vacía
    error_response = handle_response(response, data=request.instance_id, data_name="EC2 instance ID")
    if error_response.get("message"):
        return error_response
    try:
        # Simulación de un error de autenticación
        if request.access_key == "invalid":
            error_response = handle_response(response, auth_check=True)
            if error_response.get("message"):
                return error_response
        # Simulación de un error de conexión
        if request.region == "unknown-region":
            error_response = handle_response(response, connection_check=True, data_name="EC2")
            if error_response.get("message"):
                return error_response
        ec2_metrics = EC2Metrics(
            request.access_key,
            request.secret_key,
            request.region,
            request.instance_id
        )
        metrics_results = ec2_metrics.get_cpu_utilization(request.start_time, request.end_time)
        # Procesar el resultado y verificar si está vacío
        return handle_response(response, data=metrics_results, data_name="EC2 metrics")

    except ValueError as e:
        error_response = handle_response(response, validation_check=str(e))
        return error_response

    except Exception as e:
        return handle_response(response)
    
@app.post("/metrics/waf-allowed")
async def get_waf_data(request: WAFRequest, response: Response):
    try:
        waf_service = WafMetricsR(
            access_key=request.access_key,
            secret_key=request.secret_key,
            region=request.region,
            web_acl_id=request.web_acl_id
        )

        result = waf_service.get_Waf_Allowe_data(
            metric='AllowedRequests',  
            start_time=request.start_time,
            end_time=request.end_time,
            country_code=request.country_code,
            time=request.time,
            stat=request.stat
        )
        return result

    except Exception as e:
        return handle_response(response, validation_check=str(e))
    
@app.post("/metrics/waf-blocked")
async def get_waf_blocked_data(request: WAFRequest, response: Response):
    try:
        waf_service = WafMetricsR(
            access_key=request.access_key,
            secret_key=request.secret_key,
            region=request.region,
            web_acl_id=request.web_acl_id
        )

        result = waf_service.get_Waf_blocked_data(
            metric='deniedRequests',  
            start_time=request.start_time,
            end_time=request.end_time,
            country_code=request.country_code,
            time=request.time,
            stat=request.stat
        )
        return result

    except Exception as e:
        return handle_response(response, validation_check=str(e))
    
@app.post("/metrics/wafImage")
async def get_cloudwatch_metrics(request: WafRequestImage, response: Response):
    try:
        session = boto3.Session(
            aws_access_key_id=request.access_key,
            aws_secret_access_key=request.secret_key,
            region_name=request.region
        )
        now = datetime.now()
        first_day_last_month = (now.replace(day=1) - timedelta(days=1)).replace(day=1)
        last_day_last_month = now.replace(day=1) - timedelta(days=1)
        start_time = first_day_last_month.strftime('%Y-%m-%dT%H:%M:%S')
        end_time = last_day_last_month.strftime('%Y-%m-%dT%H:%M:%S')
        cloudwatch_client = session.client('cloudwatch')
        metric_response = cloudwatch_client.get_metric_data(
            MetricDataQueries=[
                {
                    'Id': 'allowedRequests',
                    'MetricStat': {
                        'Metric': {
                            'Namespace': 'AWS/WAFV2',
                            'MetricName': 'AllowedRequests',
                            'Dimensions': [
                                {'Name': 'WebACL', 'Value': 'ACL-AWS-defecto'},
                                {'Name': 'Region', 'Value': session.region_name},
                                {'Name': 'Country', 'Value': request.country_code}
                            ]
                        },
                        'Period': 86400,  # Datos diarios
                        'Stat': 'Sum'
                    },
                    'ReturnData': True
                }
            ],
            StartTime=start_time,
            EndTime=end_time
        )
        timestamps = metric_response['MetricDataResults'][0]['Timestamps']
        values = metric_response['MetricDataResults'][0]['Values']
        if not timestamps or not values:
            return {"status": "error", "message": "No data found"}
        buffer = io.BytesIO()
        plt.figure(figsize=(10, 5))
        # Graficar los datos con el título y la leyenda
        plt.plot(timestamps, values, label=f'Solicitudes Permitidas ({request.country_code})', color='green', marker='o')
        plt.xlabel('Fecha', fontsize=12)
        plt.ylabel('Cantidad de Solicitudes Permitidas', fontsize=12)
        plt.title(f'Solicitudes Permitidas en {request.country_code}', fontsize=14)
        plt.xticks(rotation=45)
        plt.legend()  # Mostrar la leyenda
        plt.tight_layout()  # Para ajustar el contenido y que el texto no se corte
        plt.savefig(buffer, format='png')
        buffer.seek(0)
        image_base64 = base64.b64encode(buffer.read()).decode('utf-8')
        plt.close()
        return {"status": "success","message": "Waf metrics by last month","image_base64": image_base64}

    except Exception as e:
        response.status_code = 400  # Código de estado de error
        return {"status": "error", "message": str(e)}
    
@app.post("/metrics/load_balancer/request_count")
async def get_load_balance_request_count(request: LoadBalancerRequest, response: Response):
    try:
        load_balance_service = LoadBalancerMetrics(
            access_key=request.access_key,
            secret_key=request.secret_key,
            region=request.region,
            load_balancer_arn=request.load_balancer_arn
        )

        result = load_balance_service.get_metric_data(
            metric='RequestCount',  
            start_time=request.start_time,
            end_time=request.end_time,
            time=request.time,
            stat=request.stat
        )
        return result

    except Exception as e:
        return handle_response(response, validation_check=str(e))

@app.post("/metrics/load_balancer/target_response_time")
async def get_load_balance_target_response(request: LoadBalancerRequest, response: Response):
    try:
        load_balance_service = LoadBalancerMetrics(
            access_key=request.access_key,
            secret_key=request.secret_key,
            region=request.region,
            load_balancer_arn=request.load_balancer_arn
        )

        result = load_balance_service.get_metric_data(
            metric='TargetResponseTime',  
            start_time=request.start_time,
            end_time=request.end_time,
            time=request.time,
            stat=request.stat
        )
        return result

    except Exception as e:
        return handle_response(response, validation_check=str(e))

@app.post("/metrics/load_balancer/http_2xx_count")
async def get_load_balance_http2(request: LoadBalancerRequest, response: Response):
    try:
        load_balance_service = LoadBalancerMetrics(
            access_key=request.access_key,
            secret_key=request.secret_key,
            region=request.region,
            load_balancer_arn=request.load_balancer_arn
        )

        result = load_balance_service.get_metric_data(
            metric='HTTPCode_Target_2XX_Count',  
            start_time=request.start_time,
            end_time=request.end_time,
            time=request.time,
            stat=request.stat
        )
        return result

    except Exception as e:
        return handle_response(response, validation_check=str(e))

@app.post("/metrics/load_balancer/http_3xx_count")
async def get_load_balance_http3(request: LoadBalancerRequest, response: Response):
    try:
        load_balance_service = LoadBalancerMetrics(
            access_key=request.access_key,
            secret_key=request.secret_key,
            region=request.region,
            load_balancer_arn=request.load_balancer_arn
        )

        result = load_balance_service.get_metric_data(
            metric='HTTPCode_Target_3XX_Count',  
            start_time=request.start_time,
            end_time=request.end_time,
            time=request.time,
            stat=request.stat
        )
        return result

    except Exception as e:
        return handle_response(response, validation_check=str(e))

@app.post("/metrics/load_balancer/http_4xx_count")
async def get_load_balance_http4(request: LoadBalancerRequest, response: Response):
    try:
        load_balance_service = LoadBalancerMetrics(
            access_key=request.access_key,
            secret_key=request.secret_key,
            region=request.region,
            load_balancer_arn=request.load_balancer_arn
        )

        result = load_balance_service.get_metric_data(
            metric='HTTPCode_Target_4XX_Count',  
            start_time=request.start_time,
            end_time=request.end_time,
            time=request.time,
            stat=request.stat
        )
        return result

    except Exception as e:
        return handle_response(response, validation_check=str(e))

@app.post("/metrics/load_balancer/active_connection_count")
async def get_load_balance_active_connection(request: LoadBalancerRequest, response: Response):
    try:
        load_balance_service = LoadBalancerMetrics(
            access_key=request.access_key,
            secret_key=request.secret_key,
            region=request.region,
            load_balancer_arn=request.load_balancer_arn
        )

        result = load_balance_service.get_metric_data(
            metric='ActiveConnectionCount',  
            start_time=request.start_time,
            end_time=request.end_time,
            time=request.time,
            stat=request.stat
        )
        return result

    except Exception as e:
        return handle_response(response, validation_check=str(e))

@app.post("/metrics/vpn/tunnel_data_in")
async def get_vpn_metrics_tunnel_data_in(request: VPNRequest, response: Response):
    try:
        vpn_service = VPNMetrics(
            access_key=request.access_key,
            secret_key=request.secret_key,
            region=request.region,
            vpn_id=request.vpn_id
        )

        result = vpn_service.get_tunnel_data(
            metric='TunnelDataIn',  
            start_time=request.start_time,
            end_time=request.end_time,
            time=request.time,
            stat=request.stat
        )
        return result

    except Exception as e:
        return handle_response(response, validation_check=str(e))

@app.post("/metrics/vpn/tunnel_data_out")
async def get_vpn_metrics_tunnel_data_out(request: VPNRequest, response: Response):
    try:
        vpn_service = VPNMetrics(
            access_key=request.access_key,
            secret_key=request.secret_key,
            region=request.region,
            vpn_id=request.vpn_id
        )

        result = vpn_service.get_tunnel_data(
            metric='TunnelDataOut',  
            start_time=request.start_time,
            end_time=request.end_time,
            time=request.time,
            stat=request.stat
        )
        return result

    except Exception as e:
        return handle_response(response, validation_check=str(e))

@app.post("/metrics/vpn/tunnel_state")
async def get_vpn_metrics_tunnel_state(request: VPNRequest, response: Response):
    try:
        vpn_service = VPNMetrics(
            access_key=request.access_key,
            secret_key=request.secret_key,
            region=request.region,
            vpn_id=request.vpn_id
        )

        result = vpn_service.get_tunnel_data(
            metric='TunnelState',  
            start_time=request.start_time,
            end_time=request.end_time,
            time=request.time,
            stat=request.stat
        )
        return result

    except Exception as e:
        return handle_response(response, validation_check=str(e))

@app.post("/metrics/ebs/volume_read_ops")
async def get_ebs_metrics_volumne_read_ops(request: EBSRequest, response: Response):
    try:
        ebs_service = EBSMetrics(
            access_key=request.access_key,
            secret_key=request.secret_key,
            region=request.region,
            volume_id=request.volume_id
        )

        result = ebs_service.get_ebs_metric_data(
            metric='VolumeReadOps',  
            start_time=request.start_time,
            end_time=request.end_time,
                        time=request.time,
            stat=request.stat
        )
        return result

    except Exception as e:
        return handle_response(response, validation_check=str(e))

@app.post("/metrics/ebs/volume_write_ops")
async def get_ebs_metrics_write_ops(request: EBSRequest, response: Response):
    try:
        ebs_service = EBSMetrics(
            access_key=request.access_key,
            secret_key=request.secret_key,
            region=request.region,
            volume_id=request.volume_id
        )

        result = ebs_service.get_ebs_metric_data(
            metric='VolumeWriteOps',  
            start_time=request.start_time,
            end_time=request.end_time,
                        time=request.time,
            stat=request.stat
        )
        return result

    except Exception as e:
        return handle_response(response, validation_check=str(e))

@app.post("/metrics/ebs/volume_read_bytes")
async def get_ebs_metrics_read_bytes(request: EBSRequest, response: Response):
    try:
        ebs_service = EBSMetrics(
            access_key=request.access_key,
            secret_key=request.secret_key,
            region=request.region,
            volume_id=request.volume_id
        )

        result = ebs_service.get_ebs_metric_data(
            metric='VolumeReadBytes',  
            start_time=request.start_time,
            end_time=request.end_time,
                        time=request.time,
            stat=request.stat
        )
        return result

    except Exception as e:
        return handle_response(response, validation_check=str(e))

@app.post("/metrics/ebs/volume_write_bytes")
async def get_ebs_metrics_write_bytes(request: EBSRequest, response: Response):
    try:
        ebs_service = EBSMetrics(
            access_key=request.access_key,
            secret_key=request.secret_key,
            region=request.region,
            volume_id=request.volume_id
        )

        result = ebs_service.get_ebs_metric_data(
            metric='VolumeWriteBytes',  
            start_time=request.start_time,
            end_time=request.end_time,
                        time=request.time,
            stat=request.stat
        )
        return result

    except Exception as e:
        return handle_response(response, validation_check=str(e))

@app.post("/metrics/ebs/volume_total_read_time")
async def get_ebs_metrics_total_read_time(request: EBSRequest, response: Response):
    try:
        ebs_service = EBSMetrics(
            access_key=request.access_key,
            secret_key=request.secret_key,
            region=request.region,
            volume_id=request.volume_id
        )

        result = ebs_service.get_ebs_metric_data(
            metric='VolumeTotalReadTime',  
            start_time=request.start_time,
            end_time=request.end_time,
                        time=request.time,
            stat=request.stat
        )
        return result

    except Exception as e:
        return handle_response(response, validation_check=str(e))

@app.post("/metrics/ebs/volume_total_write_time")
async def get_ebs_metrics_total_write_time(request: EBSRequest, response: Response):
    try:
        ebs_service = EBSMetrics(
            access_key=request.access_key,
            secret_key=request.secret_key,
            region=request.region,
            volume_id=request.volume_id
        )

        result = ebs_service.get_ebs_metric_data(
            metric='VolumeTotalWriteTime',  
            start_time=request.start_time,
            end_time=request.end_time,
                        time=request.time,
            stat=request.stat
        )
        return result

    except Exception as e:
        return handle_response(response, validation_check=str(e))

@app.post("/metrics/ebs/volume_idle_time")
async def get_ebs_metrics_idle_time(request: EBSRequest, response: Response):
    try:
        ebs_service = EBSMetrics(
            access_key=request.access_key,
            secret_key=request.secret_key,
            region=request.region,
            volume_id=request.volume_id
        )

        result = ebs_service.get_ebs_metric_data(
            metric='VolumeIdleTime',  
            start_time=request.start_time,
            end_time=request.end_time,
                        time=request.time,
            stat=request.stat
        )
        return result

    except Exception as e:
        return handle_response(response, validation_check=str(e))

@app.post("/metrics/ebs/volume_queue_length")
async def get_ebs_metrics_queue_length(request: EBSRequest, response: Response):
    try:
        ebs_service = EBSMetrics(
            access_key=request.access_key,
            secret_key=request.secret_key,
            region=request.region,
            volume_id=request.volume_id
        )

        result = ebs_service.get_ebs_metric_data(
            metric='VolumeQueueLength',  
            start_time=request.start_time,
            end_time=request.end_time,
                        time=request.time,
            stat=request.stat
        )
        return result

    except Exception as e:
        return handle_response(response, validation_check=str(e))

@app.post("/metrics/ebs/volume_throughput_percentage")
async def get_ebs_metrics_throughput(request: EBSRequest, response: Response):
    try:
        ebs_service = EBSMetrics(
            access_key=request.access_key,
            secret_key=request.secret_key,
            region=request.region,
            volume_id=request.volume_id
        )

        result = ebs_service.get_ebs_metric_data(
            metric='VolumeThroughputPercentage',  
            start_time=request.start_time,
            end_time=request.end_time,
                        time=request.time,
            stat=request.stat
        )
        return result

    except Exception as e:
        return handle_response(response, validation_check=str(e))

@app.post("/metrics/ebs/BurstBalance")
async def get_ebs_metrics_burst_balance(request: EBSRequest, response: Response):
    try:
        ebs_service = EBSMetrics(
            access_key=request.access_key,
            secret_key=request.secret_key,
            region=request.region,
            volume_id=request.volume_id
        )

        result = ebs_service.get_ebs_metric_data(
            metric='BurstBalance',  
            start_time=request.start_time,
            end_time=request.end_time,
                        time=request.time,
            stat=request.stat
        )
        return result

    except Exception as e:
        return handle_response(response, validation_check=str(e))
    
@app.post("/metrics/ec2/categorized")
async def categorize_ec2_metrics(request: EC2Request, response: Response):
    try:
        ec2_metrics = EC2Metrics(
            request.access_key,
            request.secret_key,
            request.region,
            request.instance_id
        )
        metrics_results = {
            'cpu_utilization': ec2_metrics.get_cpu_utilization(request.start_time, request.end_time)
        }
        categorized_results = {
            'cpu_utilization': waf.categorize_metric_data_results(metrics_results['cpu_utilization']['MetricDataResults'])
        }
        return handle_response(response, data=categorized_results, data_name="Categorized EC2 metrics")
    except Exception as e:
        return handle_response(response, validation_check=str(e))

@app.post("/metrics/ec2/diskread")
async def get_ec2_diskread_metrics(request: EC2Request, response: Response):
    try:
        ec2_service = EC2Metrics(
            access_key=request.access_key,
            secret_key=request.secret_key,
            region=request.region,
            instance_id=request.instance_id
        )

        result = ec2_service.get_ec2_metric_data(
            metric='DiskReadOps',  
            start_time=request.start_time,
            end_time=request.end_time,
                        time=request.time,
            stat=request.stat
        )
        return result

    except Exception as e:
        return handle_response(response, validation_check=str(e))
    
@app.post("/metrics/ec2/diskwrite")
async def get_ec2_diskwrite_metrics(request: EC2Request, response: Response):
    try:
        ec2_service = EC2Metrics(
            access_key=request.access_key,
            secret_key=request.secret_key,
            region=request.region,
            instance_id=request.instance_id
        )

        result = ec2_service.get_ec2_metric_data(
            metric='DiskWriteOps',  
            start_time=request.start_time,
            end_time=request.end_time,
                        time=request.time,
            stat=request.stat
        )
        return result

    except Exception as e:
        return handle_response(response, validation_check=str(e))

@app.post("/metrics/ec2/networkin")
async def get_ec2_networkin_metrics(request: EC2Request, response: Response):
    try:
        ec2_service = EC2Metrics(
            access_key=request.access_key,
            secret_key=request.secret_key,
            region=request.region,
            instance_id=request.instance_id
        )

        result = ec2_service.get_ec2_metric_data(
            metric='NetworkIn',  
            start_time=request.start_time,
            end_time=request.end_time,
                        time=request.time,
            stat=request.stat
        )
        return result

    except Exception as e:
        return handle_response(response, validation_check=str(e))

@app.post("/metrics/ec2/networkout")
async def get_ec2_networkout_metrics(request: EC2Request, response: Response):
    try:
        ec2_service = EC2Metrics(
            access_key=request.access_key,
            secret_key=request.secret_key,
            region=request.region,
            instance_id=request.instance_id
        )

        result = ec2_service.get_ec2_metric_data(
            metric='NetworkOut',  
            start_time=request.start_time,
            end_time=request.end_time,
                        time=request.time,
            stat=request.stat
        )
        return result

    except Exception as e:
        return handle_response(response, validation_check=str(e))

@app.post("/metrics/ec2/diskreadbytes")
async def get_ec2_diskreadbytes_metrics(request: EC2Request, response: Response):
    try:
        ec2_service = EC2Metrics(
            access_key=request.access_key,
            secret_key=request.secret_key,
            region=request.region,
            instance_id=request.instance_id
        )

        result = ec2_service.get_ec2_metric_data(
            metric='DiskReadBytes',  
            start_time=request.start_time,
            end_time=request.end_time,
                        time=request.time,
            stat=request.stat
        )
        return result

    except Exception as e:
        return handle_response(response, validation_check=str(e))

@app.post("/metrics/ec2/diskwritebytes")
async def get_ec2_DiskWriteBytes_metrics(request: EC2Request, response: Response):
    try:
        ec2_service = EC2Metrics(
            access_key=request.access_key,
            secret_key=request.secret_key,
            region=request.region,
            instance_id=request.instance_id
        )

        result = ec2_service.get_ec2_metric_data(
            metric='DiskWriteBytes',  
            start_time=request.start_time,
            end_time=request.end_time,
                        time=request.time,
            stat=request.stat
        )
        return result

    except Exception as e:
        return handle_response(response, validation_check=str(e))

@app.post("/metrics/ec2/statuscheckfailed")
async def get_ec2_StatusCheckFailed_metrics(request: EC2Request, response: Response):
    try:
        ec2_service = EC2Metrics(
            access_key=request.access_key,
            secret_key=request.secret_key,
            region=request.region,
            instance_id=request.instance_id
        )

        result = ec2_service.get_ec2_metric_data(
            metric='StatusCheckFailed',  
            start_time=request.start_time,
            end_time=request.end_time,
            time=request.time,
            stat=request.stat
        )
        return result

    except Exception as e:
        return handle_response(response, validation_check=str(e))

@app.post("/metrics/ec2/categorized_day/image")
async def categorize_ec2_metrics_image(request: CredentiaRequest, response: Response):
    try:
        ec2_metrics = EC2Metrics(
            request.access_key,
            request.secret_key,
            request.region,
            request.generic_id
        )
        end_time =datetime.now().strftime('%Y-%m-%dT%H:%M:%S')

        # Calcular el inicio del día (start_time) a partir de la hora actual
        start_time = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0).strftime('%Y-%m-%dT%H:%M:%S')
        metrics_results = {
            'cpu_utilization': ec2_metrics.get_cpu_utilization(start_time, end_time)
        }
        categorized_results = waf.categorize_metric_data_results(metrics_results['cpu_utilization']['MetricDataResults'])
        image_base64 = waf.generate_image_from_metrics(categorized_results)
        return {"status": "success","message": "Categorized EC2 metrics as Image","image_base64": image_base64}
    except Exception as e:
        response.status_code = 400  # Código de estado de error
        return { "status": "error","message": str(e) }
    
@app.post("/metrics/load_balancer/target_response_time/image")
async def get_load_balance_target_response(request: CredentiaRequest, response: Response):
    try:
        load_balance_service = LoadBalancerMetrics(
            access_key=request.access_key,
            secret_key=request.secret_key,
            region=request.region,
            load_balancer_arn=request.generic_id
        )
        title='TargetResponseTime'
        start_time = (datetime.now() - timedelta(days=1)).strftime('%Y-%m-%dT%H:%M:%S')  
        end_time = datetime.now().strftime('%Y-%m-%dT%H:%M:%S')
        time = 3600
        stat = 'Average' 
        metrics_results = load_balance_service.get_metric_data(
            metric=title,
            start_time=start_time,
            end_time=end_time,
            time=time,
            stat=stat
        )
        timestamps = metrics_results['timestamps']
        values = metrics_results['values']

        # Genera la imagen a partir de los datos y la convierte en base64
        image_base64 = GenericImageGenerator.generate_base64_image(timestamps, values,title)

        return {"status": "success", "message": "Categorized Load Balancer Target Response Time as Image", "image_base64": image_base64}

    except Exception as e:
        response.status_code = 400
        return {"status": "error", "message": str(e)}
    
@app.post("/metrics/ebs/volume_write_bytes/image")
async def get_load_balance_target_response(request: CredentiaRequest, response: Response):
    try:
        ebs_service = EBSMetrics(
            access_key=request.access_key,
            secret_key=request.secret_key,
            region=request.region,
            volume_id=request.generic_id
        )
        title='VolumeWriteOps'
        start_time = (datetime.now() - timedelta(days=1)).strftime('%Y-%m-%dT%H:%M:%S')  
        end_time = datetime.now().strftime('%Y-%m-%dT%H:%M:%S')
        time = 3600
        stat = 'Average' 
        metrics_results = ebs_service.get_ebs_metric_data(
            metric=title,
            start_time=start_time,
            end_time=end_time,
            time=time,
            stat=stat
        )
        timestamps = metrics_results['timestamps']
        values = metrics_results['values']

        # Genera la imagen a partir de los datos y la convierte en base64
        image_base64 = GenericImageGenerator.generate_base64_image(timestamps, values,title)

        return {"status": "success", "message": "Volume Write Bytes", "image_base64": image_base64}

    except Exception as e:
        response.status_code = 400
        return {"status": "error", "message": str(e)}

@app.post("/metrics/vpn/tunnel_data_in/image")
async def get_vpn_metrics_tunnel_data_in_image(request: CredentiaRequest, response: Response):
    try:
        vpn_service = VPNMetrics(
            access_key=request.access_key,
            secret_key=request.secret_key,
            region=request.region,
            vpn_id=request.generic_id
        )
        title='TunnelDataIn'
        start_time = (datetime.now() - timedelta(days=1)).strftime('%Y-%m-%dT%H:%M:%S')  
        end_time = datetime.now().strftime('%Y-%m-%dT%H:%M:%S')
        time = 3600
        stat = 'Average' 
        result = vpn_service.get_tunnel_data(
            metric=title,  
            start_time=start_time,
            end_time=end_time,
            time=time,
            stat=stat
        )
        timestamps = result['timestamps']
        values = result['values']

        # Genera la imagen a partir de los datos y la convierte en base64
        image_base64 = GenericImageGenerator.generate_base64_image(timestamps, values,title)

        return {"status": "success", "message": "Tunnel data in", "image_base64": image_base64}

    except Exception as e:
        response.status_code = 400
        return {"status": "error", "message": str(e)}

@app.post("/metrics/vpn/tunnel_data_out/image")
async def get_vpn_metrics_tunnel_data_out_image(request: CredentiaRequest, response: Response):
    try:
        vpn_service = VPNMetrics(
            access_key=request.access_key,
            secret_key=request.secret_key,
            region=request.region,
            vpn_id=request.generic_id
        )
        title='TunnelDataOut'
        start_time = (datetime.now() - timedelta(days=1)).strftime('%Y-%m-%dT%H:%M:%S')  
        end_time = datetime.now().strftime('%Y-%m-%dT%H:%M:%S')
        time = 3600
        stat = 'Average' 
        result = vpn_service.get_tunnel_data(
            metric=title,  
            start_time=start_time,
            end_time=end_time,
            time=time,
            stat=stat
        )
        timestamps = result['timestamps']
        values = result['values']

        # Genera la imagen a partir de los datos y la convierte en base64
        image_base64 = GenericImageGenerator.generate_base64_image(timestamps, values,title)

        return {"status": "success", "message": "Tunnel data out", "image_base64": image_base64}
    except Exception as e:
        response.status_code = 400
        return {"status": "error", "message": str(e)}
    
@app.post("/metrics/vpn/tunnel_state/image")
async def get_vpn_metrics_tunnel_state_image(request: CredentiaRequest, response: Response):
    try:
        vpn_service = VPNMetrics(
            access_key=request.access_key,
            secret_key=request.secret_key,
            region=request.region,
            vpn_id=request.generic_id
        )

        title='TunnelState'
        start_time = (datetime.now() - timedelta(days=1)).strftime('%Y-%m-%dT%H:%M:%S')  
        end_time = datetime.now().strftime('%Y-%m-%dT%H:%M:%S')
        time = 3600
        stat = 'Average' 
        result = vpn_service.get_tunnel_data(
            metric=title,  
            start_time=start_time,
            end_time=end_time,
            time=time,
            stat=stat
        )
        timestamps = result['timestamps']
        values = result['values']

        # Genera la imagen a partir de los datos y la convierte en base64
        image_base64 = GenericImageGenerator.generate_base64_image(timestamps, values,title)

        return {"status": "success", "message": "Tunnel state", "image_base64": image_base64}
    except Exception as e:
        response.status_code = 400
        return {"status": "error", "message": str(e)}