import crypto from 'crypto';
import { config } from '../config';

export function hashIp(ip: string): string {
  return crypto.createHash('sha256').update(`${ip}:${config.analytics.ipSalt}`).digest('hex');
}

export function hashToken(token: string): string {
  return crypto.createHash('sha256').update(`${token}:${config.analytics.sessionSecret}`).digest('hex');
}

export function randomToken(bytes = 32): string {
  return crypto.randomBytes(bytes).toString('hex');
}

export function normalizePath(path: string): string {
  try {
    const url = new URL(path, config.origin);
    return url.pathname.slice(0, 500) || '/';
  } catch {
    return path.slice(0, 500) || '/';
  }
}

export type DateRangeKey = 'today' | 'yesterday' | '7d' | '30d' | 'custom';

export interface ResolvedRange {
  key: DateRangeKey;
  from: Date;
  to: Date;
}

const WARSAW = config.analytics.timezone;

function warsawParts(date: Date): { y: number; m: number; d: number; h: number } {
  const fmt = new Intl.DateTimeFormat('en-CA', {
    timeZone: WARSAW,
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    hour12: false,
  });
  const parts = fmt.formatToParts(date);
  const get = (type: string) => Number(parts.find((p) => p.type === type)?.value ?? 0);
  return { y: get('year'), m: get('month'), d: get('day'), h: get('hour') };
}

export function startOfDayWarsaw(date: Date): Date {
  const { y, m, d } = warsawParts(date);
  return new Date(Date.UTC(y, m - 1, d, 0, 0, 0, 0));
}

export function endOfDayWarsaw(date: Date): Date {
  const { y, m, d } = warsawParts(date);
  return new Date(Date.UTC(y, m - 1, d, 23, 59, 59, 999));
}

export function resolveRange(
  range?: string,
  fromStr?: string,
  toStr?: string,
): ResolvedRange {
  const now = new Date();
  const key = (range ?? '7d') as DateRangeKey;

  if (key === 'today') {
    return { key, from: startOfDayWarsaw(now), to: endOfDayWarsaw(now) };
  }
  if (key === 'yesterday') {
    const y = new Date(now.getTime() - 24 * 60 * 60 * 1000);
    return { key, from: startOfDayWarsaw(y), to: endOfDayWarsaw(y) };
  }
  if (key === '7d') {
    return { key, from: new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000), to: now };
  }
  if (key === '30d') {
    return { key, from: new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000), to: now };
  }
  if (key === 'custom' && fromStr && toStr) {
    return { key, from: new Date(fromStr), to: new Date(toStr) };
  }
  return { key: '7d', from: new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000), to: now };
}

export function deviceFromUa(ua?: string | null): string {
  if (!ua) return 'unknown';
  const s = ua.toLowerCase();
  if (/mobile|android|iphone|ipad|ipod/.test(s)) return 'mobile';
  if (/tablet/.test(s)) return 'tablet';
  return 'desktop';
}
