"use server";

/**
 * Google Contacts Server Actions
 *
 * Server actions for importing contacts from Google.
 * Used by the "Add from Google" feature in the customers module.
 *
 * @module lib/actions/google-contacts.actions
 */

import { auth } from "@/lib/auth";
import { logger } from "@/lib/logger";
import {
  fetchGoogleContacts,
  fetchGoogleOtherContacts,
  hasGoogleOAuthConnection,
  SimplifiedContact,
} from "@/lib/services/google-oauth.service";
import { prisma } from "@/lib/db";
import { createId } from "@paralleldrive/cuid2";
import { revalidatePath } from "next/cache";

export interface GoogleContactsResult {
  success: boolean;
  contacts?: SimplifiedContact[];
  nextPageToken?: string;
  totalItems?: number;
  error?: string;
  needsReconnect?: boolean;
}

export interface ImportContactsResult {
  success: boolean;
  imported?: number;
  skipped?: number;
  errors?: string[];
}

/**
 * Check if user has Google OAuth connected with contacts permission
 */
export async function checkGoogleContactsConnection(): Promise<{
  connected: boolean;
  needsReconnect: boolean;
  hasContactsScope: boolean;
}> {
  try {
    const session = await auth();

    if (!session?.user?.id) {
      return {
        connected: false,
        needsReconnect: false,
        hasContactsScope: false,
      };
    }

    return await hasGoogleOAuthConnection(session.user.id);
  } catch (error) {
    logger.error("Error checking Google contacts connection", error);
    return {
      connected: false,
      needsReconnect: false,
      hasContactsScope: false,
    };
  }
}

/**
 * Fetch Google Contacts for the current user
 */
export async function getGoogleContacts(
  options: {
    pageSize?: number;
    pageToken?: string;
    query?: string;
    includeOther?: boolean;
  } = {},
): Promise<GoogleContactsResult> {
  try {
    const session = await auth();

    if (!session?.user?.id) {
      return {
        success: false,
        error: "Not authenticated",
      };
    }

    const userId = session.user.id;

    // Check connection
    const connectionStatus = await hasGoogleOAuthConnection(userId);

    if (!connectionStatus.connected) {
      return {
        success: false,
        error: "Google account not connected",
        needsReconnect: connectionStatus.needsReconnect,
      };
    }

    if (!connectionStatus.hasContactsScope) {
      return {
        success: false,
        error: "Contacts permission not granted",
        needsReconnect: true,
      };
    }

    const { pageSize = 50, pageToken, query, includeOther = false } = options;

    // Fetch main contacts
    const result = await fetchGoogleContacts(userId, {
      pageSize,
      pageToken,
      query,
    });

    if (!result) {
      return {
        success: false,
        error: "Failed to fetch contacts",
        needsReconnect: true,
      };
    }

    let allContacts = result.contacts;

    // Optionally include other contacts
    if (includeOther && !pageToken) {
      const otherResult = await fetchGoogleOtherContacts(userId, {
        pageSize: Math.min(pageSize, 50),
      });

      if (otherResult) {
        allContacts = [...allContacts, ...otherResult.contacts];
      }
    }

    // Remove duplicates
    const seen = new Set<string>();
    const uniqueContacts = allContacts.filter((contact) => {
      const key = contact.email || contact.phone || contact.id;
      if (seen.has(key)) return false;
      seen.add(key);
      return true;
    });

    return {
      success: true,
      contacts: uniqueContacts,
      nextPageToken: result.nextPageToken,
      totalItems: result.totalItems,
    };
  } catch (error) {
    logger.error("Error in getGoogleContacts action", error);
    return {
      success: false,
      error: "An unexpected error occurred",
    };
  }
}

/**
 * Import selected Google contacts into the customers table
 */
export async function importGoogleContacts(
  contacts: Array<{
    name: string;
    email?: string;
    phone?: string;
    company?: string;
  }>,
): Promise<ImportContactsResult> {
  try {
    const session = await auth();

    if (!session?.user?.id) {
      return {
        success: false,
        errors: ["Not authenticated"],
      };
    }

    const userId = session.user.id;
    let imported = 0;
    let skipped = 0;
    const errors: string[] = [];

    for (const contact of contacts) {
      try {
        // Skip contacts without phone (required field)
        if (!contact.phone) {
          skipped++;
          continue;
        }

        // Clean phone number (remove spaces, dashes, etc.)
        const cleanPhone = contact.phone.replace(/[\s\-()]/g, "");

        // Check if customer already exists with this phone
        const existing = await prisma.customers.findUnique({
          where: {
            userId_phone: {
              userId,
              phone: cleanPhone,
            },
          },
        });

        if (existing) {
          skipped++;
          continue;
        }

        // Create new customer
        await prisma.customers.create({
          data: {
            id: createId(),
            userId,
            name: contact.name || "Unknown",
            phone: cleanPhone,
            email: contact.email || null,
            notes: contact.company ? `Company: ${contact.company}` : null,
            source: "import",
            updatedAt: new Date(),
          },
        });

        imported++;
      } catch (contactError) {
        logger.error("Error importing single contact", {
          contact,
          error: contactError,
        });
        errors.push(`Failed to import ${contact.name || contact.phone}`);
      }
    }

    // Revalidate the customers page
    revalidatePath("/[lang]/dashboard");
    revalidatePath("/[lang]/dashboard/customers");

    logger.info("Google contacts import completed", {
      userId,
      imported,
      skipped,
      errors: errors.length,
    });

    return {
      success: true,
      imported,
      skipped,
      errors: errors.length > 0 ? errors : undefined,
    };
  } catch (error) {
    logger.error("Error in importGoogleContacts action", error);
    return {
      success: false,
      errors: ["An unexpected error occurred"],
    };
  }
}

/**
 * Get the Google OAuth sign-in URL for connecting/reconnecting
 */
export async function getGoogleSignInUrl(): Promise<string> {
  // NextAuth handles the OAuth flow automatically
  // Just return the sign-in URL that triggers Google OAuth
  return "/api/auth/signin/google";
}
