import { createClient } from "@/lib/supabase/server";
import { UpdateProfileInput } from "@/lib/validation/profile.schema";
import { SystemRoleId } from "@/types/auth";
import { UserRow } from "@/types/database";
import { logAuditEvent } from "./audit.service";
import { invalidateCache, cacheKeys } from "@/lib/redis";
import { normalizeAgentSlug } from "@/lib/utils";

/**
 * Updates a user's profile details
 */
export async function updateUserProfile(
  userId: string,
  input: UpdateProfileInput
): Promise<{ success: boolean; user?: UserRow; error?: string }> {
  const supabase = await createClient();

  const { data: oldUser } = await supabase
    .from("users")
    .select("*")
    .eq("id", userId)
    .single();

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

  const currentMeta = (oldUser.metadata as Record<string, unknown>) || {};
  const updatedMeta: Record<string, unknown> = { ...currentMeta };

  if (input.headline !== undefined) updatedMeta.headline = input.headline;
  if (input.bio !== undefined) updatedMeta.bio = input.bio;
  if (input.experienceYears !== undefined) updatedMeta.experience_years = input.experienceYears;
  if (input.specializations !== undefined) updatedMeta.specializations = input.specializations;
  if (input.licenseNumber !== undefined) updatedMeta.license_number = input.licenseNumber;
  if (input.websiteUrl !== undefined) updatedMeta.website_url = input.websiteUrl;
  if (input.storeAddress !== undefined) {
    updatedMeta.store_address = input.storeAddress;
    updatedMeta.office_address = input.storeAddress;
  }
  if (input.storeState !== undefined) updatedMeta.store_state = input.storeState;
  if (input.storeCity !== undefined) updatedMeta.store_city = input.storeCity;
  if (input.notifyInquiries !== undefined) updatedMeta.notify_inquiries = input.notifyInquiries;
  if (input.notifyModeration !== undefined) updatedMeta.notify_moderation = input.notifyModeration;
  if (input.notifyPayments !== undefined) updatedMeta.notify_payments = input.notifyPayments;
  if (input.notifyMaintenance !== undefined) updatedMeta.notify_maintenance = input.notifyMaintenance;

  const updateData: Partial<UserRow> = {
    first_name: input.firstName,
    last_name: input.lastName,
    phone_number: input.phoneNumber || null,
    whatsapp_number: input.whatsappNumber || null,
    metadata: updatedMeta,
    updated_at: new Date().toISOString(),
  };

  if (input.avatarUrl !== undefined) {
    updateData.avatar_url = input.avatarUrl;
  }

  const { data: updatedUser, error } = await supabase
    .from("users")
    .update(updateData)
    .eq("id", userId)
    .select("*")
    .single();

  if (error || !updatedUser) {
    return { success: false, error: error?.message || "Failed to update profile" };
  }

  // Audit log profile update
  await logAuditEvent({
    actor: { ...updatedUser, roles: [], permissions: [] },
    action: "user.profile_updated",
    entityType: "user",
    entityId: userId,
    oldState: oldUser,
    newState: updatedUser,
  });

  // Invalidate cached agent profile
  try {
    const fullName = `${updatedUser.first_name || ""} ${updatedUser.last_name || ""}`.trim();
    const slug = normalizeAgentSlug(fullName);
    await invalidateCache(
      cacheKeys.agentProfile(userId),
      cacheKeys.agentProfile(slug)
    );
  } catch {
    // ignore cache failure
  }

  return { success: true, user: updatedUser as UserRow };
}

/**
 * Switch or enable a role for the user (e.g. CUSTOMER -> PROPERTY_OWNER or AGENT)
 */
export async function switchUserRole(
  userId: string,
  targetRole: SystemRoleId
): Promise<{ success: boolean; error?: string }> {
  const allowedSelfRoles: SystemRoleId[] = ["CUSTOMER", "PROPERTY_OWNER"];

  if (!allowedSelfRoles.includes(targetRole)) {
    return {
      success: false,
      error: `Role ${targetRole} cannot be self-assigned. Becoming a Verified Agent requires KYC Accreditation approval.`,
    };
  }

  const supabase = await createClient();

  // Add role if not present
  const { error } = await supabase
    .from("user_roles")
    .upsert({
      user_id: userId,
      role_id: targetRole,
    });

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

  return { success: true };
}

/**
 * Fetches dashboard summary statistics for the user
 */
export async function getUserDashboardStats(userId: string) {
  const supabase = await createClient();

  // Active listings count
  const { count: listingsCount } = await supabase
    .from("properties")
    .select("id", { count: "exact", head: true })
    .eq("created_by_user_id", userId)
    .is("deleted_at", null);

  // Published listings count
  const { count: publishedCount } = await supabase
    .from("properties")
    .select("id", { count: "exact", head: true })
    .eq("created_by_user_id", userId)
    .eq("status", "PUBLISHED")
    .is("deleted_at", null);

  // Total Leads received
  const { count: leadsCount } = await supabase
    .from("leads")
    .select("id", { count: "exact", head: true })
    .or(`assigned_to_user_id.eq.${userId},property_id.in.(${
      `(SELECT id FROM properties WHERE created_by_user_id = '${userId}')`
    })`);

  // Agency affiliations
  const { data: agencyMemberships } = await supabase
    .from("agency_members")
    .select("agency:agencies(id, name, slug, logo_url, is_verified), role")
    .eq("user_id", userId)
    .eq("is_active", true);

  return {
    totalListings: listingsCount || 0,
    publishedListings: publishedCount || 0,
    totalLeads: leadsCount || 0,
    agencies: agencyMemberships || [],
  };
}
