import { PropertyCard } from '@/types/property-card';
import { Area } from '@/types/area';

// ==================== Rental Contract Types ====================
export interface TawtheeqContractData {
  type: 'residential' | 'commercial';
  lessor_id_number?: string;
  lessor_birthdate?: string;
  lessor_phone?: string;
  property_document?: File | null;
  property_type?: string;
  property_floors?: number;
  property_rooms?: number;
  property_address?: string;
  lessor_bank_account?: string;
  lessee_id_number?: string;
  lessee_birthdate?: string;
  lessee_id_image?: File | null;
  lessee_phone?: string;
  rent_amount?: number;
  rent_start_date?: string;
  payment_cycle?: 'yearly' | 'semi_yearly' | 'quarterly' | 'monthly';
  contract_duration?: string;
  electricity_meter?: string;
  water_meter?: string;
  extra_terms?: string;
}

export interface FinanceRequestData {
  name: string;
  job?: string;
  age?: number;
  marital_status?: string;
  bank?: string;
  salary?: number;
  hiring_date?: string;
  commitments?: string;
  commitments_installments?: number;
  early_repayment?: string;
  is_supported_by_moh?: boolean;
  property_price?: number;
  id_image?: File | null;
  salary_certificate?: File | null;
}

export interface TawtheeqContractResponse {
  success: boolean;
  message: string;
  data?: any;
  errors?: any;
}

/**
 * Formats the location subtitle to a standard "Neighborhood - City" format.
 * Cleans up redundant city names and ensures the city is at the end.
 */
export function formatLocationSubtitle(address: string | null | undefined, cityName: string): string {
  if (!cityName) return address || '';
  if (!address || address.trim() === "") return cityName;

  const cleanedCity = cityName.trim();

  // Normalize names for comparison (remove common words like 'المكرمة', 'المنورة' and handle 'ة' vs 'ه')
  const normalize = (s: string) =>
    s.replace(" المكرمة", "")
      .replace(" المنورة", "")
      .replace(/ة/g, "ه")
      .trim();
  const normalizedCity = normalize(cleanedCity);

  // Split by common separators (dash, en-dash, em-dash, arabic comma, english comma, underscore)
  const parts = address.split(/[-–—_،,]/).map(p => p.trim()).filter(Boolean);

  // Use a Set to store unique parts and avoid duplicates
  const uniqueParts = new Set<string>();
  const finalParts: string[] = [];

  parts.forEach(p => {
    const normalizedPart = normalize(p);
    // Don't add if it's the city (we'll ensure city is at the end) OR if we've seen this part before
    if (normalizedPart !== normalizedCity && !uniqueParts.has(normalizedPart)) {
      uniqueParts.add(normalizedPart);
      finalParts.push(p);
    }
  });

  // If no parts left (address was just the city), return city
  if (finalParts.length === 0) return cleanedCity;

  // Append city at the end
  return `${finalParts.join(' - ')} - ${cleanedCity}`;
}

// ==================== Authentication Types ====================
export interface LoginCredentials {
  login: string; // Can be email or phone
  password: string;
}

export interface AuthClient {
  id: number;
  name: string;
  username: string;
  email: string;
  phone: string;
  client_type: string;
  address: string | null;
  national_id: string | null;
  city: string | null;
  governorate: string | null;
  avatar: string | null;
  created_at: string;
  updated_at: string;
  favorites_count?: number;
  notifications_count?: number;
  messages_count?: number;
}

export interface LoginResponse {
  message: string;
  token: string;
  client: AuthClient;
  has_package: boolean;
  package_start_date: string | null;
  package_end_date: string | null;
  package: any | null;
}

export interface AuthError {
  message: string;
  errors?: Record<string, string[]>;
  requires_activation?: boolean;
}

/**
 * Login user with email/phone and password
 */
export async function login(credentials: LoginCredentials): Promise<LoginResponse> {
  const apiUrl = process.env.NEXT_PUBLIC_API_URL;

  if (!apiUrl) {
    throw new Error('NEXT_PUBLIC_API_URL environment variable is not set');
  }

  try {
    const response = await fetch(`${apiUrl}/user/login`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
      },
      body: JSON.stringify(credentials),
    });

    let data;
    try {
      data = await response.json();
    } catch (err) {
      throw {
        message: `خطأ في الخادم (${response.status}): استجابة غير صالحة`,
        status: response.status
      };
    }

    if (!response.ok) {
      const error: AuthError = {
        message: data.message || 'فشل تسجيل الدخول',
        errors: data.errors,
        requires_activation: data.requires_activation,
      };
      throw error;
    }

    return data as LoginResponse;
  } catch (err: any) {
    if (err.message && err.status) throw err; // Already formatted as AuthError

    // Handle generic Error objects (like network errors) which normally stringify to {}
    const message = err instanceof Error ? err.message : (err.message || 'حدث خطأ غير متوقع أثناء الاتصال بالخادم');

    throw {
      message: message,
      errors: {},
      // unexpected errors don't usually require activation
      requires_activation: false
    } as AuthError;
  }
}

/**
 * Logout user and invalidate token
 */
export async function logout(token: string): Promise<void> {
  const apiUrl = process.env.NEXT_PUBLIC_API_URL;

  if (!apiUrl) {
    throw new Error('NEXT_PUBLIC_API_URL environment variable is not set');
  }

  await fetch(`${apiUrl}/user/logout`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
      'Authorization': `Bearer ${token}`,
    },
  });
}

/**
 * Get current user by token
 */
