import { apiClient } from './api-client';

// ─── Enums ───────────────────────────────────────────────

export type TransactionType = 'SALE' | 'RENT';
export type PropertyType = 'APARTMENT' | 'HOUSE' | 'VILLA' | 'LAND' | 'OFFICE' | 'SHOPHOUSE';
export type ListingStatus =
  | 'DRAFT'
  | 'PENDING_REVIEW'
  | 'ACTIVE'
  | 'RESERVED'
  | 'SOLD'
  | 'RENTED'
  | 'EXPIRED'
  | 'REJECTED';
export type Direction =
  | 'NORTH'
  | 'SOUTH'
  | 'EAST'
  | 'WEST'
  | 'NORTHEAST'
  | 'NORTHWEST'
  | 'SOUTHEAST'
  | 'SOUTHWEST';

// ─── Interfaces ──────────────────────────────────────────

export interface PropertyMedia {
  id: string;
  url: string;
  type: 'image' | 'video';
  order: number;
  caption: string | null;
}

export interface ListingDetail {
  id: string;
  status: ListingStatus;
  transactionType: TransactionType;
  priceVND: string;
  pricePerM2: number | null;
  rentPriceMonthly: string | null;
  commissionPct: number | null;
  viewCount: number;
  saveCount: number;
  inquiryCount: number;
  publishedAt: string | null;
  createdAt: string;
  property: {
    id: string;
    propertyType: PropertyType;
    title: string;
    description: string;
    address: string;
    ward: string;
    district: string;
    city: string;
    areaM2: number;
    bedrooms: number | null;
    bathrooms: number | null;
    floors: number | null;
    direction: Direction | null;
    yearBuilt: number | null;
    legalStatus: string | null;
    amenities: string[] | null;
    projectName: string | null;
    media: PropertyMedia[];
  };
  seller: {
    id: string;
    fullName: string;
    phone: string;
  };
  agent: {
    id: string;
    userId: string;
    agency: string | null;
  } | null;
}

export interface PaginatedResult<T> {
  data: T[];
  total: number;
  page: number;
  limit: number;
  totalPages: number;
}

export interface CreateListingPayload {
  transactionType: TransactionType;
  priceVND: string;
  propertyType: PropertyType;
  title: string;
  description: string;
  address: string;
  ward: string;
  district: string;
  city: string;
  latitude: number;
  longitude: number;
  areaM2: number;
  usableAreaM2?: number;
  bedrooms?: number;
  bathrooms?: number;
  floors?: number;
  floor?: number;
  totalFloors?: number;
  direction?: Direction;
  yearBuilt?: number;
  legalStatus?: string;
  amenities?: string[];
  projectName?: string;
  rentPriceMonthly?: string;
  commissionPct?: number;
}

export interface SearchListingsParams {
  status?: ListingStatus;
  transactionType?: TransactionType;
  propertyType?: PropertyType;
  city?: string;
  district?: string;
  minPrice?: string;
  maxPrice?: string;
  minArea?: number;
  maxArea?: number;
  bedrooms?: number;
  page?: number;
  limit?: number;
}

// ─── API Functions ───────────────────────────────────────

const API_BASE_URL = process.env['NEXT_PUBLIC_API_URL'] || 'http://localhost:3001/api/v1';

export const listingsApi = {
  create: (data: CreateListingPayload) =>
    apiClient.post<{ listingId: string; propertyId: string; status: string }>(
      '/listings',
      data,
    ),

  getById: (id: string) => apiClient.get<ListingDetail>(`/listings/${id}`),

  search: (params: SearchListingsParams = {}) => {
    const query = new URLSearchParams();
    Object.entries(params).forEach(([key, value]) => {
      if (value !== undefined && value !== '') query.append(key, String(value));
    });
    const qs = query.toString();
    return apiClient.get<PaginatedResult<ListingDetail>>(`/listings${qs ? `?${qs}` : ''}`);
  },

  updateStatus: (id: string, status: ListingStatus, moderationNotes?: string) =>
    apiClient.post<{ status: string }>(`/listings/${id}/status`, {
      status,
      moderationNotes,
    }),

  uploadMedia: async (listingId: string, file: File, caption?: string) => {
    const formData = new FormData();
    formData.append('file', file);
    if (caption) formData.append('caption', caption);

    const csrfToken = typeof document !== 'undefined'
      ? document.cookie.match(/(?:^|;\s*)XSRF-TOKEN=([^;]*)/)?.[1]
      : undefined;

    const headers: HeadersInit = {};
    if (csrfToken) {
      headers['X-CSRF-Token'] = decodeURIComponent(csrfToken);
    }

    const res = await fetch(`${API_BASE_URL}/listings/${listingId}/media`, {
      method: 'POST',
      credentials: 'include',
      headers,
      body: formData,
    });

    if (!res.ok) {
      const error = await res.json().catch(() => ({ message: res.statusText }));
      throw new Error(error.message || 'Upload failed');
    }

    return res.json() as Promise<{ mediaId: string; url: string }>;
  },
};
