import type { RequestHandler } from './$types';
import { getDb } from '$lib/server/db';
import { sha256Hex } from '$lib/server/crypto';
import { icsHorizonMonths } from '$lib/server/env';
import { buildIcsCalendar } from '$lib/server/ics';
import { toIsoSqlUTC, ymdUTC, addMonthsUTC } from '$lib/server/datetime';

export const GET: RequestHandler = async ({ params, request }) => {
  const db = await getDb();
  const token = params.token || '';
  if (!token) return new Response('Not Found', { status: 404 });

  const tokenHash = await sha256Hex(token);
  const row = db
    .prepare(
      `SELECT id, type, user_id, group_id, revoked_at
       FROM calendar_tokens
       WHERE token_hash = ?
       LIMIT 1`
    )
    .get(tokenHash) as any;

  if (!row) return new Response('Not Found', { status: 404 });
  if (row.revoked_at) return new Response('Gone', { status: 410 });
  if (String(row.type) !== 'group' || !row.group_id) return new Response('Not Found', { status: 404 });

  // Validar estado del grupo (activo y no archivado); en caso contrario, tratar como feed caducado
  const gRow = db
    .prepare(`SELECT COALESCE(active,1) as active, COALESCE(archived,0) as archived, COALESCE(is_community,0) as is_community FROM groups WHERE id = ?`)
    .get(row.group_id) as any;
  if (!gRow || Number(gRow.active || 0) !== 1 || Number(gRow.archived || 0) === 1 || Number(gRow.is_community || 0) === 1) {
    db.prepare(`UPDATE calendar_tokens SET last_used_at = ? WHERE id = ?`).run(toIsoSqlUTC(), row.id);
    return new Response('Gone', { status: 410 });
  }

  const today = new Date();
  const startYmd = ymdUTC(today);
  const endYmd = ymdUTC(addMonthsUTC(today, icsHorizonMonths));

  const tasks = db
    .prepare(
      `SELECT t.id, t.description, t.due_date, g.name AS group_name
       FROM tasks t
       LEFT JOIN groups g ON g.id = t.group_id
       WHERE t.group_id = ?
         AND COALESCE(t.completed, 0) = 0
         AND t.due_date IS NOT NULL
         AND t.due_date >= ? AND t.due_date <= ?
         AND NOT EXISTS (SELECT 1 FROM task_assignments a WHERE a.task_id = t.id)
       ORDER BY t.due_date ASC, t.id ASC`
    )
    .all(row.group_id, startYmd, endYmd) as Array<{ id: number; description: string; due_date: string; group_name: string | null }>;

  const events = tasks.map((t) => ({
    id: t.id,
    description: t.description,
    due_date: t.due_date,
    group_name: t.group_name || null,
    prefix: 'T'
  }));

  const { body, etag } = await buildIcsCalendar('Tareas sin responsable (grupo)', events);

  // 304 si ETag coincide
  const inm = request.headers.get('if-none-match');
  if (inm && inm === etag) {
    // Actualizar last_used_at aunque sea 304
    db.prepare(`UPDATE calendar_tokens SET last_used_at = ? WHERE id = ?`).run(toIsoSqlUTC(), row.id);
    return new Response(null, { status: 304, headers: { ETag: etag, 'Cache-Control': 'public, max-age=300' } });
  }

  db.prepare(`UPDATE calendar_tokens SET last_used_at = ? WHERE id = ?`).run(toIsoSqlUTC(), row.id);

  return new Response(body, {
    status: 200,
    headers: {
      'content-type': 'text/calendar; charset=utf-8',
      'cache-control': 'public, max-age=300',
      ETag: etag
    }
  });
};
