import { Bundle as BundleModel, Bundle } from '@iotize/device-client.js/device/target-variable/bundle';
import { VariableInteraction } from '@iotize/device-client.js/device/target-variable/variable-interaction.interface';
import { DataManager as BaseDataManager } from '@iotize/ionic';
import { bundles as bundlesConfig } from "./tap-config";
import { Tap } from '@iotize/device-client.js/device';
import { BundleConfig, VariableConfig } from '@iotize/device-admin.js';
import { BodyConverter } from '@iotize/device-client.js/device/converter/import-adapter';

export type AppBundleConfig = BundleConfig & {
    variables: AppVariableConfig[]
};

export type AppVariableConfig = VariableConfig & {
    converter?: BodyConverter<any>
};

export namespace <%= classify(config.application.name) %> {

    interface Bundles {
        <% for (let bundle of bundles) { %>
            /**
             * Bundle  <%= bundle.name %>
             * Id: <%= bundle.id %>
             */
            <%= bundleName(bundle.name) %>: DataType.<%= classify(bundle.name) %>;
        <% } %>
    }

    export namespace DataType {
        <% for (let bundle of bundles) { %>
            export interface <%= classify(bundle.name) %> {
            <% for (variable of bundle.variables) { %>
                /**
                 * Variable  <%= variablenamify(variable.name) %>
                 * Id: <%= variable.id %>
                 */
                <%= variableName(variable.name) %>: <%= variableToType(variable) %>;
            <% } %>
            }
        <% } %>
    }

    export type VariableByType =  <% for (let [key, bundle] of bundles.entries()) { %> DataType.<%= classify(bundle.name) %><% if (!isLastItem(key, bundles)) { %> & <% } %> <% } %>;
    export type VariableKey = keyof <% for (let [key, bundle] of bundles.entries()) { %> DataType.<%= classify(bundle.name) %><% if (!isLastItem(key, bundles)) { %> & <% } %> <% } %>;

    export type BundleKey = keyof Bundles;
    export type BundleByType = Bundles;

    export interface Variables {
        <% for (let bundle of bundles) { %>
            <% for (let variable of bundle.variables) { %>
            /**
             * Variable  <%= variablenamify(variable.name) %>
             * Id: <%= variable.id %>
             */
            <%=  variableName(variable.name) %>: <%= variableToType(variable) %>;
            <% } %>
        <% } %>
    }

    export interface Bundle {
        <% for (let bundle of bundles) { %>
            <%= bundleName(bundle.name) %>: BundleModel<<%= classify(config.application.name) %>.DataType.<%= classify(bundle.name) %>>;
        <% } %>
    }

    export interface Data {
        bundles: Bundle
        Bundle<T extends BundleKey>(key: T): BundleModel<BundleByType[BundleKey]>;
        variables: Variables
        variable<T extends VariableKey>(key: T): VariableInteraction<VariableByType[T]>;
    }
    
    export class DataManager extends BaseDataManager<<%= classify(config.application.name) %>.VariableByType, <%= classify(config.application.name) %>.VariableKey, <%= classify(config.application.name) %>.BundleByType, <%= classify(config.application.name) %>.BundleKey>{
        static create(tap: Tap): DataManager {
            return new DataManager(
                tap,
                BaseDataManager.createDataFromSchemaConfig(tap, bundlesConfig) as any
            )
        }
    }

}
