import { TaskService } from '../../../tasks/service';
import { GroupSyncService } from '../../group-sync';
import { ContactsService } from '../../contacts';
import { ICONS } from '../../../utils/icons';
import { codeId, bold, italic } from '../../../utils/formatting';
import { SCOPE_ALIASES, todayYMD, formatTaskLine } from '../shared';

type Ctx = {
  sender: string;
  groupId: string;
  message: string;
};

type Msg = {
  recipient: string;
  message: string;
  mentions?: string[];
};

const LIMIT = 10;

// ---------------------------------------------------------------------------
// Shared: group tasks by group_id and render
// ---------------------------------------------------------------------------

async function groupAndRenderTasks(
  items: any[],
  todayYMD: string,
): Promise<string[]> {
  const byGroup = new Map<string, any[]>();
  for (const t of items) {
    const key = t.group_id || '(sin grupo)';
    const arr = byGroup.get(key) || [];
    arr.push(t);
    byGroup.set(key, arr);
  }

  const sections: string[] = [];
  for (const [groupId, arr] of byGroup.entries()) {
    const groupName =
      (groupId && GroupSyncService.activeGroupsCache.get(groupId)) ||
      (groupId && groupId !== '(sin grupo)' ? groupId : 'Sin grupo');

    sections.push(groupName);
    const rendered = await Promise.all(arr.map(async (t) => {
      const names = await Promise.all(
        (t.assignees || []).map(async (uid: string) => (await ContactsService.getDisplayName(uid)) || uid),
      );
      const owner =
        (t.assignees?.length || 0) === 0
          ? `${ICONS.unassigned}`
          : `${t.assignees!.length > 1 ? '👥' : '👤'} ${names.join(', ')}`;
      return formatTaskLine(t, owner, todayYMD);
    }));
    sections.push(...rendered);
    sections.push('');
  }

  // Remove trailing blank line
  if (sections.length > 0 && sections[sections.length - 1] === '') {
    sections.pop();
  }
  return sections;
}

// ---------------------------------------------------------------------------
// Build user's own tasks section (used by both "mis" and "todos")
// ---------------------------------------------------------------------------

async function buildUserTasksSection(sender: string, todayYMD: string): Promise<string[]> {
  const sections: string[] = [bold('Tus tareas')];

  const items = TaskService.listUserPending(sender, LIMIT);
  if (items.length === 0) {
    sections.push(italic('_No tienes tareas pendientes._'));
    return sections;
  }

  sections.push(...await groupAndRenderTasks(items, todayYMD));

  const total = TaskService.countUserPending(sender);
  if (total > items.length) {
    sections.push(`… y ${total - items.length} más`);
  }
  return sections;
}

// ---------------------------------------------------------------------------
// Unassigned tasks from membership (used by "todos")
// ---------------------------------------------------------------------------

async function buildUnassignedSections(sender: string, todayYMD: string): Promise<string[]> {
  const sections: string[] = [];
  const memberGroups = GroupSyncService.getFreshMemberGroupsForUser(sender);

  if (memberGroups.length === 0) {
    sections.push('ℹ️ Para ver tareas sin responsable, escribe por privado `t todas` o usa `t web`.');
    return sections;
  }

  const perGroup = TaskService.listUnassignedByGroups(memberGroups, LIMIT);
  for (const gid of perGroup.keys()) {
    const unassigned = perGroup.get(gid)!;
    if (unassigned.length === 0) continue;

    const groupName = GroupSyncService.activeGroupsCache.get(gid) || gid;
    if (sections.length && sections[sections.length - 1] !== '') sections.push('');
    sections.push(`${groupName} — Sin responsable`);

    const rendered = unassigned.map(t =>
      formatTaskLine(t, `${ICONS.unassigned}`, todayYMD),
    );
    sections.push(...rendered);

    const total = TaskService.countGroupUnassigned(gid);
    if (total > unassigned.length) {
      sections.push(`… y ${total - unassigned.length} más`);
    }
  }
  return sections;
}

// ---------------------------------------------------------------------------
// Scope: "todos" — user tasks + unassigned from member groups
// ---------------------------------------------------------------------------

async function handleVerTodos(sender: string): Promise<Msg[]> {
  const today = todayYMD();
  const sections = await buildUserTasksSection(sender, today);

  // Add unassigned section
  const unassignedSections = await buildUnassignedSections(sender, today);
  sections.push(...unassignedSections);

  return [{ recipient: sender, message: sections.join('\n') }];
}

// ---------------------------------------------------------------------------
// Scope: "mis" — user's own tasks only
// ---------------------------------------------------------------------------

async function handleVerMis(sender: string): Promise<Msg[]> {
  const today = todayYMD();
  const items = TaskService.listUserPending(sender, LIMIT);

  if (items.length === 0) {
    return [{ recipient: sender, message: italic('No tienes tareas pendientes.') }];
  }

  const sections: string[] = [bold('Tus tareas')];
  sections.push(...await groupAndRenderTasks(items, today));

  const total = TaskService.countUserPending(sender);
  if (total > items.length) {
    sections.push(`… y ${total - items.length} más`);
  }

  return [{ recipient: sender, message: sections.join('\n') }];
}

// ---------------------------------------------------------------------------
// Scope resolution
// ---------------------------------------------------------------------------

function resolveScope(tokens: string[]): string {
  const rawAction = (tokens[1] || '').toLowerCase();
  const scopeRaw = (tokens[2] || '').toLowerCase();
  if (scopeRaw) return SCOPE_ALIASES[scopeRaw] || scopeRaw;

  // Guess scope from action word
  if (rawAction === 'mias' || rawAction === 'mías') return 'mis';
  return 'todos';
}

// ---------------------------------------------------------------------------
// Main handler
// ---------------------------------------------------------------------------

export async function handleVer(context: Ctx): Promise<Msg[]> {
  const tokens = (context.message || '').trim().split(/\s+/);
  const scope = resolveScope(tokens);

  if (scope === 'todos') {
    return handleVerTodos(context.sender);
  }
  return handleVerMis(context.sender);
}
