"use server";

import { revalidatePath } from "next/cache";
import { headers } from "next/headers";
import { requireAuth } from "@/lib/auth/guard";
import { getCurrentUser } from "@/lib/auth/user";
import { createClient } from "@/lib/supabase/server";
import { createAdminClient } from "@/lib/supabase/admin";

import {
  createLeadSchema,
  updateLeadStatusSchema,
  scheduleViewingSchema,
  updateViewingStatusSchema,
  recordContactClickSchema,
  CreateLeadInput,
  UpdateLeadStatusInput,
  ScheduleViewingInput,
  UpdateViewingStatusInput,
  RecordContactClickInput,
} from "@/lib/validation/lead.schema";
import {
  updateLeadStatus,
  scheduleViewingAppointment,
  updateViewingAppointmentStatus,
} from "@/lib/services/lead.service";
import { sendLeadInquiryEmails, sendViewingScheduledEmails } from "@/lib/services/email.service";
import { leadSubmissionRateLimit, checkRateLimit } from "@/lib/ratelimit";

export async function createLeadAction(input: CreateLeadInput) {
  try {
    // 1. Rate Limiting via Upstash
    const headerList = await headers();
    const clientIp = headerList.get("x-forwarded-for") || "127.0.0.1";
    const { success: allowed } = await checkRateLimit(leadSubmissionRateLimit, `lead:${clientIp}`);

    if (!allowed) {
      return {
        success: false,
        error: "Too many inquiries submitted. Please wait a few minutes before sending another.",
      };
    }

    const validated = createLeadSchema.parse(input);
    const supabase = createAdminClient();
    const currentUser = await getCurrentUser().catch(() => null);

    // Fetch property creator / assigned agent with contact info
    const { data: property } = await supabase
      .from("properties")
      .select(`
        id, title, reference_code, slug, created_by_user_id, agency_id, assigned_agent_id,
        creator:users!properties_created_by_user_id_fkey(email, first_name, last_name, phone_number),
        assigned_agent:users!properties_assigned_agent_id_fkey(email, first_name, last_name, phone_number)
      `)
      .eq("id", validated.propertyId)
      .single();

    if (!property) {
      return { success: false, error: "Property not found" };
    }

    const assignedUserId = property.assigned_agent_id || property.created_by_user_id;
    const isViewing = validated.inquiryType === "SCHEDULE_VIEWING";
    const initialStatus = isViewing ? "VIEWING_SCHEDULED" : "NEW";
    const leadSource = validated.source || (isViewing ? "VIEWING_BOOKING" : "MARKETPLACE_CARD");

    const { data: lead, error } = await supabase
      .from("leads")
      .insert({
        property_id: validated.propertyId,
        agency_id: property.agency_id || null,
        assigned_to_user_id: assignedUserId,
        user_id: currentUser?.id || null,
        full_name: validated.clientName,
        client_name: validated.clientName,
        email: validated.clientEmail,
        client_email: validated.clientEmail,
        phone_number: validated.clientPhone || "",
        client_phone: validated.clientPhone || null,
        whatsapp_number: validated.clientPhone || null,
        message: validated.message,
        inquiry_type: validated.inquiryType,
        preferred_viewing_date: validated.preferredViewingDate ? new Date(validated.preferredViewingDate).toISOString() : null,
        source: leadSource,
        status: initialStatus,
      })
      .select("*")
      .single();

    if (error || !lead) {
      return { success: false, error: error?.message || "Failed to submit inquiry" };
    }

    // If booking a viewing, create the viewing appointment record immediately
    let appointment = null;
    if (isViewing && validated.preferredViewingDate) {
      const scheduledIso = new Date(validated.preferredViewingDate).toISOString();
      const { data: aptData } = await supabase
        .from("viewing_appointments")
        .insert({
          lead_id: lead.id,
          property_id: validated.propertyId,
          scheduled_by_user_id: assignedUserId,
          scheduled_at: scheduledIso,
          scheduled_for: scheduledIso,
          duration_minutes: 60,
          meeting_type: validated.meetingType || "PHYSICAL",
          notes: validated.message,
          status: "SCHEDULED",
        })
        .select("*")
        .single();
      appointment = aptData;
    }

    // Trigger Resend email notification asynchronously
    const recipientAgent = (property.assigned_agent || property.creator) as any;
    sendLeadInquiryEmails({
      lead: {
        id: lead.id,
        client_name: validated.clientName,
        client_email: validated.clientEmail,
        client_phone: validated.clientPhone,
        inquiry_type: validated.inquiryType,
        message: validated.message,
      },
      property: {
        title: property.title,
        reference_code: property.reference_code,
        slug: property.slug,
      },
      agent: recipientAgent,
    }).catch(() => {});

    if (appointment && validated.preferredViewingDate) {
      sendViewingScheduledEmails({
        appointment: {
          scheduled_at: appointment.scheduled_at || appointment.scheduled_for,
          meeting_type: appointment.meeting_type || "PHYSICAL",
          meeting_location: appointment.meeting_location || property.title,
          notes: appointment.notes,
        },
        lead: {
          client_name: validated.clientName,
          client_email: validated.clientEmail,
          client_phone: validated.clientPhone,
        },
        property: {
          title: property.title,
        },
        agent: recipientAgent,
      }).catch(() => {});
    }

    revalidatePath("/dashboard/leads");
    revalidatePath("/dashboard");
    return { success: true, lead, appointment };
  } catch (err: unknown) {
    const message = err instanceof Error ? err.message : "Failed to create inquiry";
    return { success: false, error: message };
  }
}