export async function getCurrentUser(token: string): Promise<AuthClient | null> {
  const apiUrl = process.env.NEXT_PUBLIC_API_URL;

  if (!apiUrl) {
    return null;
  }

  try {
    const response = await fetch(`${apiUrl}/user/profile`, {
      headers: {
        'Accept': 'application/json',
        'Authorization': `Bearer ${token}`,
      },
    });

    if (!response.ok) {
      console.error(`getCurrentUser broken: ${response.status} ${response.statusText}`);
      try {
        const text = await response.text();
        console.error('Response body:', text);
      } catch (e) {
        console.error('Could not read response body', e);
      }
      return null;
    }

    const data = await response.json();
    // The backend wraps responses in a 'data' object via the jsonResponse helper
    const user = data.data?.user || data.data?.client || data.user || data.client || null;
    if (user && !user.avatar) {
      user.avatar = '/placeholder-avatar.png';
    }
    return user;
  } catch (error) {
    console.error('getCurrentUser fetch error:', error);
    return null;
  }
}

/**
 * Create a new Tawtheeq (Rental) Contract request
 */
export async function createTawtheeqContract(data: TawtheeqContractData, token: string): Promise<TawtheeqContractResponse> {
  const apiUrl = process.env.NEXT_PUBLIC_API_URL;

  if (!apiUrl) {
    throw new Error('NEXT_PUBLIC_API_URL environment variable is not set');
  }

  const formData = new FormData();

  // Append all fields to FormData
  Object.entries(data).forEach(([key, value]) => {
    if (value !== undefined && value !== null) {
      if (value instanceof File) {
        formData.append(key, value);
      } else {
        formData.append(key, String(value));
      }
    }
  });

  try {
    const response = await fetch(`${apiUrl}/user/tawtheeq-contracts`, {
      method: 'POST',
      headers: {
        'Accept': 'application/json',
        'Authorization': `Bearer ${token}`,
      },
      body: formData,
    });

    const result = await response.json();
    return result as TawtheeqContractResponse;
  } catch (error) {
    console.error("Error creating tawtheeq contract:", error);
    return {
      success: false,
      message: 'Network error or server unavailable',
    };
  }
}

/**
 * Create a new Client Finance Request
 */
export async function createFinanceRequest(data: FinanceRequestData, token: string): Promise<any> {
  const apiUrl = process.env.NEXT_PUBLIC_API_URL;

  if (!apiUrl) {
    throw new Error('NEXT_PUBLIC_API_URL environment variable is not set');
  }

  const formData = new FormData();

  // Append all fields to FormData
  Object.entries(data).forEach(([key, value]) => {
    if (value !== undefined && value !== null) {
      if (value instanceof File) {
        formData.append(key, value);
      } else if (typeof value === 'boolean') {
        formData.append(key, value ? '1' : '0');
      } else {
        formData.append(key, String(value));
      }
    }
  });

  try {
    const response = await fetch(`${apiUrl}/user/client-finance-requests`, {
      method: 'POST',
      headers: {
        'Accept': 'application/json',
        'Authorization': `Bearer ${token}`,
      },
      body: formData,
    });

    const result = await response.json();
    return result;
  } catch (error) {
    console.error("Error creating finance request:", error);
    return {
      status: 'error',
      message: 'Network error or server unavailable',
    };
  }
}

/**
 * Request OTP verification code for a new email
 */
export async function requestOtp(email: string): Promise<{ id: number; message: string }> {
  const apiUrl = process.env.NEXT_PUBLIC_API_URL;
  if (!apiUrl) {
    throw new Error('NEXT_PUBLIC_API_URL environment variable is not set');
  }

  const response = await fetch(`${apiUrl}/user/email/request-code`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
    },
    body: JSON.stringify({ email }),
  });

  const data = await response.json();

  if (!response.ok) {
    throw new Error(data.message || 'فشل إرسال رمز التحقق');
  }

  return data;
}

/**
 * Verify OTP code
 */
export async function verifyOtp(email: string, code: string): Promise<{ id: number; email: string; code: string; is_verified: boolean; message: string }> {
  const apiUrl = process.env.NEXT_PUBLIC_API_URL;

  if (!apiUrl) {
    throw new Error('NEXT_PUBLIC_API_URL environment variable is not set');
  }

  const response = await fetch(`${apiUrl}/user/email/verify-code`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
    },
    body: JSON.stringify({ email, code }),
  });

  const data = await response.json();

  if (!response.ok) {
    throw new Error(data.message || 'رمز التحقق غير صحيح');
  }

  return data;
}

// Backend response types
interface BackendProperty {
  id: number;
  title: string;
  address: string;
  price: string;
  spaces: string;
  room: string;
  bathroom: string;
  floor: string;
  advertiser_type?: string;
  type_of_property?: string;
  is_premium: number;
  is_favorite: boolean;
  section: string;
  status: string;
  price_of_meter: string;
  living_rooms_count?: string;
  latitude?: string;
  longitude?: string;
  images: { url: string }[];
  city: {
    name: string;
  } | null;
  categories?: { id: number; title: string, en_title?: string }[];
  owner: {
    name: string;
    avatar: string | null;
    client_type?: string;
    company_name: string | null;
  } | null;
}

