import {Type} from '@angular/core';
import {Routes} from '@angular/router';

import {Editor, TreeUtils} from 'm2-core';
import {CdDemoComponent} from './components/content/abstract/CdDemoComponent';
import {CdNode, CdNodeType} from './components/docs-tree/CdNode';
import {CdNodeCardDemoComponent} from './components/content/demo/lazy/node-card/cd-node-card-demo.component';
import {CdNodesTreeDemoComponent} from './components/content/demo/lazy/nodes-tree/cd-nodes-tree-demo.component';
import {CdItemCardDemoComponent} from './components/content/demo/lazy/item-card/cd-item-card-demo.component';
import {CdItemsTableDemoComponent} from './components/content/demo/lazy/items-table/cd-items-table-demo.component';
import {CdTxDetailsDemoComponent} from './components/content/demo/lazy/tx-details/cd-tx-details-demo.component';
import {CdJournalDemoComponent} from './components/content/demo/lazy/journal/cd-journal-demo.component';
import {CdCodeEditorDemoComponent} from './components/content/demo/lazy/code-editor/cd-code-editor-demo.component';
import {CdGlobalModalsServiceDemoComponent} from './components/content/demo/service/system/global-modals/cd-global-modals-service-demo.component';
import {CdNotificationServiceDemoComponent} from './components/content/demo/service/system/notification/cd-notification-service-demo.component';
import {CdTouchScrollerDemoComponent} from './components/content/demo/directive/cd-touch-scroller-demo.component';
import {CdActionsServiceDemoComponent} from './components/content/demo/service/system/global-modals/cd-actions-service-demo.component';
import {CdPluginSupportServiceDemoComponent} from './components/content/demo/service/plugin/cd-plugin-support-service-demo.component';
import {CdTransactionButtonDemoComponent} from './components/content/demo/transaction/button/cd-transaction-button-demo.component';
import {CdApplicationAttributesDemoComponent} from './components/content/demo/application/attribute/cd-application-attributes-demo.component';
import {CdLayerServiceDemoComponent} from './components/content/demo/service/system/layer/cd-layer-service-demo.component';
import {CdTabsDemoComponent} from './components/content/demo/ui-elements/tabs/cd-tabs-demo.component';
import {CdCardGroupDemoComponent} from './components/content/demo/card/group/cd-card-group-demo.component';
import {CdPropertyRowDemoComponent} from './components/content/demo/card/property-row/cd-property-row-demo.component';
import {CdItemCardRowDemoComponent} from './components/content/demo/card/item-row/cd-item-card-row-demo.component';
import {CdTabsChildDemoComponent} from './components/content/demo/ui-elements/tabs/cd-tabs-child-demo.component';
import {CdNodesTreeChildDemoComponent} from './components/content/demo/lazy/nodes-tree/cd-nodes-tree-child-demo.component';


export function getContentNodes(): CdNode[] {
    TreeUtils.doForAll(CD_NODES, n => {
        n.id = formCdNodeId(n.routerLink, n.fragment);
        n.isExpanded = n.children?.length > 0;
    });
    return CD_NODES;
}

export function formCdNodeId(routerLink: string, fragment?: string): string {
    return `${routerLink}#${fragment ?? ''}`;
}

export function getContentRoutesData(): [string, Type<CdDemoComponent | Editor>, CdNodeType, Routes?][] {
    return TreeUtils.findNodes(CD_NODES, n => !!n.componentClass, false)
        .map(n => [n.routerLink, n.componentClass, n.type, n.childRoutes]);
}

export function getDefaultContentRouterLink(): string {
    return CD_NODES[0].routerLink;
}

export function getDocsPath(routerLink: string, fragment?: string): string {
    const node = TreeUtils.findNode(CD_NODES, n => n.routerLink === routerLink && n.fragment == fragment,
            n => n.children);
    return node?.node.docsPath || '';
}


/**
 * Unfortunately, Angular AoT compiler doesn't allow form list of components to declare dynamically,
 * so we have to specify them explicitly in array below:(
 */
