import api from './api';

// Types
export interface AgentType {
  id: string;
  name: string;
  slug: string;
  description: string | null;
}

export interface AgentProfile {
  id: string;
  userId: string;
  firstName: string;
  lastName: string;
  slug: string;
  email: string | null;
  phone: string | null;
  bio: string | null;
  headline: string | null;
  avatar: string | null;
  licenseNumber: string | null;
  experience: number | null;
  specializations: string[];
  languages: string[];
  serviceAreas: string[];
  city: string | null;
  state: string | null;
  country: string | null;
  rating: number | null;
  reviewCount: number;
  isVerified: boolean;
  isFeatured: boolean;
  isActive: boolean;
  isAvailable: boolean;
  agentTypeId: string | null;
  agentType: AgentType | null;
  verificationStatus?: string;
  verificationNote?: string | null;
  user?: {
    id: string;
    email: string;
    avatar: string | null;
  };
}

interface ApiResponse<T> {
  success: boolean;
  data: T;
  message?: string;
}

export interface FieldValueInput {
  fieldSlug: string;
  value: string | number | boolean | string[] | Record<string, unknown> | Record<string, unknown>[] | null;
}

export interface FieldValueResponse {
  fieldSlug: string;
  fieldName: string;
  fieldType: string;
  sectionSlug: string;
  sectionName: string;
  value: unknown;
  valueLabel?: unknown;
}

export interface GetFieldValuesResponse {
  agentProfileId: string;
  fieldValues: FieldValueResponse[];
}

export interface SaveFieldValuesResponse {
  message: string;
  savedCount: number;
  data: unknown[];
}

// Search parameters for public agent search
export interface SearchAgentsParams {
  search?: string;
  location?: string;
  city?: string;
  state?: string;
  country?: string;
  agentTypeId?: string;
  isVerified?: boolean;
  page?: number;
  limit?: number;
  sortBy?: 'createdAt' | 'averageRating' | 'totalReviews' | 'firstName';
  sortOrder?: 'asc' | 'desc';
  filters?: Record<string, string[]>;
}

// Field value from search response
export interface AgentFieldValue {
  id: string;
  fieldId: string;
  textValue: string | null;
  numberValue: number | null;
  booleanValue: boolean | null;
  jsonValue: unknown;
  dateValue: string | null;
  field: {
    slug: string;
    name: string;
    fieldType: string;
  };
}

// Public agent listing response
export interface PublicAgentProfile {
  id: string;
  firstName: string;
  lastName: string;
  slug: string;
  email: string | null;
  phone: string | null;
  bio: string | null;
  avatar: string | null;
  licenseNumber: string | null;
  experience: number | null;
  specializations: string[];
  languages: string[];
  serviceAreas: string[];
  city: string | null;
  state: string | null;
  country: string | null;
  rating: number | null;
  reviewCount: number;
  isVerified: boolean;
  isFeatured: boolean;
  isAvailable: boolean;
  agentTypeId: string | null;
  agentType: AgentType | null;
  createdAt?: string;
  fieldValues?: AgentFieldValue[];
  matchPercentage?: number;
}

export interface SearchAgentsResponse {
  data: PublicAgentProfile[];
  total: number;
  page: number;
  limit: number;
  totalPages: number;
}

// Agents Service for Web
class AgentsService {
  private basePath = '/agents';

  async getMyProfile(): Promise<AgentProfile> {
    const response = await api.get<ApiResponse<AgentProfile>>(`${this.basePath}/profile/me`);
    return response.data.data;
  }

  async getAgentById(id: string): Promise<AgentProfile> {
    const response = await api.get<ApiResponse<AgentProfile>>(`${this.basePath}/${id}`);
    return response.data.data;
  }

  async updateProfile(data: Partial<AgentProfile>): Promise<AgentProfile> {
    const response = await api.put<ApiResponse<AgentProfile>>(`${this.basePath}/profile`, data);
    return response.data.data;
  }

  async saveFieldValues(fieldValues: FieldValueInput[]): Promise<SaveFieldValuesResponse> {
    const response = await api.put<ApiResponse<SaveFieldValuesResponse>>(
      `${this.basePath}/profile/field-values`,
      { fieldValues }
    );
    return response.data.data;
  }

  async getFieldValues(): Promise<GetFieldValuesResponse> {
    const response = await api.get<ApiResponse<GetFieldValuesResponse>>(
      `${this.basePath}/profile/field-values`
    );
    return response.data.data;
  }

  async getFieldValuesByAgentId(id: string): Promise<GetFieldValuesResponse> {
    const response = await api.get<ApiResponse<GetFieldValuesResponse>>(
      `${this.basePath}/${id}/field-values`
    );
    return response.data.data;
  }

  async getAgentTypes(): Promise<AgentType[]> {
    const response = await api.get<ApiResponse<AgentType[]>>('/agent-types');
    return response.data.data;
  }

  async getFeaturedAgents(limit = 3): Promise<PublicAgentProfile[]> {
    const response = await api.get<ApiResponse<PublicAgentProfile[]>>(`/agents/featured?limit=${limit}`);
    return response.data.data;
  }

  async searchAgents(params: SearchAgentsParams = {}): Promise<SearchAgentsResponse> {
    const queryParams = new URLSearchParams();

    if (params.search) queryParams.set('search', params.search);
    if (params.location) queryParams.set('location', params.location);
    if (params.city) queryParams.set('city', params.city);
    if (params.state) queryParams.set('state', params.state);
    if (params.country) queryParams.set('country', params.country);
    if (params.agentTypeId) queryParams.set('agentTypeId', params.agentTypeId);
    if (params.isVerified !== undefined) queryParams.set('isVerified', String(params.isVerified));
    if (params.page) queryParams.set('page', String(params.page));
    if (params.limit) queryParams.set('limit', String(params.limit));
    if (params.sortBy) queryParams.set('sortBy', params.sortBy);
    if (params.sortOrder) queryParams.set('sortOrder', params.sortOrder);
    if (params.filters && Object.keys(params.filters).length > 0) {
      queryParams.set('filters', JSON.stringify(params.filters));
    }

    const queryString = queryParams.toString();
    const url = queryString ? `${this.basePath}?${queryString}` : this.basePath;

    const response = await api.get<ApiResponse<{ data: PublicAgentProfile[]; meta: { total: number; page: number; limit: number; totalPages: number } }>>(url);
    const result = response.data.data;
    return {
      data: result.data,
      total: result.meta.total,
      page: result.meta.page,
      limit: result.meta.limit,
      totalPages: result.meta.totalPages,
    };
  }
}

export const agentsService = new AgentsService();
