// Natural-language quick add, Todoist style:
//   "Pay rent tomorrow p1 @home #Sydney ~30m"
// → title "Pay rent", due tomorrow, priority 1, context @home,
//   project "Sydney" (matched by name prefix), estimate 30 min.
import type { Project, Task } from "./types";

export interface ParsedQuickAdd {
  title: string;
  priority?: Task["priority"];
  due_date?: string;
  context?: string;
  project_id?: string;
  estimate_min?: number;
}

const WEEKDAYS = ["sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"];

function iso(d: Date): string {
  const y = d.getFullYear();
  const m = String(d.getMonth() + 1).padStart(2, "0");
  const day = String(d.getDate()).padStart(2, "0");
  return `${y}-${m}-${day}`;
}

function parseDateWord(word: string): string | undefined {
  const w = word.toLowerCase();
  const today = new Date();
  if (w === "today" || w === "tod") return iso(today);
  if (w === "tomorrow" || w === "tmr" || w === "tom") {
    const d = new Date(today);
    d.setDate(d.getDate() + 1);
    return iso(d);
  }
  if (/^\d{4}-\d{2}-\d{2}$/.test(w)) return w;
  const wd = WEEKDAYS.findIndex((n) => n === w || n.slice(0, 3) === w);
  if (wd >= 0) {
    const d = new Date(today);
    const delta = (wd - d.getDay() + 7) % 7 || 7; // always the *next* occurrence
    d.setDate(d.getDate() + delta);
    return iso(d);
  }
  return undefined;
}

function parseEstimate(token: string): number | undefined {
  const m = token.match(/^~(?:(\d+)h)?(\d+)?m?$/i);
  if (!m || (!m[1] && !m[2])) return undefined;
  return (Number(m[1] ?? 0) * 60 + Number(m[2] ?? 0)) || undefined;
}

export function parseQuickAdd(input: string, projects: Project[]): ParsedQuickAdd {
  const out: ParsedQuickAdd = { title: "" };
  const rest: string[] = [];

  for (const token of input.trim().split(/\s+/)) {
    const p = token.match(/^p([1-4])$/i);
    if (p && out.priority === undefined) {
      out.priority = Number(p[1]) as Task["priority"];
      continue;
    }
    if (token.startsWith("@") && token.length > 1 && out.context === undefined) {
      out.context = token;
      continue;
    }
    if (token.startsWith("#") && token.length > 1 && out.project_id === undefined) {
      const name = token.slice(1).toLowerCase();
      const match = projects.find(
        (pr) => pr.status === "active" && pr.name.toLowerCase().startsWith(name),
      );
      if (match) {
        out.project_id = match.id;
        continue;
      }
    }
    const est = parseEstimate(token);
    if (est && out.estimate_min === undefined) {
      out.estimate_min = est;
      continue;
    }
    if (out.due_date === undefined) {
      const due = parseDateWord(token);
      if (due) {
        out.due_date = due;
        continue;
      }
    }
    rest.push(token);
  }

  out.title = rest.join(" ");
  return out;
}
