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

/**
 * Create a new review (from customer submission)
 * Phase 8: Content, Careers, Real Estate, Analytics, Reviews
 */
export const createReview = mutation({
  args: {
    userId: v.string(),
    customerName: v.string(),
    customerEmail: v.optional(v.string()),
    customerPhone: v.optional(v.string()),
    platform: v.optional(v.string()),
    rating: v.number(),
    title: v.optional(v.string()),
    content: v.optional(v.string()),
    language: v.optional(v.string()),
    reviewRequestId: v.optional(v.string()),
    questionResponses: v.optional(v.any()),
  },
  handler: async (ctx, args) => {
    const now = Date.now();
    const id = await ctx.db.insert("reviews", {
      userId: args.userId,
      customerName: args.customerName,
      customerEmail: args.customerEmail,
      customerPhone: args.customerPhone,
      platform: args.platform ?? "direct",
      rating: args.rating,
      title: args.title,
      content: args.content,
      language: args.language ?? "en",
      isVerified: false,
      reviewRequestId: args.reviewRequestId,
      questionResponses: args.questionResponses,
      isFeatured: false,
      createdAt: now,
      updatedAt: now,
    });

    // If linked to a review request, mark it completed
    if (args.reviewRequestId) {
      const request = await ctx.db
        .query("review_requests")
        .filter((q) => q.eq(q.field("_id"), args.reviewRequestId))
        .first();
      if (request) {
        await ctx.db.patch(request._id, {
          status: "COMPLETED",
          completedAt: now,
          updatedAt: now,
        });
      }
    }

    return id;
  },
});

/**
 * Create a review request (send to customer via email/WhatsApp)
 * Phase 8: Content, Careers, Real Estate, Analytics, Reviews
 */
export const createReviewRequest = mutation({
  args: {
    userId: v.string(),
    customerName: v.string(),
    customerEmail: v.optional(v.string()),
    customerPhone: v.optional(v.string()),
    channel: v.optional(v.string()),
    message: v.optional(v.string()),
    language: v.optional(v.string()),
    bookingId: v.optional(v.string()),
    customerId: v.optional(v.string()),
    questions: v.optional(v.any()),
  },
  handler: async (ctx, args) => {
    const now = Date.now();
    const token = `rev_${now}_${Math.random().toString(36).slice(2, 10)}`;
    const expiresAt = now + 14 * 24 * 60 * 60 * 1000; // 14 days

    const id = await ctx.db.insert("review_requests", {
      userId: args.userId,
      customerName: args.customerName,
      customerEmail: args.customerEmail,
      customerPhone: args.customerPhone,
      channel: args.channel ?? "email",
      token,
      message: args.message,
      language: args.language ?? "en",
      status: "PENDING",
      expiresAt,
      bookingId: args.bookingId,
      customerId: args.customerId,
      questions: args.questions,
      source: "manual",
      reminderCount: 0,
      createdAt: now,
      updatedAt: now,
    });
    return { id, token };
  },
});

/**
 * Update review fields (featured status, owner response, etc.)
 * Wave 1: Reviews gap-fill
 */
export const updateReview = mutation({
  args: {
    userId: v.string(),
    reviewId: v.id("reviews"),
    isFeatured: v.optional(v.boolean()),
    featuredOrder: v.optional(v.number()),
    responseText: v.optional(v.string()),
    title: v.optional(v.string()),
    content: v.optional(v.string()),
  },
  handler: async (ctx, args) => {
    const now = Date.now();

    // Verify ownership
    const review = await ctx.db.get(args.reviewId);
    if (!review || review.userId !== args.userId) {
      throw new Error("Review not found or access denied");
    }

    const { userId, reviewId, ...fields } = args;
    const patch: Record<string, unknown> = { updatedAt: now };
    for (const [key, value] of Object.entries(fields)) {
      if (value !== undefined) patch[key] = value;
    }

    // When featuring, set featuredAt; when un-featuring, clear it
    if (args.isFeatured === true) {
      patch.featuredAt = now;
      // If no explicit order provided, assign next order
      if (args.featuredOrder === undefined) {
        const featured = await ctx.db
          .query("reviews")
          .withIndex("by_userId_isFeatured", (q) =>
            q.eq("userId", args.userId).eq("isFeatured", true),
          )
          .collect();
        const maxOrder = featured.reduce(
          (max, r) => Math.max(max, r.featuredOrder ?? 0),
          0,
        );
        patch.featuredOrder = maxOrder + 1;
      }
    } else if (args.isFeatured === false) {
      patch.featuredAt = undefined;
      patch.featuredOrder = 0;
    }

    // When responding, set respondedAt
    if (args.responseText !== undefined) {
      patch.respondedAt = now;
    }

    await ctx.db.patch(args.reviewId, patch);
    return args.reviewId;
  },
});

/**
 * Batch update featuredOrder for featured reviews (drag-and-drop reorder)
 * Wave 1: Reviews gap-fill
 */
export const reorderFeaturedReviews = mutation({
  args: {
    userId: v.string(),
    orderedIds: v.array(v.id("reviews")),
  },
  handler: async (ctx, args) => {
    const now = Date.now();

    for (let i = 0; i < args.orderedIds.length; i++) {
      const review = await ctx.db.get(args.orderedIds[i]);
      if (review && review.userId === args.userId && review.isFeatured) {
        await ctx.db.patch(args.orderedIds[i], {
          featuredOrder: i + 1,
          updatedAt: now,
        });
      }
    }

    return { updated: args.orderedIds.length };
  },
});