// Full property details from /properties/{id} endpoint
export interface PropertyDetails {
  id: number;
  title: string;
  price: string;
  to_price?: string;
  address: string;
  section: string;
  spaces: string;
  room: string;
  bathroom: string;
  floor: string;
  description: string;
  status: string;
  location_link?: string;
  property_age?: string;
  property_direction?: string;
  street_width?: string;
  is_premium: number;
  is_favorite: boolean;
  type_of_property?: string;
  advertiser_type?: string;
  owner: {
    id: number;
    type: string;
    name: string;
    phone: string;
    avatar: string | null;
    client_type?: string;
    company_name: string | null;
  } | null;
  city: { id?: number; name: string } | null;
  governorate: { id?: number; name: string } | null;
  district: { id?: number; name: string } | null;
  categories: { id: number; title: string }[];
  features: { id: number; title: string }[];
  images: { id?: number; url: string }[];
  ad_number?: string;
  created_at?: string;
  latitude?: string;
  longitude?: string;
}

interface BackendPropertyRequest {
  id: number;
  section: string;
  price: string;
  to_price: string;
  space: string;
  to_space: string;
  rooms: number;
  bathrooms: number;
  description: string;
  category: { id: number; title: string } | null;
  city: { id: number; name: string } | null;
  client: { name: string; avatar: string | null } | null;
  created_at: string;
}

interface BackendResponse {
  data: BackendProperty[];
}

interface PropertyRequestResponse {
  data: {
    data: BackendPropertyRequest[];
  };
}

interface BackendCity {
  id: number;
  name: string;
  name_en?: string;
  logo: string | null;
  properties_count?: number;
}

// --- Services Types ---
export interface Service {
  id: number;
  title: string;
  description: string;
  icon?: string;
}

interface ServicesResponse {
  data: {
    id: number;
    title: string;
    description: string;
  }[];
}

export async function getServices(): Promise<Service[]> {
  const apiUrl = process.env.NEXT_PUBLIC_API_URL;
  if (!apiUrl) throw new Error('API URL not set');

  try {
    const response = await fetch(`${apiUrl}/services`, { cache: 'no-store' });
    if (!response.ok) return [];

    const json: ServicesResponse = await response.json();
    return (json.data || []).map(s => ({
      id: s.id,
      title: s.title,
      description: s.description,
    }));
  } catch (error) {
    console.error("Error fetching services:", error);
    return [];
  }
}

interface CitiesResponse {
  data: BackendCity[];
}

// City interface for dropdowns
export interface City {
  id: number;
  name: string;
}

/**
 * Fetches all cities from the backend for use in dropdowns/filters
 */
export async function getCities(): Promise<City[]> {
  const apiUrl = process.env.NEXT_PUBLIC_API_URL;

  if (!apiUrl) {
    throw new Error('NEXT_PUBLIC_API_URL environment variable is not set');
  }

  try {
    const response = await fetch(`${apiUrl}/user/cities`, {
      cache: 'no-store',
    });

    if (!response.ok) {
      return [];
    }

    const json: CitiesResponse = await response.json();

    if (!json.data || !Array.isArray(json.data)) {
      return [];
    }

    return json.data.map((city) => ({
      id: city.id,
      name: city.name,
    }));
  } catch (error) {
    console.error("Error fetching cities:", error);
    return [];
  }
}

/**
 * Fetches all districts for a specific city
 */
export async function getDistrictsByCity(cityId: number | string): Promise<any[]> {
  const apiUrl = process.env.NEXT_PUBLIC_API_URL;
  if (!apiUrl) throw new Error('NEXT_PUBLIC_API_URL not set');

  try {
    const response = await fetch(`${apiUrl}/user/districts/by-city/${cityId}`, { cache: 'no-store' });
    if (!response.ok) return [];
    const json = await response.json();
    return json.data || [];
  } catch (error) {
    console.error("Error fetching districts:", error);
    return [];
  }
}

/**
 * Fetches all governorates for a specific city
 */
export async function getGovernoratesByCity(cityId: number | string): Promise<any[]> {
  const apiUrl = process.env.NEXT_PUBLIC_API_URL;
  if (!apiUrl) throw new Error('NEXT_PUBLIC_API_URL not set');

  try {
    const response = await fetch(`${apiUrl}/user/cities/governorates-by-city/${cityId}`, { cache: 'no-store' });
    if (!response.ok) return [];
    const json = await response.json();
    return json.data || [];
  } catch (error) {
    console.error("Error fetching governorates:", error);
    return [];
  }
}

// Category interface for dropdowns
export interface Category {
  id: number;
  title: string;
}

/**
 * Fetches all categories from the backend for use in dropdowns/filters
 */
export async function getCategories(): Promise<Category[]> {
  const apiUrl = process.env.NEXT_PUBLIC_API_URL;

  if (!apiUrl) {
    throw new Error('NEXT_PUBLIC_API_URL environment variable is not set');
  }

  try {
    const response = await fetch(`${apiUrl}/user/categories`, {
      cache: 'no-store',
    });

    if (!response.ok) {
      return [];
    }

    const json = await response.json();
    const data = json.data || [];

    if (!Array.isArray(data)) {
      return [];
    }

    return data.map((cat: any) => ({
      id: cat.id,
      title: cat.title || cat.ar_title || cat.name || '',
    }));
  } catch (error) {
    console.error("Error fetching categories:", error);
    return [];
  }
}

// Search filter interface
export interface SearchFilters {
  city_id?: string;
  section?: string;
  type?: string;
  rooms?: string;
  bathrooms?: string;
  min_price?: string;
  max_price?: string;
  min_area?: string;
  max_area?: string;
  search?: string;
  page?: number;
  per_page?: number;
}

// Search result interface
export interface SearchResult {
  properties: PropertyCard[];
  meta: {
    current_page: number;
    last_page: number;
    per_page: number;
    total: number;
  };
}

/**
 * Search properties with filters
 */
