import type { Database } from 'bun:sqlite';
import { AllowedGroups } from './allowed-groups';
import { GroupSyncService } from './group-sync';
import { normalizeWhatsAppId, isGroupId } from '../utils/whatsapp';
import { Metrics } from './metrics';
import { TaskService } from '../tasks/service';
import { codeId, formatDDMM } from '../utils/formatting';
import { getDb } from '../db/locator';

type AdminContext = {
  sender: string;      // normalized user id (digits only)
  groupId: string;     // raw JID (group or DM)
  message: string;     // raw message text
};

type AdminResponse = { recipient: string; message: string };

export class AdminService {
  

  private static admins(): Set<string> {
    const raw = String(process.env.ADMIN_USERS || '');
    const set = new Set<string>();
    for (const token of raw.split(',').map(s => s.trim()).filter(Boolean)) {
      const n = normalizeWhatsAppId(token);
      if (n) set.add(n);
    }
    return set;
  }

  static getAdmins(): string[] {
    return Array.from(this.admins());
  }

  private static isAdmin(userId: string | null | undefined): boolean {
    const n = normalizeWhatsAppId(userId || '');
    if (!n) return false;
    return this.admins().has(n);
  }

  private static help(): string {
    return [
      'Comandos de administración:',
      '- /admin pendientes (alias: pending, pend)',
      '- /admin habilitar-aquí (alias: enable)',
      '- /admin deshabilitar-aquí (alias: disable)',
      '- /admin allow all (alias: habilitar-todos, enable all)',
      '- /admin allow-group <group_id@g.us> (alias: allow)',
      '- /admin block-group <group_id@g.us> (alias: block)',
      '- /admin sync-grupos (alias: group-sync, syncgroups)',
      '- /admin ver todos (alias: listar, list all)',
    ].join('\n');
  }

