export const fieldClass =
    'h-9 w-full rounded-md border border-input bg-background px-3 text-sm outline-none transition-colors placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50';

export function asList(value: unknown): Record<string, unknown>[] {
    if (!Array.isArray(value)) {
        return [];
    }

    return value.filter(
        (row): row is Record<string, unknown> =>
            Boolean(row) && typeof row === 'object' && !Array.isArray(row),
    );
}

export function asStrings(value: unknown): string[] {
    if (Array.isArray(value)) {
        return value.filter((item) => typeof item === 'string' && item !== '');
    }

    if (value && typeof value === 'object') {
        return Object.keys(value as Record<string, unknown>).filter((key) =>
            key.toLowerCase().includes('php'),
        );
    }

    return [];
}

export function text(row: Record<string, unknown>, keys: string[]): string {
    for (const key of keys) {
        const value = row[key];

        if (value != null && value !== '' && typeof value !== 'object') {
            return String(value);
        }
    }

    return '';
}

export function generateSecret(length = 16): string {
    const chars =
        'abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789!@#$%';
    const bytes = new Uint8Array(length);
    crypto.getRandomValues(bytes);

    return Array.from(bytes, (byte) => chars[byte % chars.length]).join('');
}

function parseAmount(value: unknown): number | null {
    if (value == null || value === '') {
        return null;
    }

    if (typeof value === 'number') {
        return Number.isFinite(value) ? value : null;
    }

    const raw = String(value).trim().toLowerCase();

    if (
        raw === 'unlimited' ||
        raw === '∞' ||
        raw === 'none' ||
        raw === 'null'
    ) {
        return null;
    }

    const match = raw.match(/^([\d.,]+)\s*([kmgt]i?b?)?/);

    if (!match) {
        return null;
    }

    const amount = Number.parseFloat(match[1].replace(',', '.'));

    if (Number.isNaN(amount)) {
        return null;
    }

    const unit = match[2] ?? 'm';

    if (unit.startsWith('g')) {
        return amount * 1024;
    }

    if (unit.startsWith('k')) {
        return amount / 1024;
    }

    if (unit.startsWith('t')) {
        return amount * 1024 * 1024;
    }

    return amount;
}

export function formatMb(value: number | null): string {
    if (value == null) {
        return '∞';
    }

    if (value >= 1024) {
        return `${(value / 1024).toLocaleString('fr-FR', { maximumFractionDigits: 1 })} Go`;
    }

    return `${value.toLocaleString('fr-FR', { maximumFractionDigits: 1 })} Mo`;
}

export function quotaView(
    used: unknown,
    limit: unknown,
): { label: string; percent: number | null } {
    const usedMb = parseAmount(used) ?? 0;
    const limitMb = parseAmount(limit);

    if (limitMb == null || limitMb <= 0) {
        return { label: `${formatMb(usedMb)} / ∞`, percent: null };
    }

    return {
        label: `${formatMb(usedMb)} / ${formatMb(limitMb)}`,
        percent: Math.min(100, Math.round((usedMb / limitMb) * 100)),
    };
}

export function mailboxQuotaLabel(
    usedMb: unknown,
    quotaMb: unknown,
    unlimited: unknown,
): { label: string; percent: number | null } {
    const used = typeof usedMb === 'number' ? usedMb : parseAmount(usedMb) ?? 0;
    const limit =
        unlimited === true || unlimited === 1
            ? null
            : typeof quotaMb === 'number'
              ? quotaMb
              : parseAmount(quotaMb);

    return quotaView(used, limit);
}