export async function searchProperties(filters: SearchFilters): Promise<SearchResult> {
  const apiUrl = process.env.NEXT_PUBLIC_API_URL;

  if (!apiUrl) {
    throw new Error('NEXT_PUBLIC_API_URL environment variable is not set');
  }

  try {
    // Build query string
    const params = new URLSearchParams();
    if (filters.city_id) params.set('city_id', filters.city_id);
    if (filters.section) params.set('section', filters.section);
    if (filters.type) params.set('type', filters.type);
    if (filters.rooms) params.set('rooms', filters.rooms);
    if (filters.bathrooms) params.set('bathrooms', filters.bathrooms);
    if (filters.min_price) params.set('min_price', filters.min_price);
    if (filters.max_price) params.set('max_price', filters.max_price);
    if (filters.min_area) params.set('min_area', filters.min_area);
    if (filters.max_area) params.set('max_area', filters.max_area);
    if (filters.search) params.set('search', filters.search);
    if (filters.page) params.set('page', filters.page.toString());
    if (filters.per_page) params.set('per_page', filters.per_page.toString());

    const response = await fetch(`${apiUrl}/properties/search?${params.toString()}`, {
      cache: 'no-store',
    });

    if (!response.ok) {
      return { properties: [], meta: { current_page: 1, last_page: 1, per_page: 24, total: 0 } };
    }

    const json = await response.json();

    if (!json.data || !json.data.data) {
      return { properties: [], meta: { current_page: 1, last_page: 1, per_page: 24, total: 0 } };
    }

    // Map backend data to PropertyCard interface
    const properties: PropertyCard[] = json.data.data.map((property: BackendProperty): PropertyCard => {
      // Format price as number with locale string
      const priceNumber = parseFloat(property.price || '0');
      const formattedPrice = priceNumber.toLocaleString();

      // Build subtitle: [Neighborhood] - [City]
      const subtitle = formatLocationSubtitle(property.address, property.city?.name || '');

      // Image with fallback
      const image = property.images?.length > 0
        ? property.images[0].url
        : '/no-image.png';

      // Badge: "مميز" if is_premium is 1, else empty string
      const badge = Number(property.is_premium) === 1 ? 'مميز' : '';

      // Parse numeric fields safely
      const area = parseInt(property.spaces || '0', 10) || 0;
      const bedrooms = parseInt(property.room || '0', 10) || 0;
      const bathrooms = parseInt(property.bathroom || '0', 10) || 0;
      const floors = parseInt(property.floor || '0', 10) || 0;

      // Company info with fallbacks
      const company = property.owner?.name || '';
      const companyLogo = property.owner?.avatar || '/placeholder-avatar.png';
      const companyTitle = translate(property.owner?.client_type);

      const clientType = translate(property.owner?.client_type || property.advertiser_type);

      return {
        id: property.id,
        title: property.title || '',
        subtitle,
        image,
        badge,
        price: formattedPrice,
        area,
        bedrooms,
        bathrooms,
        floors,
        company,
        companyLogo,
        companyTitle,
        clientType,
        propertyType: translate(property.type_of_property),
        rawPropertyType: property.type_of_property,
        categoryTitles: (property.categories || []).map((c: any) => c.en_title?.toLowerCase() || c.title?.toLowerCase() || ''),
        isFavorite: property.is_favorite ?? false,
        section: (property.section || '').includes('sale') ? 'sale' : 'rent',
        rawSection: property.section || '',
        livingRooms: parseInt(property.living_rooms_count || '0', 10) || 0,
        latitude: property.latitude ? parseFloat(property.latitude) : undefined,
        longitude: property.longitude ? parseFloat(property.longitude) : undefined,
      };
    });

    return {
      properties,
      meta: json.data.meta || { current_page: 1, last_page: 1, per_page: 24, total: properties.length },
    };
  } catch (error) {
    console.error("Error searching properties:", error);
    return { properties: [], meta: { current_page: 1, last_page: 1, per_page: 24, total: 0 } };
  }
}

// Property Request interface for search results
export interface PropertyRequestSearchItem {
  id: number;
  title: string;
  subtitle: string;
  section: string;
  badge: string;
  budget: string;
  price: string;
  area: string;
  rooms: string;
  bedrooms: number;
  bathrooms: number;
  city: string;
  propertyType: string;
  company: string;
  companyLogo: string;
  daysLeft: number;
  client: {
    name: string;
    avatar: string;
  };
}

/**
 * Get public property requests for search page
 */