  static async handle(ctx: AdminContext): Promise<AdminResponse[]> {
    const sender = normalizeWhatsAppId(ctx.sender);
    if (!sender) return [];

    if (!this.isAdmin(sender)) {
      return [{ recipient: sender, message: '🚫 No estás autorizado para usar /admin.' }];
    }

    const instanceDb = getDb() as Database;
    // Asegurar acceso a la misma DB para AllowedGroups

    const raw = String(ctx.message || '').trim();
    const lower = raw.toLowerCase();
    if (!lower.startsWith('/admin')) {
      return [];
    }

    const rest = lower.slice('/admin'.length).trim();

    // /admin pendientes
    if (rest === 'pendientes' || rest === 'pending' || rest === 'pend') {
      const rows = AllowedGroups.listByStatus('pending');
      if (!rows || rows.length === 0) {
        return [{ recipient: sender, message: '✅ No hay grupos pendientes.' }];
      }
      const list = rows.map(r => `- ${r.group_id}${r.label ? ` (${r.label})` : ''}`).join('\n');
      return [{
        recipient: sender,
        message: `Grupos pendientes (${rows.length}):\n${list}`
      }];
    }

    // /admin habilitar-aquí
    if (rest === 'habilitar-aquí' || rest === 'habilitar-aqui' || rest === 'enable') {
      if (!isGroupId(ctx.groupId)) {
        return [{ recipient: sender, message: 'ℹ️ Este comando se debe usar dentro de un grupo.' }];
      }
      const changed = AllowedGroups.setStatus(ctx.groupId, 'allowed');
      try { if (changed) Metrics.inc('admin_actions_total_allow'); } catch {}
      return [{ recipient: sender, message: `✅ Grupo habilitado: ${ctx.groupId}` }];
    }

    // /admin deshabilitar-aquí
    if (rest === 'deshabilitar-aquí' || rest === 'deshabilitar-aqui' || rest === 'disable') {
      if (!isGroupId(ctx.groupId)) {
        return [{ recipient: sender, message: 'ℹ️ Este comando se debe usar dentro de un grupo.' }];
      }
      const changed = AllowedGroups.setStatus(ctx.groupId, 'blocked');
      try { if (changed) Metrics.inc('admin_actions_total_block'); } catch {}
      return [{ recipient: sender, message: `✅ Grupo deshabilitado: ${ctx.groupId}` }];
    }

    // /admin archivar-aquí
    if (rest === 'archivar-aquí' || rest === 'archivar-aqui' || rest === 'archive here' || rest === 'archive-aqui' || rest === 'archive-aquí') {
      if (!isGroupId(ctx.groupId)) {
        return [{ recipient: sender, message: 'ℹ️ Este comando se debe usar dentro de un grupo.' }];
      }
      instanceDb.transaction(() => {
        instanceDb.prepare(`
          UPDATE groups
          SET active = 0, archived = 1, last_verified = strftime('%Y-%m-%d %H:%M:%f','now')
          WHERE id = ?
        `).run(ctx.groupId);
        instanceDb.prepare(`
          UPDATE calendar_tokens
          SET revoked_at = strftime('%Y-%m-%d %H:%M:%f','now')
          WHERE group_id = ? AND revoked_at IS NULL
        `).run(ctx.groupId);
        instanceDb.prepare(`
          UPDATE group_members
          SET is_active = 0
          WHERE group_id = ? AND is_active = 1
        `).run(ctx.groupId);
      })();
      try { AllowedGroups.setStatus(ctx.groupId, 'blocked'); } catch {}
      return [{ recipient: sender, message: `📦 Grupo archivado: ${ctx.groupId}` }];
    }

    // /admin archivar-grupo <jid>
    if (rest.startsWith('archivar-grupo ') || rest.startsWith('archive-group ')) {
      const arg = rest.startsWith('archivar-grupo ') ? rest.slice('archivar-grupo '.length).trim() : rest.slice('archive-group '.length).trim();
      if (!isGroupId(arg)) {
        return [{ recipient: sender, message: '⚠️ Debes indicar un group_id válido terminado en @g.us' }];
      }
      instanceDb.transaction(() => {
        instanceDb.prepare(`
          UPDATE groups
          SET active = 0, archived = 1, last_verified = strftime('%Y-%m-%d %H:%M:%f','now')
          WHERE id = ?
        `).run(arg);
        instanceDb.prepare(`
          UPDATE calendar_tokens
          SET revoked_at = strftime('%Y-%m-%d %H:%M:%f','now')
          WHERE group_id = ? AND revoked_at IS NULL
        `).run(arg);
        instanceDb.prepare(`
          UPDATE group_members
          SET is_active = 0
          WHERE group_id = ? AND is_active = 1
        `).run(arg);
      })();
      try { AllowedGroups.setStatus(arg, 'blocked'); } catch {}
      return [{ recipient: sender, message: `📦 Grupo archivado: ${arg}` }];
    }

    // /admin borrar-aquí
    if (rest === 'borrar-aquí' || rest === 'borrar-aqui' || rest === 'delete here' || rest === 'delete-here') {
      if (!isGroupId(ctx.groupId)) {
        return [{ recipient: sender, message: 'ℹ️ Este comando se debe usar dentro de un grupo.' }];
      }
      instanceDb.transaction(() => {
        instanceDb.prepare(`DELETE FROM tasks WHERE group_id = ?`).run(ctx.groupId);
        instanceDb.prepare(`DELETE FROM groups WHERE id = ?`).run(ctx.groupId);
        try { instanceDb.prepare(`DELETE FROM allowed_groups WHERE group_id = ?`).run(ctx.groupId); } catch {}
      })();
      return [{ recipient: sender, message: `🗑️ Grupo borrado y datos asociados eliminados: ${ctx.groupId}` }];
    }

    // /admin borrar-grupo <jid>
    if (rest.startsWith('borrar-grupo ') || rest.startsWith('delete-group ')) {
      const arg = rest.startsWith('borrar-grupo ') ? rest.slice('borrar-grupo '.length).trim() : rest.slice('delete-group '.length).trim();
      if (!isGroupId(arg)) {
        return [{ recipient: sender, message: '⚠️ Debes indicar un group_id válido terminado en @g.us' }];
      }
      instanceDb.transaction(() => {
        instanceDb.prepare(`DELETE FROM tasks WHERE group_id = ?`).run(arg);
        instanceDb.prepare(`DELETE FROM groups WHERE id = ?`).run(arg);
        try { instanceDb.prepare(`DELETE FROM allowed_groups WHERE group_id = ?`).run(arg); } catch {}
      })();
      return [{ recipient: sender, message: `🗑️ Grupo borrado y datos asociados eliminados: ${arg}` }];
    }

    // /admin allow all
    if (
      rest === 'allow all' ||
      rest === 'allow-all' ||
      rest === 'habilitar-todos' ||
      rest === 'permitir todos' ||
      rest === 'enable all'
    ) {
      const pendings = AllowedGroups.listByStatus('pending');
      if (!pendings || pendings.length === 0) {
        return [{ recipient: sender, message: '✅ No hay grupos pendientes.' }];
      }
      let changed = 0;
      for (const r of pendings) {
        const didChange = AllowedGroups.setStatus(r.group_id, 'allowed', r.label ?? null);
        if (didChange) changed++;
        try { Metrics.inc('admin_actions_total_allow'); } catch {}
      }
      return [{ recipient: sender, message: `✅ Grupos habilitados: ${changed}` }];
    }

    // /admin allow-group <jid>
    if (rest.startsWith('allow-group ') || (rest.startsWith('allow ') && rest !== 'allow all' && rest !== 'allow-all')) {
      const arg = (rest.startsWith('allow-group ') ? rest.slice('allow-group '.length) : rest.slice('allow '.length)).trim();
      if (!isGroupId(arg)) {
        return [{ recipient: sender, message: '⚠️ Debes indicar un group_id válido terminado en @g.us' }];
      }
      const changed = AllowedGroups.setStatus(arg, 'allowed');
      try { if (changed) Metrics.inc('admin_actions_total_allow'); } catch {}
      return [{ recipient: sender, message: `✅ Grupo habilitado: ${arg}` }];
    }

    // /admin block-group <jid>
    if (rest.startsWith('block-group ') || rest.startsWith('block ')) {
      const arg = (rest.startsWith('block-group ') ? rest.slice('block-group '.length) : rest.slice('block '.length)).trim();
      if (!isGroupId(arg)) {
        return [{ recipient: sender, message: '⚠️ Debes indicar un group_id válido terminado en @g.us' }];
      }
      const changed = AllowedGroups.setStatus(arg, 'blocked');
      try { if (changed) Metrics.inc('admin_actions_total_block'); } catch {}
      return [{ recipient: sender, message: `✅ Grupo bloqueado: ${arg}` }];
    }

    // /admin sync-grupos
    if (rest === 'sync-grupos' || rest === 'group-sync' || rest === 'syncgroups') {
      try {
        const r = await GroupSyncService.syncGroups(true);
        return [{ recipient: sender, message: `✅ Sync de grupos ejecutado: ${r.added} añadidos, ${r.updated} actualizados.` }];
      } catch (e) {
        const msg = e instanceof Error ? e.message : String(e);
        return [{ recipient: sender, message: `❌ Error al ejecutar sync de grupos: ${msg}` }];
      }
    }

    // /admin ver todos [<limite>]
    if (
      rest === 'ver todos' ||
      rest.startsWith('ver todos ') ||
      rest === 'listar' ||
      rest.startsWith('listar ') ||
      rest === 'list all' ||
      rest.startsWith('list all ') ||
      rest === 'list-all' ||
      rest.startsWith('list-all ')
    ) {
      // Asegurar acceso a la misma DB para TaskService

      const DEFAULT_LIMIT = 50;
      let limit = DEFAULT_LIMIT;
      const maybeNum = parseInt(rest.split(/\s+/).pop() || '', 10);
      if (Number.isFinite(maybeNum) && maybeNum > 0) {
        limit = Math.min(maybeNum, 500); // tope razonable
      }

      const tasks = TaskService.listAllActive(limit);
      const total = TaskService.countAllActive();

      if (!tasks || tasks.length === 0) {
        return [{ recipient: sender, message: '✅ No hay tareas activas.' }];
      }

      const lines = tasks.map(t => {
        const ddmm = formatDDMM(t.due_date);
        const groupLabel = t.group_name || t.group_id || 'DM';
        const parts: string[] = [
          `${codeId(t.id, t.display_code)}`,
          String(t.description || '').trim()
        ];
        if (ddmm) parts.push(`vence ${ddmm}`);
        if (groupLabel) parts.push(`[${groupLabel}]`);
        return `- ${parts.join(' · ')}`;
      });
      const header = total > limit
        ? `Tus tareas — Tareas activas (${total}) — mostrando ${tasks.length} primeras:`
        : `Tus tareas — Tareas activas (${total}):`;
      const footer = `ℹ️ Para ver tareas sin responsable de un grupo, pide el listado desde ese grupo.`;

      try { Metrics.inc('admin_actions_total_list'); } catch {}

      return [{
        recipient: sender,
        message: `${header}\n${lines.join('\n')}\n\n${footer}`
      }];
    }

    // Ayuda por defecto
    return [{ recipient: sender, message: this.help() }];
  }
}
