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

/**
 * Track an analytics event
 * Phase 8: Content, Careers, Real Estate, Analytics, Reviews
 */
export const trackEvent = mutation({
  args: {
    eventName: v.string(),
    category: v.string(),
    properties: v.optional(v.any()),
    userId: v.optional(v.string()),
    sessionId: v.optional(v.string()),
    page: v.optional(v.string()),
  },
  handler: async (ctx, args) => {
    const id = await ctx.db.insert("analytics_events", {
      eventName: args.eventName,
      category: args.category,
      properties: args.properties,
      userId: args.userId,
      sessionId: args.sessionId,
      page: args.page,
      createdAt: Date.now(),
    });
    return id;
  },
});

/**
 * Record a site visit
 * Phase 8: Content, Careers, Real Estate, Analytics, Reviews
 */
export const recordVisit = mutation({
  args: {
    visitorId: v.string(),
    sessionId: v.string(),
    page: v.string(),
    country: v.optional(v.string()),
    city: v.optional(v.string()),
    language: v.optional(v.string()),
    userAgent: v.optional(v.string()),
    referrer: v.optional(v.string()),
    userId: v.optional(v.string()),
  },
  handler: async (ctx, args) => {
    const id = await ctx.db.insert("site_visits", {
      visitorId: args.visitorId,
      sessionId: args.sessionId,
      page: args.page,
      country: args.country,
      city: args.city,
      language: args.language,
      userAgent: args.userAgent,
      referrer: args.referrer,
      userId: args.userId,
      createdAt: Date.now(),
    });
    return id;
  },
});

/**
 * Record/update workflow analytics metrics
 * No analytics_metrics table exists — inserts into workflow_analytics
 * Phase 8: Content, Careers, Real Estate, Analytics, Reviews
 */
export const updateMetrics = mutation({
  args: {
    userId: v.string(),
    workflowType: v.string(),
    date: v.number(),
    messagesReceived: v.optional(v.number()),
    messagesSent: v.optional(v.number()),
    appointmentsBooked: v.optional(v.number()),
    quotationsSent: v.optional(v.number()),
    leadsGenerated: v.optional(v.number()),
    metadata: v.optional(v.any()),
  },
  handler: async (ctx, args) => {
    // Check for existing entry for this user+workflowType+date
    const existing = await ctx.db
      .query("workflow_analytics")
      .withIndex("by_userId_workflowType_date", (q: any) =>
        q
          .eq("userId", args.userId)
          .eq("workflowType", args.workflowType)
          .eq("date", args.date),
      )
      .first();

    if (existing) {
      await ctx.db.patch(existing._id, {
        messagesReceived: args.messagesReceived ?? existing.messagesReceived,
        messagesSent: args.messagesSent ?? existing.messagesSent,
        appointmentsBooked:
          args.appointmentsBooked ?? existing.appointmentsBooked,
        quotationsSent: args.quotationsSent ?? existing.quotationsSent,
        leadsGenerated: args.leadsGenerated ?? existing.leadsGenerated,
        metadata: args.metadata ?? existing.metadata,
      });
      return existing._id;
    }

    const id = await ctx.db.insert("workflow_analytics", {
      userId: args.userId,
      workflowType: args.workflowType,
      date: args.date,
      messagesReceived: args.messagesReceived ?? 0,
      messagesSent: args.messagesSent ?? 0,
      appointmentsBooked: args.appointmentsBooked ?? 0,
      quotationsSent: args.quotationsSent ?? 0,
      leadsGenerated: args.leadsGenerated ?? 0,
      metadata: args.metadata,
    });
    return id;
  },
});

/**
 * Record a web vital metric (CLS, FID, LCP, FCP, TTFB, INP)
 * Phase 8: Content, Careers, Real Estate, Analytics, Reviews
 */
export const recordWebVital = mutation({
  args: {
    name: v.string(),
    value: v.number(),
    rating: v.union(
      v.literal("good"),
      v.literal("needs-improvement"),
      v.literal("poor"),
    ),
    url: v.string(),
    userAgent: v.optional(v.string()),
    navigationType: v.optional(v.string()),
  },
  handler: async (ctx, args) => {
    const id = await ctx.db.insert("web_vitals", {
      name: args.name,
      value: args.value,
      rating: args.rating,
      url: args.url,
      userAgent: args.userAgent,
      navigationType: args.navigationType,
      recordedAt: Date.now(),
    });
    return id;
  },
});

/**
 * Upsert workflow execution metrics — find by workflowType+userId+date,
 * increment counters if exists, otherwise insert new row.
 * Maps execution metrics onto the existing workflow_analytics schema:
 *   executionCount → appointmentsBooked
 *   successCount   → messagesReceived
 *   failureCount   → messagesSent
 *   avgDurationMs  → stored in metadata
 * Phase 8: Content, Careers, Real Estate, Analytics, Reviews
 */
export const upsertWorkflowMetrics = mutation({
  args: {
    workflowType: v.string(),
    userId: v.string(),
    date: v.number(),
    executionCount: v.optional(v.number()),
    successCount: v.optional(v.number()),
    failureCount: v.optional(v.number()),
    avgDurationMs: v.optional(v.number()),
  },
  handler: async (ctx, args) => {
    const existing = await ctx.db
      .query("workflow_analytics")
      .withIndex("by_userId_workflowType_date", (q: any) =>
        q
          .eq("userId", args.userId)
          .eq("workflowType", args.workflowType)
          .eq("date", args.date),
      )
      .first();

    const prevMeta = (existing?.metadata ?? {}) as Record<string, unknown>;
    const prevExec = (prevMeta.executionCount as number) ?? 0;
    const prevSuccess = (prevMeta.successCount as number) ?? 0;
    const prevFailure = (prevMeta.failureCount as number) ?? 0;
    const prevAvgMs = (prevMeta.avgDurationMs as number) ?? 0;

    const addedExec = args.executionCount ?? 0;
    const newExecTotal = prevExec + addedExec;
    const newSuccessTotal = prevSuccess + (args.successCount ?? 0);
    const newFailureTotal = prevFailure + (args.failureCount ?? 0);

    // Weighted average duration
    const newAvgMs =
      newExecTotal > 0
        ? Math.round(
            (prevAvgMs * prevExec + (args.avgDurationMs ?? 0) * addedExec) /
              newExecTotal,
          )
        : 0;

    const updatedMeta = {
      ...prevMeta,
      executionCount: newExecTotal,
      successCount: newSuccessTotal,
      failureCount: newFailureTotal,
      avgDurationMs: newAvgMs,
      lastExecution: Date.now(),
    };

    if (existing) {
      await ctx.db.patch(existing._id, {
        appointmentsBooked: (existing.appointmentsBooked ?? 0) + addedExec,
        metadata: updatedMeta,
      });
      return existing._id;
    }

    const id = await ctx.db.insert("workflow_analytics", {
      userId: args.userId,
      workflowType: args.workflowType,
      date: args.date,
      messagesReceived: 0,
      messagesSent: 0,
      appointmentsBooked: addedExec,
      quotationsSent: 0,
      leadsGenerated: 0,
      metadata: updatedMeta,
    });
    return id;
  },
});