export async function getPropertyRequests(filters?: { section?: string; city_id?: string; search?: string; per_page?: number; page?: number }): Promise<{
  requests: PropertyRequestSearchItem[];
  meta: { current_page: number; last_page: number; total: number };
}> {
  const apiUrl = process.env.NEXT_PUBLIC_API_URL;

  if (!apiUrl) {
    return { requests: [], meta: { current_page: 1, last_page: 1, total: 0 } };
  }

  try {
    const params = new URLSearchParams();
    if (filters?.section) params.set('section', filters.section);
    if (filters?.city_id) params.set('city_id', filters.city_id);
    if (filters?.search) params.set('search', filters.search);
    if (filters?.per_page) params.set('per_page', filters.per_page.toString());
    if (filters?.page) params.set('page', filters.page.toString());

    const response = await fetch(`${apiUrl}/property-requests?${params.toString()}`, {
      cache: 'no-store',
    });

    if (!response.ok) {
      return { requests: [], meta: { current_page: 1, last_page: 1, total: 0 } };
    }

    const json = await response.json();

    if (!json.data?.data) {
      return { requests: [], meta: { current_page: 1, last_page: 1, total: 0 } };
    }

    const requests: PropertyRequestSearchItem[] = json.data.data.map((req: any) => {
      // Calculate days left
      const createdAt = new Date(req.created_at);
      const now = new Date();
      const diffTime = Math.abs(now.getTime() - createdAt.getTime());
      const daysLeft = Math.floor(diffTime / (1000 * 60 * 60 * 24));

      // Ensure valid avatar URL (not empty string)
      const clientAvatar = req.client?.avatar && req.client.avatar !== ''
        ? req.client.avatar
        : '/placeholder-avatar.png';

      return {
        id: req.id,
        title: req.title || `طلب ${req.category?.title || 'عقار'} في ${req.city?.name || 'المنطقة'}`,
        subtitle: req.description || '',
        section: req.section || '',
        badge: req.section === 'sale' ? 'بيع' : 'إيجار',
        budget: req.budget ? `${parseFloat(req.budget).toLocaleString()} ريال` : 'غير محدد',
        price: req.budget ? `${parseFloat(req.budget).toLocaleString()}` : 'حسب السوق',
        area: req.area ? `${req.area}` : 'غير محدد',
        rooms: req.rooms || 'غير محدد',
        bedrooms: parseInt(req.rooms || '0', 10) || 0,
        bathrooms: parseInt(req.bathrooms || '0', 10) || 0,
        city: req.city?.name || 'غير محدد',
        propertyType: req.category?.title || 'عقار',
        company: req.client?.name && req.client.name !== '' ? req.client.name : 'باحث عن عقار',
        companyLogo: clientAvatar,
        daysLeft,
        client: {
          name: req.client?.name || 'مجهول',
          avatar: clientAvatar,
        },
      };
    });

    return {
      requests,
      meta: json.data.meta || { current_page: 1, last_page: 1, total: requests.length },
    };
  } catch (error) {
    console.error("Error fetching property requests:", error);
    return { requests: [], meta: { current_page: 1, last_page: 1, total: 0 } };
  }
}

// Marketing Property interface for search results
export interface MarketingPropertyItem {
  id: number;
  title: string;
  subtitle: string;
  image: string;
  price: string;
  area: number;
  rooms: number;
  bathrooms: number;
  section: string;
  owner: {
    name: string;
    avatar: string;
  };
}

/**
 * Get public marketing properties for search page
 */
export async function getMarketingProperties(filters?: { section?: string; search?: string; per_page?: number; page?: number }): Promise<{
  properties: PropertyCard[];
  meta: { current_page: number; last_page: number; total: number };
}> {
  const apiUrl = process.env.NEXT_PUBLIC_API_URL;

  if (!apiUrl) {
    return { properties: [], meta: { current_page: 1, last_page: 1, total: 0 } };
  }

  try {
    const params = new URLSearchParams();
    if (filters?.section) params.set('section', filters.section);
    if (filters?.search) params.set('search', filters.search);
    if (filters?.per_page) params.set('per_page', filters.per_page.toString());
    if (filters?.page) params.set('page', filters.page.toString());

    const response = await fetch(`${apiUrl}/properties/marketing?${params.toString()}`, {
      cache: 'no-store',
    });

    if (!response.ok) {
      return { properties: [], meta: { current_page: 1, last_page: 1, total: 0 } };
    }

    const json = await response.json();

    // Handle pagination response
    const data = json.data?.data || json.data || [];
    if (!Array.isArray(data)) {
      return { properties: [], meta: { current_page: 1, last_page: 1, total: 0 } };
    }

    const properties: PropertyCard[] = data.map((prop: any): PropertyCard => {
      const priceNumber = parseFloat(prop.price || '0');
      const formattedPrice = priceNumber.toLocaleString();

      const subtitle = formatLocationSubtitle(prop.address, prop.city?.name || '');

      const image = prop.images?.length > 0
        ? prop.images[0].url
        : '/no-image.png';

      const badge = prop.is_premium === 1 ? 'مميز' : '';

      const area = parseInt(prop.spaces || prop.area || '0', 10) || 0;
      const bedrooms = parseInt(prop.room || '0', 10) || 0;
      const bathrooms = parseInt(prop.bathroom || '0', 10) || 0;
      const floors = parseInt(prop.floor || '0', 10) || 0;

      const company = prop.owner?.name || 'ملاك';
      const companyLogo = prop.owner?.avatar || '/placeholder-avatar.png';
      const companyTitle = translate(prop.owner?.client_type);

      // Map labels for Marketing/Projects: Professional only
      let clientType = translate(prop.owner?.client_type || prop.advertiser_type);

      // Force professional label for marketing/projects section
      if (clientType === 'مالك') {
        clientType = 'شركة عقارية';
      }

      return {
        id: prop.id,
        title: prop.title || '',
        subtitle,
        image,
        badge,
        price: formattedPrice,
        area,
        bedrooms,
        bathrooms,
        floors,
        company,
        companyLogo,
        companyTitle,
        clientType,
        propertyType: translate(prop.type_of_property),
        isFavorite: prop.is_favorite ?? false,
        section: prop.section || '',
      };
    });

    return {
      properties,
      meta: json.data?.meta || { current_page: 1, last_page: 1, total: properties.length },
    };
  } catch (error) {
    console.error("Error fetching marketing properties:", error);
    return { properties: [], meta: { current_page: 1, last_page: 1, total: 0 } };
  }
}

