import { prisma } from "@/lib/prisma";

export type TaskStatus = "todo" | "in_progress" | "completed";
export type TaskCategory = "seo" | "llmo" | "gbp" | "content" | "technical";
export type TaskPriority = "low" | "medium" | "high" | "critical";
export type TaskEffort = "low" | "medium" | "high";

interface TaskFilters {
  status?: TaskStatus;
  category?: TaskCategory;
  priority?: TaskPriority;
  assignedTo?: string;
}

/**
 * List tasks for a brand with optional filters.
 */
export async function getTasks(brandId: string, filters?: TaskFilters) {
  const where: Record<string, unknown> = { brandId };
  if (filters?.status) where.status = filters.status;
  if (filters?.category) where.category = filters.category;
  if (filters?.priority) where.priority = filters.priority;
  if (filters?.assignedTo) where.assignedTo = filters.assignedTo;

  return prisma.task.findMany({
    where,
    include: {
      assignee: { select: { id: true, name: true, email: true, image: true } },
      pageLaunch: { select: { id: true, pageUrl: true, launchDate: true } },
    },
    orderBy: [
      { priority: "desc" },
      { createdAt: "desc" },
    ],
  });
}

/**
 * Get task counts grouped by status for a brand.
 */
export async function getTaskCounts(brandId: string) {
  const tasks = await prisma.task.groupBy({
    by: ["status"],
    where: { brandId },
    _count: true,
  });

  const counts: Record<string, number> = { todo: 0, in_progress: 0, completed: 0 };
  for (const t of tasks) {
    counts[t.status] = t._count;
  }
  return counts;
}

/**
 * Create a new task.
 */
export async function createTask(data: {
  brandId: string;
  title: string;
  description?: string;
  category: TaskCategory;
  priority?: TaskPriority;
  effort?: TaskEffort;
  pageUrl?: string;
  recommendation?: string;
  source?: string;
  sourceId?: string;
  sourceRunAt?: Date;
  dueDate?: Date;
  assignedTo?: string;
  preventDuplicate?: boolean;
}) {
  // Prevent duplicate: prefer sourceId match (exact), fall back to title match
  if (data.preventDuplicate !== false) {
    const where: Record<string, unknown> = {
      brandId: data.brandId,
      status: { not: "completed" },
    };

    // If we have a sourceId, match on source+sourceId for precise dedup
    if (data.source && data.sourceId) {
      where.source = data.source;
      where.sourceId = data.sourceId;
    } else {
      where.title = data.title;
    }

    const existing = await prisma.task.findFirst({ where });
    if (existing) {
      return { ...existing, _duplicate: true };
    }
  }

  return prisma.task.create({
    data: {
      brandId: data.brandId,
      title: data.title,
      description: data.description,
      category: data.category,
      priority: data.priority ?? "medium",
      effort: data.effort ?? "medium",
      pageUrl: data.pageUrl,
      recommendation: data.recommendation,
      source: data.source ?? "manual",
      sourceId: data.sourceId,
      sourceRunAt: data.sourceRunAt,
      dueDate: data.dueDate,
      assignedTo: data.assignedTo,
    },
    include: {
      assignee: { select: { id: true, name: true, email: true } },
    },
  });
}

/**
 * Update a task's status. When completed, sets completedAt.
 */
export async function updateTaskStatus(taskId: string, status: TaskStatus) {
  return prisma.task.update({
    where: { id: taskId },
    data: {
      status,
      completedAt: status === "completed" ? new Date() : null,
    },
  });
}

/**
 * Update any task fields.
 */
export async function updateTask(taskId: string, data: {
  title?: string;
  description?: string;
  category?: TaskCategory;
  priority?: TaskPriority;
  effort?: TaskEffort;
  status?: TaskStatus;
  pageUrl?: string;
  dueDate?: Date | null;
  assignedTo?: string | null;
}) {
  return prisma.task.update({
    where: { id: taskId },
    data: {
      ...data,
      completedAt: data.status === "completed" ? new Date() : data.status ? null : undefined,
    },
    include: {
      assignee: { select: { id: true, name: true, email: true } },
    },
  });
}

/**
 * Complete a task and optionally create a PageLaunch record.
 */
export async function completeTaskAndLaunch(
  taskId: string,
  launchData?: {
    pageUrl: string;
    pageType: string;
    baselineSessions?: number;
    baselineClicks?: number;
    baselineImpressions?: number;
    baselinePosition?: number;
    baselineConversions?: number;
    baselineRevenue?: number;
    notes?: string;
  }
) {
  // Complete the task
  const task = await prisma.task.update({
    where: { id: taskId },
    data: { status: "completed", completedAt: new Date() },
  });

  // If launch data provided, create a PageLaunch record
  if (launchData) {
    const launch = await prisma.pageLaunch.create({
      data: {
        brandId: task.brandId,
        taskId: task.id,
        pageUrl: launchData.pageUrl,
        pageType: launchData.pageType,
        launchDate: new Date(),
        notes: launchData.notes,
        baselineSessions: launchData.baselineSessions ?? 0,
        baselineClicks: launchData.baselineClicks ?? 0,
        baselineImpressions: launchData.baselineImpressions ?? 0,
        baselinePosition: launchData.baselinePosition ?? 0,
        baselineConversions: launchData.baselineConversions ?? 0,
        baselineRevenue: launchData.baselineRevenue ?? 0,
      },
    });
    return { task, launch };
  }

  return { task, launch: null };
}
