import numpy as np
from fastapi import APIRouter, Depends
from loguru import logger
from sqlalchemy.orm import Session

import app.models.domain.devices as domain_devices
from app.api.dependencies.db import get_db
from app.controllers.equipment.ahu.basic import build_acatah_freq_set
from app.controllers.equipment.ahu.supply_air_temperature_set import (
    build_acatah_supply_air_temperature_set,
)
from app.controllers.equipment.ahu.switch import build_acatah_switch_set
from app.controllers.equipment.ahu.thermal_mode import build_acatah_thermal_mode_set
from app.controllers.equipment.fcu.basic import build_acatfc_instructions
from app.controllers.equipment.fcu.early_start import (
    build_acatfc_early_start_prediction,
)
from app.controllers.equipment.pau.freq_set import build_acatfu_freq_set
from app.controllers.equipment.pau.supply_air_temperature_set import (
    build_acatfu_supply_air_temperature,
)
from app.controllers.equipment.pau.switch import build_acatfu_switch_set
from app.controllers.equipment.vav import build_acatva_instructions
from app.controllers.equipment.ventilation_fan.switch import build_acvtsf_switch_set
from app.controllers.equipment.vrf.basic import build_acatvi_instructions

router = APIRouter()


@router.post(
    "/instructions/acatah/thermal-mode-set",
    response_model=domain_devices.ACATAHThermalModeSetResponse,
)
async def get_acatah_thermal_mode_set_v2(
    params: domain_devices.ACATAHThermalModeSetRequest,
):
    thermal_mode = build_acatah_thermal_mode_set(params)

    logger.info(f"{params.device_id}: thermal mode set - {thermal_mode}")
    resp = {"thermal_mode_set": thermal_mode}

    return resp


@router.post(
    "/instructions/acatah/supply-air-temperature-set",
    response_model=domain_devices.ACATAHSupplyAirTempSetResponse,
)
async def get_acatah_supply_air_temperature_set_v2(
    params: domain_devices.ACATAHSupplyAirTempSetRequest,
):
    supply_air_temperature_set = build_acatah_supply_air_temperature_set(params)

    logger.info(supply_air_temperature_set)

    resp = {"supply_air_temperature_set": supply_air_temperature_set}

    return resp


@router.post(
    "/instructions/acatah/freq-set", response_model=domain_devices.ACATAHFreqSetResponse
)
async def get_acatah_freq_set(params: domain_devices.ACATAHFreqSetRequest):
    freq_set = await build_acatah_freq_set(params)

    logger.info(params)
    logger.info(f"{params.device_id}: freq set - {freq_set}")

    resp = {"freq_set": freq_set}

    return resp


@router.post(
    "/instructions/acatah/switch-set",
    response_model=domain_devices.ACATAHSwitchSetResponse,
)
async def get_acatah_switch_set(params: domain_devices.ACATAHSwitchSetRequest):
    switch_set = await build_acatah_switch_set(params)

    logger.info(params)
    logger.info(f"{params.device_id}: switch set - {switch_set}")

    resp = {"switch_set": switch_set}

    return resp


@router.post(
    "/instructions/acvtsf/switch-set",
    response_model=domain_devices.ACVTSFSwitchSetResponse,
)
async def get_acvtsf_switch_set(params: domain_devices.ACVTSFSwitchSetRequest):
    switch_set = await build_acvtsf_switch_set(params)

    logger.info(params)
    logger.info(f"{params.device_id}: switch set - {switch_set}")

    resp = {"switch_set": switch_set}

    return resp


@router.post(
    "/instructions/acatfu/switch-set",
    response_model=domain_devices.ACATFUSwitchSetResponse,
)
async def get_acatfu_switch_set(params: domain_devices.ACATFUSwitchSetRequest):
    switch_set = await build_acatfu_switch_set(params)

    logger.info(params)
    logger.info(f"{params.device_id}: switch set - {switch_set}")

    resp = {"switch_set": switch_set}

    return resp


@router.post(
    "/instructions/acatfu/supply-air-temperature-set",
    response_model=domain_devices.ACATFUSupplyAirTempSetResponse,
)
async def get_acatfu_supply_air_temperature_set_v2(
    params: domain_devices.ACATFUSupplyAirTempSetRequest,
):
    supply_air_temperature_set = build_acatfu_supply_air_temperature(params)

    logger.info(supply_air_temperature_set)

    resp = {"supply_air_temperature_set": supply_air_temperature_set}

    return resp


@router.post(
    "/instructions/acatfu/freq-set", response_model=domain_devices.ACATFUFreqSetResponse
)
async def get_acatfu_freq_set(params: domain_devices.ACATFUFreqSetRequest):
    freq_set = build_acatfu_freq_set(params)

    logger.info(f"{params.device_id} - {freq_set}")

    resp = {"freq_set": freq_set}

    return resp


@router.post(
    "/prediction/acatfc/early-start",
    response_model=domain_devices.ACATFCEarlyStartPredictionResponse,
)
async def get_acatfc_early_start_prediction(
    params: domain_devices.ACATFCEarlyStartPredictionRequest,
    db: Session = Depends(get_db),
):
    minutes = await build_acatfc_early_start_prediction(params, db)

    logger.info(params)
    logger.info(f"{params.space_id} - {minutes}")

    resp = {"minutes": minutes}

    return resp


@router.post(
    "/instructions/acatvi", response_model=domain_devices.ACATVIInstructionsResponse
)
async def get_acatvi_instructions(
    params: domain_devices.ACATVIInstructionsRequest, db: Session = Depends(get_db)
):
    instructions = await build_acatvi_instructions(params, db)

    logger.info(params)
    logger.info(f"{params.device_id} - {instructions}")

    return instructions


@router.post(
    "/instructions/acatfc", response_model=domain_devices.ACATFCInstructionsResponse
)
async def get_acatfc_instructions(params: domain_devices.ACATFCInstructionsRequest):
    instructions = await build_acatfc_instructions(params)

    logger.info(params)
    logger.info(f"{params.device_id} - {instructions}")

    response = domain_devices.ACATFCInstructionsResponse(
        onOff=instructions.switch_set,
        speed=instructions.speed_set,
        temperature=instructions.temperature_set,
        mode=instructions.switch_set,
        water=instructions.water_valve_switch_set,
    )

    return response


@router.post(
    "/instructions/acatva", response_model=domain_devices.ACATVAInstructionsResponse
)
async def get_acatva_instructions(params: domain_devices.ACATVAInstructionsRequest):
    instructions = await build_acatva_instructions(params)

    logger.info(params)
    logger.info(f"{params.device_id} - {instructions}")

    resp = dict()
    if not np.isnan(instructions.supply_air_flow_set):
        resp.update({"SupplyAirFlowSet": instructions.supply_air_flow_set})
    if not np.isnan(instructions.virtual_realtime_temperature):
        resp.update(
            {"VirtualRealtimeTemperature": instructions.virtual_realtime_temperature}
        )
    if not np.isnan(instructions.virtual_temperature_target_set):
        resp.update(
            {"TargetTemperatureSet": instructions.virtual_temperature_target_set}
        )

    return resp