#include <app/ConcreteAttributePath.h>
#include <lib/support/logging/CHIPLogging.h>
#include "platform/CHIPDeviceLayer.h"
#include <app-common/zap-generated/attributes/Accessors.h>
#include <app-common/zap-generated/callback.h>
#include <app-common/zap-generated/cluster-objects.h>
#include <sys/_stdint.h>
#include <zap-generated/PluginApplicationCallbacks.h>
#include <zap-generated/clusters/WaterValveData/Commands.h>

#include "app/data-model/List.h"
#include "app/task_executor.h"
#include "clusters/WaterValveData/Enums.h"
#include "clusters/WaterValveData/Structs.h"
#include "lib/support/logging/TextOnlyLogging.h"

using namespace chip;
using namespace chip::app;
using namespace chip::app::Clusters;

void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath &attributePath,
                                       uint8_t type,
                                       uint16_t size,
                                       uint8_t *value)
{
    ClusterId clusterId = attributePath.mClusterId;
    AttributeId attributeId = attributePath.mAttributeId;
    EndpointId endpointId = attributePath.mEndpointId;

    uint32_t value32 = 0;

    if (size == 1)
        value32 = *value;
    else if (size == 2)
        value32 = *reinterpret_cast<uint16_t *>(value);
    else if (size == 4)
        value32 = *reinterpret_cast<uint32_t *>(value);

    ChipLogProgress(DeviceLayer,
                    "====================Attribute change on endpoint %d, clusterId: %" PRIu32 ", attributeId: %" PRIu32
                    ", type: %d, size: %d, value: %d",
                    endpointId,
                    clusterId,
                    attributeId,
                    type,
                    size,
                    value32);
}

bool emberAfWaterValveDataClusterGetWaterStatsCallback(
    chip::app::CommandHandler *commandObj,
    const chip::app::ConcreteCommandPath &commandPath,
    const chip::app::Clusters::WaterValveData::Commands::GetWaterStats::DecodableType &commandData)
{
    ChipLogProgress(DeviceLayer,
                    "[%s] Water stats requested, stats = %d last = %d",
                    __FUNCTION__,
                    static_cast<int>(commandData.stats),
                    commandData.last);

    return true;
}

bool emberAfWaterValveDataClusterGetWaterUsageCallback(
    chip::app::CommandHandler *commandObj,
    const chip::app::ConcreteCommandPath &commandPath,
    const chip::app::Clusters::WaterValveData::Commands::GetWaterUsage::DecodableType &commandData)
{
    ChipLogProgress(DeviceLayer, "[%s] Water usage requested", __FUNCTION__);
    return true;
}

bool emberAfWaterValveDataClusterSetValveSessionCallback(
    chip::app::CommandHandler *commandObj,
    const chip::app::ConcreteCommandPath &commandPath,
    const chip::app::Clusters::WaterValveData::Commands::SetValveSession::DecodableType &commandData)
{
    ChipLogProgress(
        DeviceLayer,
        "[%s] Set Valve session requested - hour: %u, minute: %u duration: %u weekdays: %u, volume: %u, operation: %d",
        __FUNCTION__,
        commandData.session.hour,
        commandData.session.minute,
        commandData.session.duration,
        commandData.session.weekdays,
        commandData.session.volume,
        static_cast<int>(commandData.operation));
    return true;
}

bool emberAfWaterValveDataClusterGetValveSessionLogsCallback(
    chip::app::CommandHandler *commandObj,
    const chip::app::ConcreteCommandPath &commandPath,
    const chip::app::Clusters::WaterValveData::Commands::GetValveSessionLogs::DecodableType &commandData)
{
    ChipLogProgress(DeviceLayer, "[%s] Get valve session logs page:%d", __FUNCTION__, commandData.page);
    return true;
}

bool emberAfWaterValveDataClusterGetAllValveSessionCallback(
    chip::app::CommandHandler *commandObj,
    const chip::app::ConcreteCommandPath &commandPath,
    const chip::app::Clusters::WaterValveData::Commands::GetAllValveSession::DecodableType &commandData)
{
    return true;
}

bool emberAfWaterValveDataClusterOpenValveWithVolumeCallback(
    chip::app::CommandHandler *commandObj,
    const chip::app::ConcreteCommandPath &commandPath,
    const chip::app::Clusters::WaterValveData::Commands::OpenValveWithVolume::DecodableType &commandData)
{
    ChipLogProgress(DeviceLayer,
                    "[%s] Open valve with volume: %d.%dL",
                    __FUNCTION__,
                    commandData.volume / 10,
                    commandData.volume % 10);
    return true;
}

bool emberAfWaterValveDataClusterGetValveTemperatureRecordCallback(
    chip::app::CommandHandler *commandObj,
    const chip::app::ConcreteCommandPath &commandPath,
    const chip::app::Clusters::WaterValveData::Commands::GetValveTemperatureRecord::DecodableType &commandData)
{
    ChipLogProgress(DeviceLayer, "[%s] Get valve temperature record page:%d", __FUNCTION__, commandData.page);
    return true;
}

bool emberAfWaterValveDataClusterGetValveFreezeRecordCallback(
    chip::app::CommandHandler *commandObj,
    const chip::app::ConcreteCommandPath &commandPath,
    const chip::app::Clusters::WaterValveData::Commands::GetValveFreezeRecord::DecodableType &commandData)
{
    ChipLogProgress(DeviceLayer, "[%s] Get valve freeze record page:%d", __FUNCTION__, commandData.page);
    return true;
}

void MatterWaterValveDataPluginServerInitCallback()
{
    return;
}

void emberAfTemperatureMeasurementClusterInitCallback(chip::EndpointId endpoint)
{
    ChipLogProgress(DeviceLayer, "[%s] Init temperature measurement cluster", __FUNCTION__);
}

void emberAfBooleanStateClusterServerInitCallback(chip::EndpointId endpoint)
{
}

void emberAfValveConfigurationAndControlClusterServerInitCallback(chip::EndpointId endpoint)
{
}