import * as i0 from '@angular/core';
import { inject, Injectable } from '@angular/core';
import { AXPEntityService } from '@acorex/platform/layout/entity';
import { RootConfig } from '@acorex/modules/tenant-management';
import { RootConfig as RootConfig$1 } from '@acorex/modules/subscription-management';
import { RootConfig as RootConfig$2 } from '@acorex/modules/application-management';

//#endregion
class GetTenantRegistrationTimelineQuery {
    constructor() {
        this.entityService = inject(AXPEntityService);
        this.tenantService = this.entityService
            .withEntity(`${RootConfig.module.name}.${RootConfig.entities.tenant.name}`)
            .data();
        this.tenantUserService = this.entityService
            .withEntity(`${RootConfig.module.name}.${RootConfig.entities.tenantUser.name}`)
            .data();
        this.subscriptionService = this.entityService
            .withEntity(`${RootConfig$1.module.name}.${RootConfig$1.entities.subscription.name}`)
            .data();
        this.planItemService = this.entityService
            .withEntity(`${RootConfig$1.module.name}.${RootConfig$1.entities.subscriptionPlanItem.name}`)
            .data();
        this.applicationService = this.entityService
            .withEntity(`${RootConfig$2.module.name}.${RootConfig$2.entities.application.name}`)
            .data();
    }
    async fetch(input) {
        // Extract filters from AXPFilterClause format
        const extractedFilters = this.extractTenantFilters(input.filters);
        const filterLogic = input.filters?.logic || input.logic || 'and';
        // Separate custom filters from entity filters
        const entityFilters = [];
        let dateRangeFilter;
        if (extractedFilters && extractedFilters.length > 0) {
            for (const filter of extractedFilters) {
                if (filter.field === 'dateRange') {
                    dateRangeFilter = filter.value;
                }
                else {
                    entityFilters.push(filter);
                }
            }
        }
        // Get all tenants
        const tenantsResult = await this.tenantService.query({
            skip: 0,
            take: 10000,
            filter: entityFilters.length > 0
                ? {
                    logic: filterLogic,
                    filters: entityFilters,
                }
                : undefined,
        });
        let tenants = tenantsResult.items.filter((t) => t.registrationDate);
        // Apply date range filter if provided
        if (dateRangeFilter) {
            tenants = this.applyDateRangeFilter(tenants, dateRangeFilter);
        }
        // Get all tenant users for counting
        const tenantUsersResult = await this.tenantUserService.query({
            skip: 0,
            take: 10000,
        });
        const tenantUsers = tenantUsersResult.items;
        // Get all subscriptions for counting
        const subscriptionsResult = await this.subscriptionService.query({
            skip: 0,
            take: 10000,
        });
        const subscriptions = subscriptionsResult.items.filter((s) => s.subscriberType === 'Tenant');
        // Get all plan items and applications for application counting
        const planItemsResult = await this.planItemService.query({
            skip: 0,
            take: 10000,
        });
        const planItems = planItemsResult.items;
        const applicationsResult = await this.applicationService.query({
            skip: 0,
            take: 10000,
        });
        const applications = applicationsResult.items;
        // Get application counts for tenants
        const applicationCounts = await this.getApplicationCountsForTenants(tenants.map((t) => t.id), subscriptions, planItems, applications);
        // Build results
        const results = [];
        for (const tenant of tenants) {
            if (!tenant.registrationDate)
                continue;
            const registrationDate = new Date(tenant.registrationDate);
            // Extract time period info
            const year = registrationDate.getFullYear();
            const month = registrationDate.getMonth() + 1;
            const monthName = registrationDate.toLocaleString('en-US', { month: 'long' });
            const quarter = Math.ceil(month / 3);
            const quarterName = `Q${quarter}`;
            // Count users for this tenant
            const userCount = tenantUsers.filter((tu) => tu.tenantId === tenant.id).length;
            // Count subscriptions for this tenant
            const subscriptionCount = subscriptions.filter((s) => s.subscriberId === tenant.id).length;
            // Get application count
            const applicationCount = applicationCounts.get(tenant.id) || 0;
            results.push({
                tenantId: tenant.id,
                tenantName: tenant.title,
                registrationDate: registrationDate,
                registrationDateStr: registrationDate.toISOString(),
                status: tenant.statusId || 'Unknown',
                country: tenant.country?.title,
                userCount: userCount,
                applicationCount: applicationCount,
                subscriptionCount: subscriptionCount,
                month: monthName,
                monthNumber: month,
                quarter: quarterName,
                year: year,
            });
        }
        // Apply sorting if provided
        if (input.sort && input.sort.length > 0) {
            results.sort((a, b) => {
                for (const sortField of input.sort) {
                    const field = sortField.field;
                    const aValue = a[field];
                    const bValue = b[field];
                    const dir = sortField.dir === 'asc' ? 1 : -1;
                    if (aValue === undefined && bValue === undefined)
                        continue;
                    if (aValue === undefined)
                        return 1 * dir;
                    if (bValue === undefined)
                        return -1 * dir;
                    // Handle date comparison
                    if (field === 'registrationDate') {
                        const aDate = a.registrationDate.getTime();
                        const bDate = b.registrationDate.getTime();
                        if (aDate < bDate)
                            return -1 * dir;
                        if (aDate > bDate)
                            return 1 * dir;
                        continue;
                    }
                    if (aValue < bValue)
                        return -1 * dir;
                    if (aValue > bValue)
                        return 1 * dir;
                }
                return 0;
            });
        }
        else {
            // Default sort by registration date descending (newest first)
            results.sort((a, b) => {
                return b.registrationDate.getTime() - a.registrationDate.getTime();
            });
        }
        // Apply pagination
        const skip = input.skip || 0;
        const take = input.take || 10;
        const total = results.length;
        const items = results.slice(skip, skip + take);
        return {
            items,
            total,
        };
    }
    //#region ----   Helper Methods   ----
    /**
     * Get application counts for tenants
     */
    async getApplicationCountsForTenants(tenantIds, subscriptions, planItems, applications) {
        const counts = new Map();
        for (const tenantId of tenantIds) {
            const tenantSubscriptions = subscriptions.filter((s) => s.subscriberId === tenantId);
            // Get unique applications through subscriptions → plans → plan items → editions → applications
            const applicationSet = new Set();
            for (const subscription of tenantSubscriptions) {
                if (!subscription.planId)
                    continue;
                // Get plan items for this plan
                const planPlanItems = planItems.filter((pi) => pi.planId === subscription.planId);
                for (const planItem of planPlanItems) {
                    if (!planItem.editionId)
                        continue;
                    // Find applications that have this edition
                    for (const application of applications) {
                        if (application.editionIds && application.editionIds.includes(planItem.editionId)) {
                            applicationSet.add(application.id);
                        }
                    }
                }
            }
            counts.set(tenantId, applicationSet.size);
        }
        return counts;
    }
    //#endregion
    //#region ----   Filter Extraction   ----
    /**
     * Extract tenant-specific filters from AXPFilterClause format
     * Maps report parameter paths to tenant entity field names
     */
    extractTenantFilters(parameters) {
        const filters = [];
        const paramsAny = parameters;
        if (!paramsAny?.filters || !Array.isArray(paramsAny.filters)) {
            return filters;
        }
        for (const filter of paramsAny.filters) {
            if (!filter?.field || filter?.value === undefined || filter?.value === null) {
                continue;
            }
            const field = filter.field;
            const value = filter.value;
            const operator = filter.operator || { type: 'equal' };
            // Handle tenant-specific field mappings
            if (field === 'tenantId') {
                // Tenant ID filter - can be array of IDs or single ID
                if (Array.isArray(value) && value.length > 0) {
                    filters.push({
                        field: 'id',
                        operator: { type: 'in' },
                        value: value,
                    });
                }
                else if (value) {
                    filters.push({
                        field: 'id',
                        operator: { type: 'equal' },
                        value: value,
                    });
                }
            }
            else if (field === 'statusId') {
                // Status filter - skip 'all' value
                if (value && value !== 'all') {
                    filters.push({
                        field: 'statusId',
                        operator: { type: 'equal' },
                        value: value,
                    });
                }
            }
            else if (field === 'dateRange') {
                // Date range filter - custom logic handled in query
                filters.push({
                    field: 'dateRange',
                    operator: { type: 'equal' },
                    value: value,
                });
            }
            else {
                // Direct field mapping
                filters.push({
                    field: field,
                    operator: operator,
                    value: value,
                });
            }
        }
        return filters;
    }
    //#endregion
    //#region ----   Custom Filter Handlers   ----
    /**
     * Apply date range filter to tenants
     */
    applyDateRangeFilter(tenants, dateRange) {
        if (!dateRange || !dateRange.start || !dateRange.end) {
            return tenants;
        }
        const startDate = new Date(dateRange.start);
        const endDate = new Date(dateRange.end);
        endDate.setHours(23, 59, 59, 999);
        return tenants.filter((tenant) => {
            if (!tenant.registrationDate)
                return false;
            const regDate = new Date(tenant.registrationDate);
            return regDate >= startDate && regDate <= endDate;
        });
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: GetTenantRegistrationTimelineQuery, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: GetTenantRegistrationTimelineQuery, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: GetTenantRegistrationTimelineQuery, decorators: [{
            type: Injectable,
            args: [{
                    providedIn: 'root',
                }]
        }] });

export { GetTenantRegistrationTimelineQuery };
//# sourceMappingURL=acorex-connectivity-mock-get-tenant-registration-timeline.query-CfDjhtaC.mjs.map