// export function getContentComponentsToDeclare(): Type<any>[] {
//     return CD_NODES.reduce((res, c) => {...}, []);
// }
export const CD_CONTENT_COMPONENTS: Type<any>[] = [
    CdNodesTreeDemoComponent, CdNodesTreeChildDemoComponent,
    CdNodeCardDemoComponent,
    CdItemsTableDemoComponent,
    CdItemCardDemoComponent,
    CdCodeEditorDemoComponent,
    CdJournalDemoComponent,
    CdTxDetailsDemoComponent,
    CdGlobalModalsServiceDemoComponent,
    CdActionsServiceDemoComponent,
    CdNotificationServiceDemoComponent,
    CdTouchScrollerDemoComponent,
    CdPluginSupportServiceDemoComponent,
    CdTransactionButtonDemoComponent,
    CdApplicationAttributesDemoComponent,
    CdLayerServiceDemoComponent,
    CdTabsDemoComponent, CdTabsChildDemoComponent,
    CdCardGroupDemoComponent,
    CdPropertyRowDemoComponent,
    CdItemCardRowDemoComponent,
];


/**
 * Since this file is used for generating code examples, there are some rules to follow:
 *  1. routerLink and componentClass must be specified on the same line
 *  2. demo code is localed within single file, fragments can be marked via special comments:
 *     // region <fragment>
 *        ...
 *     // endregion <fragment>
 *  3. all CdNodes must be described inline in CD_NODES array, no refs to external arrays are allowed
 */