const TRANSLATIONS: Record<string, string> = {
  // Advertiser Type (The 5 Official Types)
  'seeker': 'باحث عن عقار',
  'developer': 'مطور عقاري',
  'owner': 'مالك عقار',
  'company': 'شركة عقارية',
  'real-estate-company': 'شركة عقارية',
  'real_estate_company': 'شركة عقارية',
  'broker': 'مسوق عقاري',
  'marketer': 'مسوق عقاري',
  'agent': 'مسوق عقاري',
  'admin': 'إدارة المنصة',
  'شركة عقارية': 'شركة عقارية',
  'مطور عقاري': 'مطور عقاري',
  'وسيط': 'مسوق عقاري',

  // Property Type
  'apartment': 'شقة',
  'villa': 'فيلا',
  'house': 'منزل',
  'duplex': 'دوبلكس',
  'land': 'أرض',
  'compound': 'مجمع سكني',
  'chalet': 'شاليه',
  'floor': 'دور',
  'unit': 'وحدة',
  // 'project' is usually handled by type_of_property === 'project' logic, but good to have here
  'project': 'مشروع',
  'store': 'محل',
  'farm': 'مزرعة',
  'rest_house': 'استراحة',
  'office': 'مكتب',
  'building': 'عمارة',
  'warehouse': 'مستودع',
  'individual': 'باحث عن عقار',
};

export const translate = (value: string | undefined): string => {
  if (!value) return '';
  const key = value.toLowerCase().trim();
  return TRANSLATIONS[key] || value;
};

/**
 * Fetches properties from the Laravel backend and maps them to PropertyCard interface
 */
export async function getProperties(): Promise<PropertyCard[]> {
  const apiUrl = process.env.NEXT_PUBLIC_API_URL;

  if (!apiUrl) {
    throw new Error('NEXT_PUBLIC_API_URL environment variable is not set');
  }

  try {
    const response = await fetch(`${apiUrl}/properties`, {
      cache: 'no-store',
    });

    if (!response.ok) {
      throw new Error(`Failed to fetch properties: ${response.status} ${response.statusText}`);
    }

    const json: BackendResponse = await response.json();

    if (!json.data || !Array.isArray(json.data)) {
      throw new Error('Invalid response format: expected data array');
    }

    // Map backend properties to PropertyCard interface
    return json.data.map((property): PropertyCard => {
      // Format price as number with locale string
      const priceNumber = parseFloat(property.price || '0');
      const formattedPrice = priceNumber.toLocaleString();

      // Build subtitle: [Neighborhood] - [City]
      const subtitle = formatLocationSubtitle(property.address, property.city?.name || '');

      // استخدام no-image.png كمؤشر عند عدم وجود صور
      const image = property.images?.length > 0
        ? property.images[0].url
        : '/no-image.png';

      // Badge: "مميز" if is_premium is 1, else empty string
      const badge = Number(property.is_premium) === 1 ? 'مميز' : '';

      // Parse numeric fields safely
      const area = parseInt(property.spaces || '0', 10) || 0;
      const bedrooms = parseInt(property.room || '0', 10) || 0;
      const bathrooms = parseInt(property.bathroom || '0', 10) || 0;
      const floors = parseInt(property.floor || '0', 10) || 0;

      // Company info with fallbacks
      const company = property.owner?.name || '';
      const companyLogo = property.owner?.avatar || '/placeholder-avatar.png';
      const companyTitle = translate(property.owner?.client_type);

      const clientType = translate(property.owner?.client_type || property.advertiser_type);

      return {
        type: 'unit',
        id: property.id,
        title: property.title || '',
        subtitle,
        image,
        badge,
        price: formattedPrice,
        area,
        bedrooms,
        bathrooms,
        floors,
        company,
        companyLogo,
        companyTitle,
        clientType,
        propertyType: translate(property.type_of_property),
        rawPropertyType: property.type_of_property,
        categoryTitles: (property.categories || []).map((c: any) => c.en_title?.toLowerCase() || c.title?.toLowerCase() || ''),
        isFavorite: property.is_favorite ?? false,
        section: (property.section || '').includes('sale') ? 'sale' : 'rent',
        rawSection: property.section || '',
        livingRooms: parseInt(property.living_rooms_count || '0', 10) || 0,
        latitude: property.latitude ? parseFloat(property.latitude) : undefined,
        longitude: property.longitude ? parseFloat(property.longitude) : undefined,
      };
    });
  } catch (error) {
    if (error instanceof Error) {
      throw error;
    }
    throw new Error(`Unexpected error fetching properties: ${String(error)}`);
  }
}

// Priority cities in exact sort order for Saudi Market design
const PRIORITY_CITIES: readonly string[] = ['riyadh', 'jeddah', 'mecca', 'medina', 'dammam', 'khobar', 'abha'] as const;

// City images mapping: Local files from public/main-page/areas/
const CITY_IMAGES: Record<string, string> = {
  'riyadh': '/main-page/areas/riyadh.png',
  'mecca': '/main-page/areas/mecca.png',
  'jeddah': '/main-page/areas/jeddah.jpg',
  'medina': '/main-page/areas/medina.jpg',
  'dammam': '/main-page/areas/dammam.jpg',
  'khobar': '/main-page/areas/khobar.jpg',
  'alkhobar': '/main-page/areas/khobar.jpg',
  'abha': '/main-page/areas/abha.jpg'
};

/**
 * Fetches areas (cities) from the Laravel backend and maps them to Area interface
 * Sorted by priority order with Riyadh always first, limited to exactly 5 items for grid layout
 */
