import { alovaInstance } from 'api/endpoints';

import type {
  APIcall,
  Action,
  Activity,
  CommandItem,
  Commands,
  CoreData,
  DashboardData,
  DeviceData,
  DeviceEntity,
  Entities,
  EntityItem,
  ModuleItem,
  Modules,
  Schedule,
  ScheduleItem,
  SensorData,
  Settings,
  WriteAnalogSensor,
  WriteTemperatureSensor
} from '../app/main/types';

const MSGPACK_CONFIG = { responseType: 'arraybuffer' as const };

// Dashboard
export const readDashboard = () =>
  alovaInstance.Get<DashboardData>('/rest/dashboardData', MSGPACK_CONFIG);

// Devices
export const readCoreData = () => alovaInstance.Get<CoreData>('/rest/coreData');
export const readDeviceData = (id: number) =>
  alovaInstance.Get<DeviceData>('/rest/deviceData', {
    params: { id },
    ...MSGPACK_CONFIG
  });
export const writeDeviceValue = (data: { id: number; c: string; v: unknown }) =>
  alovaInstance.Post('/rest/writeDeviceValue', data);

// Application Settings
export const readSettings = () => alovaInstance.Get<Settings>('/rest/settings');
export const writeSettings = (data: Settings) =>
  alovaInstance.Post('/rest/settings', data);
export const getBoardProfile = (boardProfile: string) =>
  alovaInstance.Get('/rest/boardProfile', {
    params: { boardProfile }
  });

// Sensors
export const readSensorData = () =>
  alovaInstance.Get<SensorData>('/rest/sensorData');
export const writeTemperatureSensor = (ts: WriteTemperatureSensor) =>
  alovaInstance.Post('/rest/writeTemperatureSensor', ts);
export const writeAnalogSensor = (as: WriteAnalogSensor) =>
  alovaInstance.Post('/rest/writeAnalogSensor', as);

// Activity
export const readActivity = () => alovaInstance.Get<Activity>('/rest/activity');

// API
export const API = (apiCall: APIcall) => alovaInstance.Post('/api', apiCall);

// Generic action
export const callAction = (action: Action) =>
  alovaInstance.Post('/rest/action', action);

// SettingsCustomization
export const readDeviceEntities = (id: number) =>
  alovaInstance.Get<DeviceEntity[]>('/rest/deviceEntities', {
    params: { id },
    ...MSGPACK_CONFIG,
    // @ts-expect-error - exactOptionalPropertyTypes compatibility issue
    transform(data) {
      const entities = data as DeviceEntity[];
      return entities.map((de) => ({
        ...de,
        o_m: de.m,
        o_cn: de.cn,
        o_mi: de.mi,
        o_ma: de.ma
      }));
    }
  });
export const resetCustomizations = () =>
  alovaInstance.Post('/rest/resetCustomizations');
export const writeCustomizationEntities = (data: {
  id: number;
  entity_ids: string[];
}) => alovaInstance.Post('/rest/customizationEntities', data);
export const writeDeviceName = (data: { id: number; name: string }) =>
  alovaInstance.Post('/rest/writeDeviceName', data);

// SettingsScheduler
export const readSchedule = () =>
  alovaInstance.Get<ScheduleItem[]>('/rest/schedule', {
    // @ts-expect-error - exactOptionalPropertyTypes compatibility issue
    transform(data) {
      const schedule = (data as Schedule).schedule;
      return schedule.map((si) => ({
        ...si,
        o_id: si.id,
        o_active: si.active,
        o_deleted: si.deleted,
        o_flags: si.flags,
        o_time: si.time,
        o_cmd_name: si.cmd_name,
        o_name: si.name
      }));
    }
  });
export const writeSchedule = (data: Schedule) =>
  alovaInstance.Post('/rest/schedule', data);

// Commands
export const readCommands = () =>
  alovaInstance.Get<CommandItem[]>('/rest/commands', {
    // @ts-expect-error - exactOptionalPropertyTypes compatibility issue
    transform(data) {
      const commands = (data as Commands).commands;
      return commands.map((ci) => ({
        ...ci,
        o_id: ci.id,
        o_cmd: ci.cmd,
        o_value: ci.value,
        o_name: ci.name
      }));
    }
  });
export const writeCommands = (data: Commands) =>
  alovaInstance.Post('/rest/commands', data);

// Modules
export const readModules = () =>
  alovaInstance.Get<ModuleItem[]>('/rest/modules', {
    transform(data) {
      const modules = (data as Modules).modules;
      return modules.map((mi) => ({
        ...mi,
        o_enabled: mi.enabled,
        o_license: mi.license
      }));
    }
  });
export const writeModules = (data: {
  key: string;
  enabled: boolean;
  license: string;
}) => alovaInstance.Post('/rest/modules', data);

// CustomEntities
export const readCustomEntities = () =>
  alovaInstance.Get<EntityItem[]>('/rest/customEntities', {
    // @ts-expect-error - exactOptionalPropertyTypes compatibility issue
    transform(data) {
      const entities = (data as Entities).entities;
      return entities.map((ei) => ({
        ...ei,
        o_id: ei.id,
        o_ram: ei.ram,
        o_device_id: ei.device_id,
        o_type_id: ei.type_id,
        o_offset: ei.offset,
        o_factor: ei.factor,
        o_uom: ei.uom,
        o_value_type: ei.value_type,
        o_name: ei.name,
        o_writeable: ei.writeable,
        o_value: ei.value,
        o_deleted: ei.deleted,
        o_hide: ei.hide
      }));
    }
  });
export const writeCustomEntities = (data: Entities) =>
  alovaInstance.Post('/rest/customEntities', data);