const CD_NODES: CdNode[] = [
    // Lazy components
    {
        displayName: $localize`Дерево групп`,
        type: CdNodeType.component,
        routerLink: 'nodesTree', componentClass: CdNodesTreeDemoComponent,
        childRoutes: [
            { path: ':nodeId', component: CdNodesTreeChildDemoComponent }
        ],
        tags: ['nodes-tree'],
        docsPath: '/components/NodesTreeComponent.html'

    },
    {
        displayName: $localize`Карточка группы`,
        type: CdNodeType.component,
        routerLink: 'nodeCard', componentClass: CdNodeCardDemoComponent,
        tags: ['node-card-lazy'],
        docsPath: '/directives/NodeCardLazyDirective.html'
    },
    {
        displayName: $localize`Таблица позиций`,
        type: CdNodeType.component,
        routerLink: 'itemsTable', componentClass: CdItemsTableDemoComponent,
        tags: ['items-datatable'],
        docsPath: '/components/ItemsDatatableComponent.html'
    },
    {
        displayName: $localize`Карточка позиции`,
        type: CdNodeType.component,
        routerLink: 'itemCard', componentClass: CdItemCardDemoComponent,
        tags: ['item-card-lazy'],
        docsPath: '/directives/ItemCardLazyDirective.html'
    },
    {
        displayName: $localize`Редактор кода`,
        type: CdNodeType.component,
        routerLink: 'codeEditor', componentClass: CdCodeEditorDemoComponent,
        tags: ['code-editor-lazy'],
        docsPath: '/directives/CodeEditorLazyDirective.html'
    },
    {
        displayName: $localize`Журнал`,
        type: CdNodeType.component,
        routerLink: 'journal', componentClass: CdJournalDemoComponent,
        tags: ['journal-editor-lazy'],
        docsPath: '/directives/JournalEditorLazyDirective.html'
    },
    {
        displayName: $localize`Детализация пакета изменений`,
        type: CdNodeType.component,
        routerLink: 'txDetails', componentClass: CdTxDetailsDemoComponent,
        tags: ['tx-details-lazy', 'transaction-details'],
        docsPath: '/directives/TransactionDetailsLazyDirective.html'
    },

    // Services
    {
        displayName: $localize`Сервис модальных окон`,
        type: CdNodeType.service,
        routerLink: 'globalModalsService', componentClass: CdGlobalModalsServiceDemoComponent,
        fragment: 'demoComponent',
        tags: ['GlobalModalsService'],
        docsPath: '/injectables/GlobalModalsService.html',
        children: [
            // Selectors
            {
                displayName: $localize`Диалог выбора групп`,
                type: CdNodeType.service,
                routerLink: 'globalModalsService',
                fragment: 'nodesSelector',
                tags: ['NodesSelectorComponent'],
                docsPath: '/classes/NodesSelectorConfig.html'
            },
            {
                displayName: $localize`Диалог выбора группы классификатора`,
                type: CdNodeType.service,
                routerLink: 'globalModalsService',
                fragment: 'classifierSelector',
                tags: ['ClassifierSelectorComponent'],
                docsPath: '/classes/ClassifierSelectorConfig.html'
            },
            // Formula
            {
                displayName: $localize`Редактор формул`,
                type: CdNodeType.service,
                routerLink: 'globalModalsService',
                fragment: 'formulaEditor',
                tags: ['FormulaEditorComponent'],
                docsPath: '/classes/FormulaEditorConfig.html'
            },
            // Node
            {
                displayName: $localize`Диаграмма взаимосвязей между группами`,
                type: CdNodeType.service,
                routerLink: 'globalModalsService',
                fragment: 'nodeRelations',
                tags: ['NodeRelationsDialogComponent'],
                docsPath: '/interfaces/NodeRelationsDialogConfig.html'
            },
            // Item
            {
                displayName: $localize`Генератор позиций`,
                type: CdNodeType.service,
                routerLink: 'globalModalsService',
                fragment: 'itemGenerator',
                tags: ['ItemGeneratorComponent'],
                docsPath: '/interfaces/ItemGeneratorConfig.html'
            },
            {
                displayName: $localize`Версии позиции`,
                type: CdNodeType.service,
                routerLink: 'globalModalsService',
                fragment: 'itemVersions',
                tags: ['ItemVersionsDialogComponent'],
                docsPath: '/classes/ItemVersionsDialogConfig.html'
            },
            // Applications
            {
                displayName: $localize`Редактор заявки`,
                type: CdNodeType.service,
                routerLink: 'globalModalsService',
                fragment: 'applicationEditor',
                tags: ['ApplicationEditorComponent'],
                docsPath: '/interfaces/ApplicationEditorConfig.html'
            },
            {
                displayName: $localize`Редактор группы заявок`,
                type: CdNodeType.service,
                routerLink: 'globalModalsService',
                fragment: 'applicationGroupEditor',
                tags: ['ApplicationsGroupEditorComponent'],
                docsPath: '/interfaces/ApplicationsGroupEditorConfig.html'
            },
            // File selector
            {
                displayName: $localize`Выбор файлов`,
                type: CdNodeType.service,
                routerLink: 'globalModalsService',
                fragment: 'fileSelector',
                tags: ['FileSelectorConfig', 'FileSelectorComponent'],
                docsPath: '/interfaces/FileSelectorConfig.html'
            },
        ]
    },
    {
        displayName: $localize`Сервис слоев`,
        type: CdNodeType.service,
        routerLink: 'layerService', componentClass: CdLayerServiceDemoComponent,
        fragment: 'demoComponent',
        tags: ['LayerService'],
        docsPath: '/injectables/LayerService.html',
        children: [
            {
                displayName: $localize`Выбор заявок`,
                type: CdNodeType.service,
                routerLink: 'layerService',
                fragment: 'applicationSelector',
                tags: ['ApplicationSelectorConfig'],
                docsPath: '/classes/ApplicationSelectorConfig.html'
            },
            {
                displayName: $localize`Выбор пользователей`,
                type: CdNodeType.service,
                routerLink: 'layerService',
                fragment: 'userSelector',
                tags: ['UserSelectorConfig'],
                docsPath: '/classes/UserSelectorConfig.html'
            },
            {
                displayName: $localize`Выбор импортируемых позиций`,
                type: CdNodeType.service,
                routerLink: 'layerService',
                fragment: 'sourceRecordSelector',
                tags: ['SourceRecordSelectorConfig'],
                docsPath: '/classes/SourceRecordSelectorConfig.html'
            },
            {
                displayName: $localize`Выбор групп и позиций`,
                type: CdNodeType.service,
                routerLink: 'layerService',
                fragment: 'classifiableSelector',
                tags: ['ClassifiableSelectorConfig'],
                docsPath: '/classes/ClassifiableSelectorConfig.html'
            },
            {
                displayName: $localize`Произвольная страница`,
                type: CdNodeType.service,
                routerLink: 'layerService',
                fragment: 'layerConfig',
                tags: ['LayerConfig'],
                docsPath: '/classes/LayerConfig.html'
            }
        ]
    },
    {
        displayName: $localize`Подтверждение действия`,
        type: CdNodeType.service,
        routerLink: 'actionsService', componentClass: CdActionsServiceDemoComponent,
        fragment: 'demoComponent',
        tags: ['ActionsService'],
        docsPath: '/injectables/ActionsService.html',
        children: [
            {
                displayName: $localize`Подтверждение действия`,
                type: CdNodeType.service,
                routerLink: 'actionsService',
                fragment: 'confirmAction',
                tags: ['confirm'],
                docsPath: '/injectables/ActionsService.html#confirm'
            },
            {
                displayName: $localize`Запрос комментария`,
                type: CdNodeType.service,
                routerLink: 'actionsService',
                fragment: 'prompt',
                tags: ['prompt'],
                docsPath: '/injectables/ActionsService.html#prompt'
            }
        ]
    },
    {
        displayName: $localize`Сервис уведомлений`,
        type: CdNodeType.service,
        routerLink: 'notificationService', componentClass: CdNotificationServiceDemoComponent,
        tags: ['NotificationService'],
        docsPath: '/injectables/NotificationService.html'
    },
    {
        displayName: $localize`Сервис поддержки расширений`,
        type: CdNodeType.service,
        routerLink: 'pluginSupportService', componentClass: CdPluginSupportServiceDemoComponent,
        tags: ['PluginSupportService'],
        docsPath: '/injectables/PluginSupportService.html'
    },

    /***** Directives *****/
    {
        displayName: $localize`Эффект Touch Scroll`,
        type: CdNodeType.directive,
        routerLink: 'touchScroller', componentClass: CdTouchScrollerDemoComponent,
        tags: ['TouchScrollerDirective'],
        docsPath: '/directives/TouchScrollerDirective.html'
    },

    /***** Transactions *****/
    {
        displayName: $localize`Управление пакетами изменений`,
        type: CdNodeType.component,
        routerLink: 'transactionBtn', componentClass: CdTransactionButtonDemoComponent,
        tags: ['TransactionButtonComponent'],
        docsPath: '/components/TransactionButtonComponent.html'
    },

    /***** Applications *****/
    {
        displayName: $localize`Атрибуты заявки`,
        type: CdNodeType.component,
        routerLink: 'applicationAttributeValue', componentClass: CdApplicationAttributesDemoComponent,
        fragment: 'demoComponent',
        tags: ['ApplicationAttributeValueComponent, ApplicationAttributesSingleComponent'],
        docsPath: '/components/ApplicationAttributeValueComponent.html'
    },

    /***** UI elements *****/
    {
        displayName: $localize`Вкладки`,
        type: CdNodeType.component,
        routerLink: 'tabs', componentClass: CdTabsDemoComponent,
        childRoutes: [
            { path: ':tabId', component: CdTabsChildDemoComponent }
        ],
        tags: ['TabsComponent'],
        docsPath: '/components/TabsComponent.html'
    },

    /***** Card *****/
    {
        displayName: $localize`Карточка`,
        type: CdNodeType.group,
        routerLink: 'cardGroup', componentClass: CdCardGroupDemoComponent,
        tags: ['Card'],
        docsPath: '/',
        children: [
            {
                displayName: $localize`Атрибуты позиции`,
                type: CdNodeType.component,
                routerLink: 'itemCardRow', componentClass: CdItemCardRowDemoComponent,
                tags: ['ItemCardRowComponent'],
                docsPath: '/components/ItemCardRowComponent.html'
            },
            {
                displayName: $localize`Произвольные иерархические данные`,
                type: CdNodeType.component,
                routerLink: 'propertyRow', componentClass: CdPropertyRowDemoComponent,
                tags: ['PropertyRow'],
                docsPath: '/classes/PropertyRow.html'
            },
        ]
    },
];
