import { mutation, internalMutation } from "../_generated/server";
import { v } from "convex/values";
import { socialPlatformValidator } from "../schema/social";

/**
 * Create a new post in the content queue
 * Phase 5: Social Media
 */
export const createPost = mutation({
  args: {
    socialAccountId: v.string(),
    platform: v.string(),
    content: v.string(),
    hashtags: v.optional(v.array(v.string())),
    mediaUrls: v.optional(v.array(v.string())),
  },
  handler: async (ctx, args) => {
    const now = Date.now();
    return await ctx.db.insert("social_content_queue", {
      socialAccountId: args.socialAccountId,
      platform: args.platform as
        | "INSTAGRAM"
        | "FACEBOOK"
        | "TIKTOK"
        | "TWITTER",
      content: args.content,
      hashtags: args.hashtags ?? [],
      mediaUrls: args.mediaUrls ?? [],
      status: "DRAFT",
      retryCount: 0,
      createdAt: now,
      updatedAt: now,
    });
  },
});

/**
 * Schedule a post for future publishing
 * Phase 5: Social Media
 */
export const schedulePost = mutation({
  args: {
    id: v.id("social_content_queue"),
    scheduledAt: v.number(),
  },
  handler: async (ctx, args) => {
    await ctx.db.patch(args.id, {
      scheduledAt: args.scheduledAt,
      status: "SCHEDULED",
      updatedAt: Date.now(),
    });
  },
});

/**
 * Update post status (draft -> scheduled -> published / failed)
 * Phase 5: Social Media
 */
export const updatePostStatus = mutation({
  args: {
    id: v.id("social_content_queue"),
    status: v.string(),
    platformPostId: v.optional(v.string()),
    platformUrl: v.optional(v.string()),
    errorMessage: v.optional(v.string()),
  },
  handler: async (ctx, args) => {
    const updates: Record<string, unknown> = {
      status: args.status as
        | "DRAFT"
        | "SCHEDULED"
        | "PUBLISHING"
        | "PUBLISHED"
        | "FAILED",
      updatedAt: Date.now(),
    };
    if (args.platformPostId !== undefined) {
      updates.platformPostId = args.platformPostId;
    }
    if (args.platformUrl !== undefined) {
      updates.platformUrl = args.platformUrl;
    }
    if (args.errorMessage !== undefined) {
      updates.errorMessage = args.errorMessage;
    }
    if (args.status === "PUBLISHED") {
      updates.publishedAt = Date.now();
    }
    await ctx.db.patch(args.id, updates);
  },
});

/**
 * Internal version of updatePostStatus for use from actions
 */
export const updatePostStatusInternal = internalMutation({
  args: {
    id: v.id("social_content_queue"),
    status: v.string(),
    platformPostId: v.optional(v.string()),
    platformUrl: v.optional(v.string()),
    errorMessage: v.optional(v.string()),
  },
  handler: async (ctx, args) => {
    const updates: Record<string, unknown> = {
      status: args.status as
        | "DRAFT"
        | "SCHEDULED"
        | "PUBLISHING"
        | "PUBLISHED"
        | "FAILED",
      updatedAt: Date.now(),
    };
    if (args.platformPostId !== undefined) {
      updates.platformPostId = args.platformPostId;
    }
    if (args.platformUrl !== undefined) {
      updates.platformUrl = args.platformUrl;
    }
    if (args.errorMessage !== undefined) {
      updates.errorMessage = args.errorMessage;
    }
    if (args.status === "PUBLISHED") {
      updates.publishedAt = Date.now();
    }
    await ctx.db.patch(args.id, updates);
  },
});

/**
 * Mark a social inbox message as read
 * Phase 5: Social Media
 */
export const markMessageRead = mutation({
  args: { id: v.id("social_messages") },
  handler: async (ctx, args) => {
    await ctx.db.patch(args.id, {
      isRead: true,
      updatedAt: Date.now(),
    });
  },
});

/**
 * Connect a social media account
 * Phase 5: Social Media
 */
export const connectAccount = mutation({
  args: {
    userId: v.string(),
    platform: v.string(),
    platformAccountId: v.string(),
    accountName: v.string(),
    accessToken: v.string(),
    refreshToken: v.optional(v.string()),
    tokenExpiry: v.optional(v.number()),
    metadata: v.optional(v.any()),
  },
  handler: async (ctx, args) => {
    const now = Date.now();
    return await ctx.db.insert("social_accounts", {
      userId: args.userId,
      platform: args.platform as
        | "INSTAGRAM"
        | "FACEBOOK"
        | "TIKTOK"
        | "TWITTER",
      platformAccountId: args.platformAccountId,
      accountName: args.accountName,
      accessToken: args.accessToken,
      refreshToken: args.refreshToken,
      tokenExpiry: args.tokenExpiry,
      status: "CONNECTED",
      metadata: args.metadata,
      createdAt: now,
      updatedAt: now,
    });
  },
});

/**
 * Disconnect a social media account
 * Phase 5: Social Media
 */
export const disconnectAccount = mutation({
  args: { id: v.id("social_accounts") },
  handler: async (ctx, args) => {
    await ctx.db.delete(args.id);
  },
});

/**
 * Delete a social account (alias for disconnectAccount, uses string ID)
 * Phase 5: Social Media (gap-fill for route wiring)
 */
export const deleteAccount = mutation({
  args: { id: v.id("social_accounts") },
  handler: async (ctx, args) => {
    await ctx.db.delete(args.id);
  },
});

/**
 * Upsert a social media account (connect or update existing)
 * Used by OAuth callback to create/update accounts after token exchange.
 * Phase 5: Social Media (gap-fill for callback route wiring)
 */
export const upsertAccount = mutation({
  args: {
    userId: v.string(),
    platform: socialPlatformValidator,
    platformAccountId: v.string(),
    accountName: v.string(),
    accessToken: v.string(),
    refreshToken: v.optional(v.string()),
    tokenExpiry: v.optional(v.number()),
    metadata: v.optional(v.any()),
  },
  handler: async (ctx, args) => {
    const now = Date.now();

    // Check if account already exists
    const existing = await ctx.db
      .query("social_accounts")
      .withIndex("by_userId_platform_platformAccountId", (q) =>
        q
          .eq("userId", args.userId)
          .eq("platform", args.platform)
          .eq("platformAccountId", args.platformAccountId),
      )
      .unique();

    if (existing) {
      // Update existing account
      await ctx.db.patch(existing._id, {
        accountName: args.accountName,
        accessToken: args.accessToken,
        refreshToken: args.refreshToken,
        tokenExpiry: args.tokenExpiry,
        status: "CONNECTED" as const,
        metadata: args.metadata,
        updatedAt: now,
      });
      return existing._id;
    }

    // Create new account
    return await ctx.db.insert("social_accounts", {
      userId: args.userId,
      platform: args.platform,
      platformAccountId: args.platformAccountId,
      accountName: args.accountName,
      accessToken: args.accessToken,
      refreshToken: args.refreshToken,
      tokenExpiry: args.tokenExpiry,
      status: "CONNECTED",
      metadata: args.metadata,
      createdAt: now,
      updatedAt: now,
    });
  },
});
