import { type SetRequiredAndNotNull } from '@augment-vir/common';
import { type EmptyObject, type IsAny, type IsEmptyObject } from 'type-fest';
import { LitElement, type CSSResult } from '../lit-exports/base-lit-exports.js';
import { type MinimalDefinitionWithInputs } from '../template-transforms/minimal-element-definition.js';
import { type CustomElementTagName } from './custom-tag-name.js';
import { type DeclarativeElementInit } from './declarative-element-init.js';
import { type DeclarativeElementDefinitionOptions } from './definition-options.js';
import { type BaseCssPropertyName } from './properties/css-properties.js';
import { type CssVars } from './properties/css-vars.js';
import { type EventDescriptorMap, type EventsInitMap } from './properties/element-events.js';
import { type PropertyInitMapBase } from './properties/element-properties.js';
import { type HostClassNamesMap } from './properties/host-classes.js';
import { type ObservableListenerMap } from './properties/property-proxy.js';
import { type RenderCallback, type RenderParams, type UpdateStateCallback } from './render-callback.js';
import { type SlotNameMap } from './slot-names.js';
/**
 * The `host` type for a declarative element. This references a declarative element instance's
 * top-level HTML element and always contains a shadow root (wherein the element is rendered).
 *
 * @category Internal
 */
export type DeclarativeElementHost<TagName extends CustomElementTagName = any, Inputs extends PropertyInitMapBase = any, State extends PropertyInitMapBase = any, EventsInit extends EventsInitMap = any, HostClassKeys extends BaseCssPropertyName<TagName> = any, CssVarKeys extends BaseCssPropertyName<TagName> = any, SlotNames extends ReadonlyArray<string> = any> = SetRequiredAndNotNull<Omit<DeclarativeElement<TagName, Inputs, State, EventsInit, HostClassKeys, CssVarKeys, SlotNames>, Exclude<keyof StaticDeclarativeElementProperties<any, any, any, any, any, any, any>, keyof HTMLElement>>, 'shadowRoot'>;
/**
 * The full definition for a declarative element.
 *
 * @category Internal
 */
export type DeclarativeElementDefinition<TagName extends CustomElementTagName = any, Inputs extends PropertyInitMapBase = any, State extends PropertyInitMapBase = any, EventsInit extends EventsInitMap = any, HostClassKeys extends BaseCssPropertyName<TagName> = any, CssVarKeys extends BaseCssPropertyName<TagName> = any, SlotNames extends ReadonlyArray<string> = any> = (new () => DeclarativeElementHost<TagName, Inputs, State, EventsInit, HostClassKeys, CssVarKeys, SlotNames>) & StaticDeclarativeElementProperties<TagName, Inputs, State, EventsInit, HostClassKeys, CssVarKeys, SlotNames> & {
    InstanceType: DeclarativeElementHost<TagName, Inputs, State, EventsInit, HostClassKeys, CssVarKeys, SlotNames>;
};
/**
 * Abstract class base for all declarative elements.
 *
 * @category Internal
 */
