import { mutation } from "../_generated/server";
import { v } from "convex/values";

/**
 * Create a new lead
 * Phase 7: Leads, Quotations, Expenses
 */
export const createLead = mutation({
  args: {
    userId: v.string(),
    organizationId: v.optional(v.string()),
    name: v.string(),
    phone: v.optional(v.string()),
    email: v.optional(v.string()),
    company: v.optional(v.string()),
    source: v.string(),
    interest: v.optional(v.string()),
    notes: v.optional(v.string()),
  },
  handler: async (ctx, args) => {
    const now = Date.now();
    const id = await ctx.db.insert("leads", {
      userId: args.userId,
      organizationId: args.organizationId,
      name: args.name,
      phone: args.phone,
      email: args.email,
      company: args.company,
      source: args.source,
      interest: args.interest,
      notes: args.notes,
      customFields: {},
      metadata: {},
      status: "NEW",
      score: 0,
      tags: [],
      touchCount: 0,
      firstTouchAt: now,
      lastActivityAt: now,
      createdAt: now,
      updatedAt: now,
    });
    return id;
  },
});

/**
 * Update lead details
 * Phase 7: Leads, Quotations, Expenses
 */
export const updateLead = mutation({
  args: {
    id: v.id("leads"),
    name: v.optional(v.string()),
    phone: v.optional(v.string()),
    email: v.optional(v.string()),
    company: v.optional(v.string()),
    status: v.optional(v.string()),
    notes: v.optional(v.string()),
    assignedTo: v.optional(v.string()),
    tags: v.optional(v.array(v.string())),
  },
  handler: async (ctx, args) => {
    const { id, ...updates } = args;
    const filtered: Record<string, unknown> = {};
    for (const [key, value] of Object.entries(updates)) {
      if (value !== undefined) {
        filtered[key] = value;
      }
    }
    filtered.updatedAt = Date.now();
    await ctx.db.patch(id, filtered);
  },
});

/**
 * Assign a lead to a user
 * Phase 7: Leads, Quotations, Expenses
 */
export const assignLead = mutation({
  args: {
    id: v.id("leads"),
    assignedTo: v.string(),
  },
  handler: async (ctx, args) => {
    await ctx.db.patch(args.id, {
      assignedTo: args.assignedTo,
      updatedAt: Date.now(),
    });
  },
});

/**
 * Update a lead's status
 * Phase 7: Leads, Quotations, Expenses
 */
export const updateLeadStatus = mutation({
  args: {
    id: v.id("leads"),
    status: v.string(),
  },
  handler: async (ctx, args) => {
    const now = Date.now();
    const patch: Record<string, unknown> = {
      status: args.status,
      updatedAt: now,
    };
    if (args.status === "CONVERTED") {
      patch.convertedAt = now;
    }
    if (args.status === "QUALIFIED") {
      patch.qualifiedAt = now;
    }
    await ctx.db.patch(args.id, patch);
  },
});

/**
 * Add a note to a lead (creates a NOTE activity)
 * Phase 7: Leads, Quotations, Expenses
 */
export const addLeadNote = mutation({
  args: {
    leadId: v.string(),
    userId: v.string(),
    title: v.string(),
    description: v.optional(v.string()),
  },
  handler: async (ctx, args) => {
    const now = Date.now();
    const id = await ctx.db.insert("lead_activities", {
      leadId: args.leadId,
      userId: args.userId,
      type: "NOTE",
      title: args.title,
      description: args.description,
      createdAt: now,
    });
    return id;
  },
});

/**
 * Delete a lead
 * Phase 7: Leads, Quotations, Expenses
 */
export const deleteLead = mutation({
  args: {
    id: v.id("leads"),
  },
  handler: async (ctx, args) => {
    await ctx.db.delete(args.id);
  },
});

/**
 * Move a lead to a different pipeline stage
 * Phase 7: Leads, Quotations, Expenses
 */
export const movePipelineStage = mutation({
  args: {
    id: v.id("leads"),
    pipelineStageId: v.string(),
  },
  handler: async (ctx, args) => {
    await ctx.db.patch(args.id, {
      pipelineStageId: args.pipelineStageId,
      updatedAt: Date.now(),
    });
  },
});

/**
 * Add an activity entry to a lead's timeline
 * Phase 7: Leads, Quotations, Expenses
 */
export const addActivity = mutation({
  args: {
    leadId: v.string(),
    userId: v.string(),
    type: v.string(),
    title: v.string(),
    description: v.optional(v.string()),
    metadata: v.optional(v.any()),
  },
  handler: async (ctx, args) => {
    const now = Date.now();
    const id = await ctx.db.insert("lead_activities", {
      leadId: args.leadId,
      userId: args.userId,
      type: args.type as
        | "NOTE"
        | "CALL"
        | "EMAIL"
        | "MEETING"
        | "WHATSAPP"
        | "STATUS_CHANGE"
        | "STAGE_CHANGE"
        | "SCORE_CHANGE"
        | "AI_QUALIFICATION",
      title: args.title,
      description: args.description,
      metadata: args.metadata,
      createdAt: now,
    });
    return id;
  },
});

/**
 * Update a lead's score
 * Phase 7: Leads, Quotations, Expenses
 */
export const updateScore = mutation({
  args: {
    id: v.id("leads"),
    score: v.number(),
    eventType: v.optional(v.string()),
    ruleName: v.optional(v.string()),
  },
  handler: async (ctx, args) => {
    const lead = await ctx.db.get(args.id);
    if (!lead) {
      throw new Error("Lead not found");
    }
    const now = Date.now();
    const scoreBefore = lead.score;

    await ctx.db.patch(args.id, {
      score: args.score,
      updatedAt: now,
    });

    // Record scoring event
    await ctx.db.insert("lead_scoring_events", {
      leadId: args.id,
      eventType:
        (args.eventType as
          | "RULE_MATCH"
          | "AI_SCORE"
          | "MANUAL_ADJUST"
          | "DECAY") ?? "MANUAL_ADJUST",
      ruleName: args.ruleName,
      points: args.score - scoreBefore,
      scoreBefore,
      scoreAfter: args.score,
      createdAt: now,
    });
  },
});
