#!/usr/bin/env python3
"""
Cariflex - OpenADR VEN (Virtual End Node)
Reçoit les signaux DSR du VTN et les transmet à FlexMeasures.
"""

import asyncio
import logging
from datetime import datetime, timezone, timedelta
from openleadr import OpenADRClient, enable_default_logging
import requests
import re

enable_default_logging()
logger = logging.getLogger("openleadr")

FM_HOST = "https://cariflex.digitribe.fr"
FM_EMAIL = "admin@digitribe.fr"
FM_PASSWORD = "Digitribe972"
VEN_ID = "Cariflex-VEN"
VTN_URL = "http://localhost:8081"

# Sensor IDs in FM
SENSOR_CONSUMPTION_PRICE = 84
SENSOR_LOAD_CONTROL = 86


def fm_login():
    session = requests.Session()
    session.verify = False
    r = session.get(f"{FM_HOST}/login")
    match = re.search(r'<input[^>]*csrf_token[^>]*value="([^"]+)"', r.text)
    if match:
        csrf = match.group(1)
        r = session.post(f"{FM_HOST}/login", data={
            "email": FM_EMAIL, "password": FM_PASSWORD,
            "csrf_token": csrf, "remember": "y"
        }, allow_redirects=True)
        if "dashboard" in r.url:
            return session
    return None


def post_sensor_data(session, sensor_id, value, unit, start, duration="PT1H"):
    r = session.post(
        f"{FM_HOST}/api/v3_0/sensors/{sensor_id}/data",
        json={"values": [value], "start": start, "duration": duration, "unit": unit},
        timeout=30
    )
    return r.status_code in [200, 201, 202]


async def main():
    client = OpenADRClient(
        ven_id=VEN_ID,
        ven_name=VEN_ID,
        vtn_url=VTN_URL,
    )
    
    logger.info(f"Starting Cariflex VEN: {VEN_ID}")
    logger.info(f"Connecting to VTN: {VTN_URL}")
    
    # Login to FM
    session = fm_login()
    if session:
        logger.info("Logged in to FlexMeasures")
    else:
        logger.error("Failed to login to FlexMeasures")
        return
    
    # Add event handler
    @client.on_event
    async def handle_event(event):
        logger.info(f"Received event: {event}")
        
        # Extract signal data
        for signal in event.get("event_signals", []):
            signal_name = signal.get("signal_name")
            
            for interval in signal.get("intervals", []):
                payload = interval.get("signal_payload", 0)
                dtstart = interval.get("dtstart", datetime.now(timezone.utc))
                
                if signal_name == "ENERGY_PRICE":
                    price = round(float(payload), 2)
                    success = post_sensor_data(
                        session, SENSOR_CONSUMPTION_PRICE, price, "EUR/MWh",
                        dtstart.isoformat() if isinstance(dtstart, datetime) else str(dtstart)
                    )
                    logger.info(f"Price {price} EUR/MWh: {success}")
                
                elif signal_name == "LOAD_CONTROL":
                    success = post_sensor_data(
                        session, SENSOR_LOAD_CONTROL, round(float(payload), 2), "%",
                        dtstart.isoformat() if isinstance(dtstart, datetime) else str(dtstart)
                    )
                    logger.info(f"Load control {payload}: {success}")
        
        return "optIn"
    
    # Run the client
    await client.run()


if __name__ == "__main__":
    asyncio.run(main())