export declare abstract class DeclarativeElement<TagName extends CustomElementTagName = any, Inputs extends PropertyInitMapBase = any, State extends PropertyInitMapBase = any, EventsInit extends EventsInitMap = any, HostClassKeys extends BaseCssPropertyName<TagName> = any, CssVarKeys extends BaseCssPropertyName<TagName> = any, SlotNames extends ReadonlyArray<string> = any> extends LitElement {
    /**
     * Assign inputs to an element instantiation. Use only on the opening tag.
     *
     * @example
     *
     * ```ts
     * import {html} from 'element-vir';
     *
     * const myTemplate = html`
     *     <${MyElement.assign({input1: 'a', input2: 'b'})}></${MyElement}>
     * `;
     * ```
     */
    static readonly assign: StaticDeclarativeElementProperties<CustomElementTagName, PropertyInitMapBase, PropertyInitMapBase, EventsInitMap, BaseCssPropertyName<CustomElementTagName>, BaseCssPropertyName<CustomElementTagName>, ReadonlyArray<string>>['assign'];
    static readonly assignedInputs: PropertyInitMapBase | undefined;
    static readonly tagName: StaticDeclarativeElementProperties<CustomElementTagName, PropertyInitMapBase, PropertyInitMapBase, EventsInitMap, BaseCssPropertyName<CustomElementTagName>, BaseCssPropertyName<CustomElementTagName>, ReadonlyArray<string>>['tagName'];
    static readonly styles: StaticDeclarativeElementProperties<CustomElementTagName, PropertyInitMapBase, PropertyInitMapBase, EventsInitMap, BaseCssPropertyName<CustomElementTagName>, BaseCssPropertyName<CustomElementTagName>, ReadonlyArray<string>>['styles'];
    static readonly render: StaticDeclarativeElementProperties<CustomElementTagName, PropertyInitMapBase, PropertyInitMapBase, EventsInitMap, BaseCssPropertyName<CustomElementTagName>, BaseCssPropertyName<CustomElementTagName>, ReadonlyArray<string>>['render'];
    static readonly InputsType: StaticDeclarativeElementProperties<CustomElementTagName, PropertyInitMapBase, PropertyInitMapBase, EventsInitMap, BaseCssPropertyName<CustomElementTagName>, BaseCssPropertyName<CustomElementTagName>, ReadonlyArray<string>>['InputsType'];
    static readonly StateType: StaticDeclarativeElementProperties<CustomElementTagName, PropertyInitMapBase, PropertyInitMapBase, EventsInitMap, BaseCssPropertyName<CustomElementTagName>, BaseCssPropertyName<CustomElementTagName>, ReadonlyArray<string>>['StateType'];
    static readonly UpdateStateType: StaticDeclarativeElementProperties<CustomElementTagName, PropertyInitMapBase, PropertyInitMapBase, EventsInitMap, BaseCssPropertyName<CustomElementTagName>, BaseCssPropertyName<CustomElementTagName>, ReadonlyArray<string>>['UpdateStateType'];
    static readonly events: StaticDeclarativeElementProperties<CustomElementTagName, PropertyInitMapBase, PropertyInitMapBase, EventsInitMap, BaseCssPropertyName<CustomElementTagName>, BaseCssPropertyName<CustomElementTagName>, ReadonlyArray<string>>['events'];
    static readonly init: StaticDeclarativeElementProperties<CustomElementTagName, PropertyInitMapBase, PropertyInitMapBase, EventsInitMap, BaseCssPropertyName<CustomElementTagName>, BaseCssPropertyName<CustomElementTagName>, ReadonlyArray<string>>['init'];
    static readonly elementOptions: StaticDeclarativeElementProperties<CustomElementTagName, PropertyInitMapBase, PropertyInitMapBase, EventsInitMap, BaseCssPropertyName<CustomElementTagName>, BaseCssPropertyName<CustomElementTagName>, ReadonlyArray<string>>['elementOptions'];
    static readonly hostClasses: StaticDeclarativeElementProperties<CustomElementTagName, PropertyInitMapBase, PropertyInitMapBase, EventsInitMap, BaseCssPropertyName<CustomElementTagName>, BaseCssPropertyName<CustomElementTagName>, ReadonlyArray<string>>['hostClasses'];
    static readonly cssVars: StaticDeclarativeElementProperties<CustomElementTagName, PropertyInitMapBase, PropertyInitMapBase, EventsInitMap, BaseCssPropertyName<CustomElementTagName>, BaseCssPropertyName<CustomElementTagName>, ReadonlyArray<string>>['cssVars'];
    static readonly slotNames: StaticDeclarativeElementProperties<CustomElementTagName, PropertyInitMapBase, PropertyInitMapBase, EventsInitMap, BaseCssPropertyName<CustomElementTagName>, BaseCssPropertyName<CustomElementTagName>, ReadonlyArray<string>>['slotNames'];
    abstract _lastRenderError: Error | undefined;
    abstract _internalRenderCount: number;
    abstract _lastRenderedProps: Readonly<Pick<RenderParams<any, Inputs, State, any, any, any, any>, 'inputs' | 'state'>>;
    /**
     * Calls all destroy methods on all state properties, if they exist. This is automatically
     * called whenever the element is detached.
     */
    abstract destroy(): void;
    abstract render(): unknown;
    abstract readonly instanceState: State;
    abstract readonly observablePropertyListenerMap: ObservableListenerMap<State & Inputs>;
    abstract readonly instanceInputs: Inputs;
    /**
     * Used to assign inputs to the given element. This can be externally called as an API for
     * setting inputs on an element reference, though this is discouraged. Inputs should typically
     * be called using the `.assign()` method on an element definition inside of an HTML template.
     */
    abstract assignInputs(inputs: EmptyObject extends Required<Inputs> ? never : Partial<Inputs>): void;
    /** The element definition for this element instance. */
    abstract readonly definition: DeclarativeElementDefinition<TagName, Inputs, State, EventsInit, HostClassKeys, CssVarKeys, SlotNames>;
}
/**
 * The assign inputs method of a declarative element.
 *
 * @category Internal
 */
export type AssignMethod<TagName extends CustomElementTagName, Inputs extends PropertyInitMapBase> = IsAny<Inputs> extends true ? any : IsEmptyObject<Required<Inputs>> extends true ? (inputsObject: never) => never : (inputsObject: IsEmptyObject<Required<Inputs>> extends true ? never : Inputs) => MinimalDefinitionWithInputs<TagName>;
/**
 * All static properties on a declarative element. These all come from the element's definition.
 *
 * @category Internal
 */
export type StaticDeclarativeElementProperties<TagName extends CustomElementTagName, Inputs extends PropertyInitMapBase, State extends PropertyInitMapBase, EventsInit extends EventsInitMap, HostClassKeys extends BaseCssPropertyName<TagName>, CssVarKeys extends BaseCssPropertyName<TagName>, SlotNames extends ReadonlyArray<string>> = {
    /** Assign inputs to an element directly on its interpolated tag. */
    readonly assign: AssignMethod<TagName, Inputs>;
    assignedInputs: Inputs | undefined;
    /** Pass through the render callback for direct unit testability */
    readonly render: RenderCallback<TagName, Inputs, State, EventsInit, HostClassKeys, CssVarKeys, SlotNames>;
    readonly events: EventDescriptorMap<TagName, EventsInit>;
    readonly slotNames: SlotNameMap<SlotNames>;
    readonly init: DeclarativeElementInit<TagName, Inputs, State, EventsInit, HostClassKeys, CssVarKeys, SlotNames>;
    readonly elementOptions: DeclarativeElementDefinitionOptions;
    readonly InputsType: Inputs;
    readonly StateType: Readonly<State>;
    readonly UpdateStateType: UpdateStateCallback<State>;
    readonly hostClasses: HostClassNamesMap<string, HostClassKeys>;
    readonly cssVars: CssVars<TagName, CssVarKeys>;
    readonly tagName: TagName;
    readonly styles: CSSResult;
};
