import type * as shxInterfaces from '@smarthome.exchange/interfaces';
import { BaseIntegration } from '../../core/classes.baseintegration.js';
import type { IIntegrationEntity, IIntegrationEvent, IIntegrationRuntime, IIntegrationSetupContext, IServiceCallRequest, IServiceCallResult } from '../../core/types.js';
import { DoorbirdClient } from './doorbird.classes.client.js';
import { DoorbirdConfigFlow } from './doorbird.classes.configflow.js';
import { createDoorbirdDiscoveryDescriptor } from './doorbird.discovery.js';
import { DoorbirdMapper } from './doorbird.mapper.js';
import type { IDoorbirdConfig } from './doorbird.types.js';
import { doorbirdDomain } from './doorbird.types.js';

export class DoorbirdIntegration extends BaseIntegration<IDoorbirdConfig> {
  public readonly domain = doorbirdDomain;
  public readonly displayName = 'DoorBird';
  public readonly status = 'control-runtime' as const;
  public readonly discoveryDescriptor = createDoorbirdDiscoveryDescriptor();
  public readonly configFlow = new DoorbirdConfigFlow();
  public readonly metadata = {
    source: 'home-assistant/core',
    upstreamPath: 'homeassistant/components/doorbird',
    upstreamDomain: doorbirdDomain,
    integrationType: 'device',
    iotClass: 'local_push',
    requirements: ['DoorBirdPy==3.0.11'],
    dependencies: ['http', 'repairs'],
    afterDependencies: [] as string[],
    codeowners: ['@oblogic7', '@bdraco', '@flacjacket'],
    configFlow: true,
    documentation: 'https://www.home-assistant.io/integrations/doorbird',
    zeroconf: [{ type: '_axis-video._tcp.local.', properties: { macaddress: '1ccae3*' } }],
    discovery: {
      manual: true,
      zeroconf: '_axis-video._tcp.local. advertisements with macaddress OUI 1CCAE3 are recognized.',
    },
    runtime: {
      type: 'control-runtime',
      polling: 'local HTTP DoorBird LAN API /bha-api/info.cgi, /bha-api/monitor.cgi?check=doorbell|motionsensor, and snapshot endpoints',
      services: ['snapshot', 'status', 'refresh', 'energize_relay', 'turn_light_on', 'favorites', 'schedule'],
      controls: true,
    },
    localApi: {
      implemented: [
        'DoorBird local HTTP info/status/snapshot API compatible with DoorBirdPy 3.0.11 endpoints used by Home Assistant',
        'zeroconf/manual discovery and config flow output for local HTTP setup',
        'relay, IR light, favorites, and schedule HTTP command shapes where represented by the upstream integration',
      ],
      explicitUnsupported: [
        'Home Assistant HTTP callback view hosting for DoorBird favorite events',
        'fake live event or command success without a configured HTTP endpoint, injected client, or command executor',
      ],
    },
  };

  public async setup(configArg: IDoorbirdConfig, contextArg: IIntegrationSetupContext): Promise<IIntegrationRuntime> {
    void contextArg;
    return new DoorbirdRuntime(new DoorbirdClient(configArg));
  }

  public async destroy(): Promise<void> {}
}

export class HomeAssistantDoorbirdIntegration extends DoorbirdIntegration {}

class DoorbirdRuntime implements IIntegrationRuntime {
  public domain = doorbirdDomain;

  constructor(private readonly client: DoorbirdClient) {}

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

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

  public async subscribe(handlerArg: (eventArg: IIntegrationEvent) => void): Promise<() => Promise<void>> {
    void handlerArg;
    throw new Error('DoorBird live event subscription is not implemented in this TypeScript port; use status polling or configure DoorBird HTTP favorites against a real callback endpoint.');
  }

  public async callService(requestArg: IServiceCallRequest): Promise<IServiceCallResult> {
    try {
      if (requestArg.domain === doorbirdDomain && (requestArg.service === 'snapshot' || requestArg.service === 'status')) {
        const snapshot = await this.client.getSnapshot();
        return { success: true, data: requestArg.service === 'status' ? snapshot.status : snapshot };
      }
      if (requestArg.domain === doorbirdDomain && requestArg.service === 'refresh') {
        const result = await this.client.refresh();
        return { success: result.success, error: result.error, data: result.snapshot || result.data };
      }

      const snapshot = await this.client.getSnapshot();
      const command = DoorbirdMapper.commandForService(snapshot, requestArg);
      if (!command) {
        return { success: false, error: `Unsupported DoorBird service: ${requestArg.domain}.${requestArg.service}` };
      }
      const data = await this.client.execute(command);
      const ok = data && typeof data === 'object' && 'ok' in data ? Boolean((data as { ok?: unknown }).ok) : true;
      return { success: ok, data };
    } catch (errorArg) {
      return { success: false, error: errorArg instanceof Error ? errorArg.message : String(errorArg) };
    }
  }

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