export async function getAreas(): Promise<Area[]> {
  const apiUrl = process.env.NEXT_PUBLIC_API_URL;

  if (!apiUrl) {
    throw new Error('NEXT_PUBLIC_API_URL environment variable is not set');
  }

  try {
    const response = await fetch(`${apiUrl}/user/cities`, {
      cache: 'no-store',
    });

    if (!response.ok) {
      throw new Error(`Failed to fetch areas: ${response.status} ${response.statusText}`);
    }

    const json: CitiesResponse = await response.json();

    if (!json.data || !Array.isArray(json.data)) {
      throw new Error('Invalid response format: expected data array');
    }

    // Map backend cities to Area interface
    const mappedAreas = json.data.map((city): Area => {
      // Generate image: Prioritize local images (CITY_IMAGES), then logo, then fallback
      let image = '/no-image.png';

      // Try to find a match in CITY_IMAGES first
      if (city.name_en) {
        const cityKey = city.name_en.toLowerCase().trim();
        const cityImage = CITY_IMAGES[cityKey];

        if (cityImage) {
          image = cityImage;
        } else if (city.logo) {
          image = city.logo;
        }
      } else if (city.logo) {
        image = city.logo;
      }

      // Generate link: /search?q=cityName
      const link = `/search?q=${city.name}`;

      return {
        id: city.id,
        title: city.name || '',
        image,
        count: city.properties_count || 0,
        link,
      };
    });

    // Sort by priority: ensure Riyadh is ALWAYS first, then others in priority order
    const sortedAreas = mappedAreas.sort((a, b) => {
      const cityA = json.data.find(c => c.id === a.id);
      const cityB = json.data.find(c => c.id === b.id);

      const keyA = cityA?.name_en?.toLowerCase().trim() || '';
      const keyB = cityB?.name_en?.toLowerCase().trim() || '';

      // Normalize keys (handle 'ar riyad' -> 'riyadh')
      const normalizedKeyA = keyA.replace(/\s+/g, '').replace('ar', '');
      const normalizedKeyB = keyB.replace(/\s+/g, '').replace('ar', '');

      // Riyadh always comes first
      const isRiyadhA = normalizedKeyA === 'riyadh' || keyA.includes('riyadh');
      const isRiyadhB = normalizedKeyB === 'riyadh' || keyB.includes('riyadh');

      if (isRiyadhA && !isRiyadhB) return -1;
      if (!isRiyadhA && isRiyadhB) return 1;

      // For non-Riyadh cities, sort by priority index
      const indexA = PRIORITY_CITIES.findIndex(priority =>
        normalizedKeyA === priority || keyA.includes(priority)
      );
      const indexB = PRIORITY_CITIES.findIndex(priority =>
        normalizedKeyB === priority || keyB.includes(priority)
      );

      // If both are in priority list, sort by their index
      if (indexA !== -1 && indexB !== -1) {
        return indexA - indexB;
      }
      // If only A is in priority list, A comes first
      if (indexA !== -1) {
        return -1;
      }
      // If only B is in priority list, B comes first
      if (indexB !== -1) {
        return 1;
      }
      // If neither is in priority list, maintain original order
      return 0;
    });

    // Return exactly 6 items (1 Vertical, 3 Top Small, 1 Bottom Small, 1 Bottom Wide)
    return sortedAreas.length > 6 ? sortedAreas.slice(0, 6) : sortedAreas;
  } catch (error) {
    if (error instanceof Error) {
      throw error;
    }
    throw new Error(`Unexpected error fetching areas: ${String(error)}`);
  }
}

// Agent Interface
export interface Agent {
  id: number;
  name: string;
  location: string;
  description: string;
  image: string;
  role?: string;
}

interface BackendAgent {
  id: number;
  name: string;
  avatar: string | null;
  client_type: string;
  notes: string | null;
  city: {
    name: string;
  } | null;
  company_name: string | null;
  verified: boolean;
  created_at: string;
}

interface AgentsResponse {
  data: BackendAgent[];
}

/**
 * Fetches agents (clients) from the backend with optional filtering
 */
export async function getAgents(options?: { verifiedOnly?: boolean; limit?: number }): Promise<Agent[]> {
  const apiUrl = process.env.NEXT_PUBLIC_API_URL;

  if (!apiUrl) {
    throw new Error('NEXT_PUBLIC_API_URL environment variable is not set');
  }

  try {
    const url = new URL(`${apiUrl}/clients`);

    if (options?.verifiedOnly) {
      url.searchParams.append('verified_only', '1');
    }

    if (options?.limit) {
      url.searchParams.append('limit', options.limit.toString());
    }

    const response = await fetch(url.toString(), {
      cache: 'no-store',
    });

    if (!response.ok) {
      throw new Error(`Failed to fetch agents: ${response.status} ${response.statusText}`);
    }

    const json: AgentsResponse = await response.json();

    return json.data.map((agent) => {
      const city = agent.city?.name || 'المملكة العربية السعودية';
      const location = `${city} - ${translate(agent.client_type)}`;

      return {
        id: agent.id,
        name: agent.name,
        location: location,
        description: agent.notes || 'مسوق عقاري معتمد',
        image: agent.avatar || '/placeholder-avatar.png',
        role: agent.client_type,
        verified: agent.verified,
        createdAt: agent.created_at
      };
    });

  } catch (error) {
    console.error("Error fetching agents:", error);
    return []; // Return empty array on error to prevent UI crash
  }
}

/**
 * Fetches premium properties (Projects) from the Laravel backend
 */