/**
 * Record user click on Direct Call or WhatsApp contact buttons
 * Dynamically registers inquiry into the listing agent's CRM pipeline
 */
export async function recordContactClickAction(input: RecordContactClickInput) {
  try {
    const validated = recordContactClickSchema.parse(input);
    const supabase = createAdminClient();
    const currentUser = await getCurrentUser().catch(() => null);

    const { data: property } = await supabase
      .from("properties")
      .select(`
        id, title, reference_code, slug, created_by_user_id, agency_id, assigned_agent_id,
        creator:users!properties_created_by_user_id_fkey(email, first_name, last_name, phone_number),
        assigned_agent:users!properties_assigned_agent_id_fkey(email, first_name, last_name, phone_number)
      `)
      .eq("id", validated.propertyId)
      .single();

    if (!property) {
      return { success: false, error: "Property not found" };
    }

    const assignedUserId = property.assigned_agent_id || property.created_by_user_id;
    const channelLabel = validated.channel === "CALL" ? "Direct Call" : "WhatsApp";
    const leadSource = validated.channel === "CALL" ? "DIRECT_CALL" : "WHATSAPP";
    const inquiryType = validated.channel === "CALL" ? "DIRECT_CALL" : "WHATSAPP_INQUIRY";

    const clientName =
      validated.clientName ||
      (currentUser ? `${currentUser.first_name || ""} ${currentUser.last_name || ""}`.trim() : null) ||
      (validated.channel === "CALL" ? "Prospective Buyer (Direct Call)" : "Prospective Buyer (WhatsApp)");

    const clientEmail = currentUser?.email || `${validated.channel.toLowerCase()}-inquiry@nigerialisting.com`;
    const clientPhone = validated.clientPhone || currentUser?.phone_number || "";

    const { data: lead, error } = await supabase
      .from("leads")
      .insert({
        property_id: validated.propertyId,
        agency_id: property.agency_id || null,
        assigned_to_user_id: assignedUserId,
        user_id: currentUser?.id || null,
        full_name: clientName,
        client_name: clientName,
        email: clientEmail,
        client_email: clientEmail,
        phone_number: clientPhone,
        client_phone: clientPhone || null,
        whatsapp_number: validated.channel === "WHATSAPP" ? clientPhone || null : null,
        message: `Client initiated ${channelLabel} interaction on listing "${property.title}" (${property.reference_code || property.id.slice(0, 8)}).`,
        inquiry_type: inquiryType,
        source: leadSource,
        status: "CONTACTED",
      })
      .select("*")
      .single();

    if (error) {
      console.warn("[ContactClickAction error]:", error.message);
      return { success: false, error: error.message };
    }

    revalidatePath("/dashboard/leads");
    revalidatePath("/dashboard");
    return { success: true, leadId: lead?.id };
  } catch (err: unknown) {
    const message = err instanceof Error ? err.message : "Failed to record contact click";
    return { success: false, error: message };
  }
}


export async function updateLeadStatusAction(input: UpdateLeadStatusInput) {
  try {
    const user = await requireAuth();
    const validated = updateLeadStatusSchema.parse(input);

    const result = await updateLeadStatus(
      user,
      validated.leadId,
      validated.status,
      validated.lostReason
    );

    if (!result.success) {
      return { success: false, error: result.error };
    }

    revalidatePath("/dashboard/leads");
    revalidatePath(`/dashboard/leads/${validated.leadId}`);
    return { success: true, lead: result.lead };
  } catch (err: unknown) {
    const message = err instanceof Error ? err.message : "Failed to update lead status";
    return { success: false, error: message };
  }
}

export async function scheduleViewingAction(input: ScheduleViewingInput) {
  try {
    const user = await requireAuth();
    const validated = scheduleViewingSchema.parse(input);

    const result = await scheduleViewingAppointment(user, validated);
    if (!result.success) {
      return { success: false, error: result.error };
    }

    revalidatePath("/dashboard/leads");
    revalidatePath(`/dashboard/leads/${validated.leadId}`);
    return { success: true, appointment: result.appointment };
  } catch (err: unknown) {
    const message = err instanceof Error ? err.message : "Failed to schedule viewing";
    return { success: false, error: message };
  }
}

export async function updateViewingStatusAction(input: UpdateViewingStatusInput) {
  try {
    const user = await requireAuth();
    const validated = updateViewingStatusSchema.parse(input);

    const result = await updateViewingAppointmentStatus(user, validated);
    if (!result.success) {
      return { success: false, error: result.error };
    }

    revalidatePath("/dashboard/leads");
    return { success: true };
  } catch (err: unknown) {
    const message = err instanceof Error ? err.message : "Failed to update viewing status";
    return { success: false, error: message };
  }
}