/**
 * Mark a review request as sent (status -> "SENT", set sentAt)
 * Wave 1: Reviews gap-fill
 */
export const sendReviewRequest = mutation({
  args: {
    userId: v.string(),
    requestId: v.id("review_requests"),
  },
  handler: async (ctx, args) => {
    const now = Date.now();

    // Verify ownership
    const request = await ctx.db.get(args.requestId);
    if (!request || request.userId !== args.userId) {
      throw new Error("Review request not found or access denied");
    }

    await ctx.db.patch(args.requestId, {
      status: "SENT",
      sentAt: now,
      updatedAt: now,
    });

    // Return full request data so the API can send the email
    return {
      id: args.requestId,
      customerName: request.customerName,
      customerEmail: request.customerEmail,
      customerPhone: request.customerPhone,
      channel: request.channel,
      token: request.token,
      language: request.language,
    };
  },
});

/**
 * Create a review question template (per user + industry)
 * Wave 1: Reviews gap-fill
 */
export const createQuestionTemplate = mutation({
  args: {
    userId: v.string(),
    industry: v.string(),
    questions: v.any(),
    isDefault: v.optional(v.boolean()),
  },
  handler: async (ctx, args) => {
    const now = Date.now();

    // Check if a template already exists for this user + industry
    const existing = await ctx.db
      .query("review_question_templates")
      .withIndex("by_userId_industry", (q) =>
        q.eq("userId", args.userId).eq("industry", args.industry),
      )
      .unique();

    if (existing) {
      // Upsert: update the existing template instead of creating a duplicate
      await ctx.db.patch(existing._id, {
        questions: args.questions,
        isDefault: args.isDefault ?? false,
        updatedAt: now,
      });
      return existing._id;
    }

    const id = await ctx.db.insert("review_question_templates", {
      userId: args.userId,
      industry: args.industry,
      questions: args.questions,
      isDefault: args.isDefault ?? true,
      createdAt: now,
      updatedAt: now,
    });

    return id;
  },
});

/**
 * Update a review question template (verify ownership first)
 * Wave 1: Reviews gap-fill
 */
export const updateQuestionTemplate = mutation({
  args: {
    userId: v.string(),
    templateId: v.id("review_question_templates"),
    questions: v.optional(v.any()),
    industry: v.optional(v.string()),
    isDefault: v.optional(v.boolean()),
  },
  handler: async (ctx, args) => {
    const now = Date.now();

    // Verify ownership
    const template = await ctx.db.get(args.templateId);
    if (!template || template.userId !== args.userId) {
      throw new Error("Template not found or access denied");
    }

    const patch: Record<string, unknown> = { updatedAt: now };
    if (args.questions !== undefined) patch.questions = args.questions;
    if (args.industry !== undefined) patch.industry = args.industry;
    if (args.isDefault !== undefined) patch.isDefault = args.isDefault;

    // When questions are explicitly updated, mark as non-default (custom)
    if (args.questions !== undefined && args.isDefault === undefined) {
      patch.isDefault = false;
    }

    await ctx.db.patch(args.templateId, patch);
    return args.templateId;
  },
});

/**
 * Delete a review question template (verify ownership first)
 * Wave 1: Reviews gap-fill
 */
export const deleteQuestionTemplate = mutation({
  args: {
    userId: v.string(),
    templateId: v.id("review_question_templates"),
  },
  handler: async (ctx, args) => {
    // Verify ownership
    const template = await ctx.db.get(args.templateId);
    if (!template || template.userId !== args.userId) {
      throw new Error("Template not found or access denied");
    }

    await ctx.db.delete(args.templateId);
    return { deleted: true };
  },
});

/**
 * Update review widget branding settings
 * Phase 8: Content, Careers, Real Estate, Analytics, Reviews
 */
export const updateWidgetSettings = mutation({
  args: {
    userId: v.string(),
    businessName: v.optional(v.string()),
    businessNameAr: v.optional(v.string()),
    logoUrl: v.optional(v.string()),
    primaryColor: v.optional(v.string()),
    backgroundColor: v.optional(v.string()),
    textColor: v.optional(v.string()),
    thankYouMessage: v.optional(v.string()),
    thankYouMessageAr: v.optional(v.string()),
    showPoweredBy: v.optional(v.boolean()),
    customCss: v.optional(v.string()),
  },
  handler: async (ctx, args) => {
    const now = Date.now();

    // Find existing settings for user
    const existing = await ctx.db
      .query("review_widget_settings")
      .withIndex("by_userId", (q) => q.eq("userId", args.userId))
      .unique();

    const { userId, ...fields } = args;
    const patch: Record<string, unknown> = { updatedAt: now };
    for (const [key, value] of Object.entries(fields)) {
      if (value !== undefined) patch[key] = value;
    }

    if (existing) {
      await ctx.db.patch(existing._id, patch);
      return existing._id;
    }

    // Create new settings
    const id = await ctx.db.insert("review_widget_settings", {
      userId: args.userId,
      primaryColor: args.primaryColor ?? "#3B82F6",
      backgroundColor: args.backgroundColor ?? "#FFFFFF",
      textColor: args.textColor ?? "#1F2937",
      showPoweredBy: args.showPoweredBy ?? true,
      businessName: args.businessName,
      businessNameAr: args.businessNameAr,
      logoUrl: args.logoUrl,
      thankYouMessage: args.thankYouMessage,
      thankYouMessageAr: args.thankYouMessageAr,
      customCss: args.customCss,
      createdAt: now,
      updatedAt: now,
    });
    return id;
  },
});