export async function getPremiumProjects(): Promise<any[]> {
  const apiUrl = process.env.NEXT_PUBLIC_API_URL;

  if (!apiUrl) {
    throw new Error('NEXT_PUBLIC_API_URL environment variable is not set');
  }

  try {
    const response = await fetch(`${apiUrl}/properties/premium`, {
      cache: 'no-store',
    });

    if (!response.ok) {
      throw new Error(`Failed to fetch premium properties: ${response.status} ${response.statusText}`);
    }

    const json: BackendResponse = await response.json();

    if (!json.data || !Array.isArray(json.data)) {
      return [];
    }

    // Map backend properties to PropertyCard interface
    return json.data.map((property): any => {
      // Format price as number with locale string
      const priceNumber = parseFloat(property.price || '0');
      const formattedPrice = priceNumber.toLocaleString();

      // Build subtitle: [Neighborhood] - [City]
      const subtitle = formatLocationSubtitle(property.address, property.city?.name || '');

      // Image Handling
      const image = property.images?.length > 0
        ? property.images[0].url
        : '/no-image.png';

      const badge = property.is_premium === 1 ? 'مميز' : '';

      // Parse numeric fields
      const area = parseInt(property.spaces || '0', 10) || 0;
      const priceOfMeter = parseFloat(property.price_of_meter || '0') || 0;
      const bedrooms = parseInt(property.room || '0', 10) || 0;
      const bathrooms = parseInt(property.bathroom || '0', 10) || 0;
      const floors = parseInt(property.floor || '0', 10) || 0;

      // Company info
      const company = property.owner?.name || 'Unknown';
      const companyLogo = property.owner?.avatar || '/placeholder-avatar.png';
      const companyTitle = translate(property.owner?.client_type);

      // Projects number (Hardcoded fallback as it's missing in backend)
      const projectsno = "مشروع متميز";

      // Map labels for Projects: Professional only
      let clientType = translate(property.owner?.client_type || property.advertiser_type);

      // Force professional label for projects section
      if (clientType === 'مالك') {
        clientType = 'شركة عقارية';
      }

      return {
        type: 'project',
        id: property.id,
        title: property.title || '',
        subtitle,
        image,
        badge,
        price: formattedPrice,
        area,
        bedrooms,
        bathrooms,
        floors,
        company,
        companyLogo,
        companyTitle,
        clientType,
        propertyType: translate(property.type_of_property),
        rawPropertyType: property.type_of_property,
        categoryTitles: (property.categories || []).map((c: any) => c.en_title?.toLowerCase() || c.title?.toLowerCase() || ''),
        rawProjectStatus: property.status,
        isFavorite: property.is_favorite ?? false,
        section: (property.section || '').includes('sale') ? 'sale' : 'rent',
        rawSection: property.section || '',
        livingRooms: parseInt(property.living_rooms_count || '0', 10) || 0,
        bathrooms_count: bathrooms,
        projectsno,
        latitude: property.latitude ? parseFloat(property.latitude) : undefined,
        longitude: property.longitude ? parseFloat(property.longitude) : undefined,
      };
    });

  } catch (error) {
    console.error("Error fetching premium projects:", error);
    return [];
  }
}

/**
 * Fetches a single property by ID from the backend
 */
export async function getPropertyById(id: number | string): Promise<PropertyDetails | null> {
  const apiUrl = process.env.NEXT_PUBLIC_API_URL;

  if (!apiUrl) {
    throw new Error('NEXT_PUBLIC_API_URL environment variable is not set');
  }

  try {
    const response = await fetch(`${apiUrl}/properties/${id}`, {
      cache: 'no-store',
    });

    if (!response.ok) {
      if (response.status === 404) {
        return null;
      }
      throw new Error(`Failed to fetch property: ${response.status} ${response.statusText}`);
    }

    const json = await response.json();

    // The backend returns { status, code, message, data }
    const property = json.data;

    if (!property) {
      return null;
    }

    return {
      id: property.id,
      title: property.title || '',
      price: property.price || '0',
      to_price: property.to_price,
      address: property.address || '',
      section: property.section || '',
      spaces: property.spaces || '0',
      room: property.room || '0',
      bathroom: property.bathroom || '0',
      floor: property.floor || '0',
      description: property.description || '',
      status: property.status || '',
      location_link: property.location_link,
      property_age: property.property_age,
      property_direction: property.property_direction,
      street_width: property.street_width,
      is_premium: property.is_premium || 0,
      is_favorite: property.is_favorite || false,
      type_of_property: property.type_of_property,
      advertiser_type: property.advertiser_type,
      owner: property.owner ? {
        id: property.owner.id,
        type: property.owner.type || 'Client',
        name: property.owner.name || '',
        phone: property.owner.phone || '',
        avatar: property.owner.avatar,
        client_type: property.owner.client_type,
        company_name: property.owner.company_name || null,
      } : null,
      city: property.city ? { id: property.city.id, name: property.city.name } : null,
      governorate: property.governorate ? { id: property.governorate.id, name: property.governorate.name } : null,
      district: property.district ? { id: property.district.id, name: property.district.name } : null,
      categories: (property.categories || []).map((c: { id: number; title: string }) => ({ id: c.id, title: c.title })),
      features: (property.features || []).map((f: { id: number; title: string }) => ({ id: f.id, title: f.title })),
      images: (property.images || []).map((img: { id?: number; url: string }) => ({ id: img.id, url: img.url })),
      ad_number: property.ad_number,
      created_at: property.created_at,
      latitude: property.latitude,
      longitude: property.longitude,
    };

  } catch (error) {
    console.error("Error fetching property by ID:", error);
    return null;
  }
}