/**
 * Provider descriptor registry.
 *
 * Single entry point for all provider-specific UI logic.
 * Components call `getDescriptor(type)` instead of if/else chains.
 */

import type { ProviderDescriptor } from './types';
import { immichDescriptor } from './immich';
import { giteaDescriptor } from './gitea';
import { plankaDescriptor } from './planka';
import { schedulerDescriptor } from './scheduler';
import { nutDescriptor } from './nut';
import { googlePhotosDescriptor } from './google-photos';
import { webhookDescriptor } from './webhook';
import { homeAssistantDescriptor } from './home-assistant';
import { bridgeSelfDescriptor } from './bridge-self';

const REGISTRY: ReadonlyMap<string, ProviderDescriptor> = new Map([
	['immich', immichDescriptor],
	['gitea', giteaDescriptor],
	['planka', plankaDescriptor],
	['scheduler', schedulerDescriptor],
	['nut', nutDescriptor],
	['google_photos', googlePhotosDescriptor],
	['webhook', webhookDescriptor],
	['home_assistant', homeAssistantDescriptor],
	['bridge_self', bridgeSelfDescriptor],
]);

/** Look up a provider descriptor by type. Returns null for unknown types. */
export function getDescriptor(type: string): ProviderDescriptor | null {
	return REGISTRY.get(type) ?? null;
}

/** All registered descriptors (stable order). */
export function allDescriptors(): ProviderDescriptor[] {
	return [...REGISTRY.values()];
}

/** All registered provider type strings. */
export function allProviderTypes(): string[] {
	return [...REGISTRY.keys()];
}

/**
 * Build a default form state for the tracking config "Event tracking" fieldset.
 * Merges event field defaults from ALL providers so the form can load any
 * existing config without missing keys, but only the active provider's fields
 * are rendered.
 */
export function buildTrackingFormDefaults(): Record<string, any> {
	const defaults: Record<string, any> = {};
	// `defaultValue` may be a function (for time-sensitive defaults like
	// today's date) so the computed value is fresh each time the form resets.
	const resolve = (v: unknown): unknown => (typeof v === 'function' ? (v as () => unknown)() : v);
	for (const desc of REGISTRY.values()) {
		for (const field of desc.eventFields) {
			defaults[field.key] = field.default;
		}
		for (const extra of desc.extraTrackingFields ?? []) {
			defaults[extra.key] = resolve(extra.defaultValue) ?? '';
		}
		for (const section of desc.featureSections ?? []) {
			defaults[section.enabledField] = section.enabledDefault;
			for (const f of section.fields) {
				defaults[f.key] = resolve(f.defaultValue) ?? '';
			}
			for (const cb of section.checkboxes ?? []) {
				defaults[cb.key] = cb.default;
			}
		}
	}
	return defaults;
}

/**
 * Build a default flat form state for the provider config form.
 * All config fields from all providers are included with empty/default values.
 */
export function buildProviderFormDefaults(): Record<string, any> {
	const defaults: Record<string, any> = {
		name: '', type: '', url: '', icon: '',
	};
	for (const desc of REGISTRY.values()) {
		for (const field of desc.configFields) {
			defaults[field.key] = field.defaultValue ?? (field.type === 'number' ? 0 : '');
		}
	}
	return defaults;
}

export type { ProviderDescriptor, ConfigField, EventTrackingField, ExtraTrackingField, FeatureSection, CollectionMeta } from './types';
