import { SimpleLocalIntegration } from '../../core/index.js';
import type * as shxInterfaces from '@smarthome.exchange/interfaces';
import type { IIntegrationEntity, IIntegrationRuntime, IIntegrationSetupContext, IServiceCallRequest, IServiceCallResult } from '../../core/index.js';
import { IncomfortClient } from './incomfort.classes.client.js';
import { IncomfortConfigFlow } from './incomfort.classes.configflow.js';
import { createIncomfortDiscoveryDescriptor } from './incomfort.discovery.js';
import { IncomfortMapper } from './incomfort.mapper.js';
import type { IIncomfortConfig } from './incomfort.types.js';
import { incomfortDomain, incomfortProfile } from './incomfort.types.js';

export class IncomfortIntegration extends SimpleLocalIntegration<IIncomfortConfig> {
  public readonly domain = incomfortDomain;
  public readonly discoveryDescriptor = createIncomfortDiscoveryDescriptor();
  public readonly configFlow = new IncomfortConfigFlow();

  constructor() {
    super(incomfortProfile);
  }

  public async setup(configArg: IIncomfortConfig, contextArg: IIntegrationSetupContext): Promise<IIntegrationRuntime> {
    void contextArg;
    return new IncomfortRuntime(new IncomfortClient(configArg));
  }
}

class IncomfortRuntime implements IIntegrationRuntime {
  public readonly domain = incomfortDomain;

  constructor(private readonly client: IncomfortClient) {}

  public async devices(): Promise<shxInterfaces.data.IDeviceDefinition[]> {
    return IncomfortMapper.toDevices(await this.client.getSnapshot());
  }

  public async entities(): Promise<IIntegrationEntity[]> {
    return IncomfortMapper.toEntities(await this.client.getSnapshot());
  }

  public async callService(requestArg: IServiceCallRequest): Promise<IServiceCallResult> {
    if (!this.acceptsDomain(requestArg.domain)) {
      return { success: false, error: `Unsupported InComfort service domain: ${requestArg.domain}` };
    }
    if (requestArg.service === 'snapshot' || requestArg.service === 'status') {
      return { success: true, data: await this.client.getSnapshot() };
    }
    if (requestArg.service === 'refresh' || requestArg.service === 'reload') {
      return this.client.refresh();
    }
    if (requestArg.service === 'set_temperature' || requestArg.service === 'set_hvac_mode') {
      return this.client.execute(requestArg);
    }
    return { success: false, error: `Unsupported InComfort service: ${requestArg.service}` };
  }

  public async destroy(): Promise<void> {
    await this.client.destroy();
  }

  private acceptsDomain(domainArg: string): boolean {
    return domainArg === incomfortDomain || Boolean(incomfortProfile.serviceDomains?.includes(domainArg));
  }
}
