import type { NotificationInterface } from '../models/notification.interface';
import type { NotificationSettingInterface } from '../models/notification-setting.interface';
import type { OccupationCategorizationInterface } from '../models/occupation-categorization.interface';
import { JobService } from '../services/job.service';
import { NotificationService } from '../services/notification.service';
import { PlacesService } from '../services/places.service';

export class AiJobAgentViewModel {
  constructor(
    private notificationService: NotificationService = new NotificationService(),
    private jobService: JobService = new JobService(),
    private placesService: PlacesService = new PlacesService(),
  ) {}

  async getNotificationSettings(): Promise<NotificationSettingInterface[]> {
    const settings = await this.notificationService.getNotificationSetting();
    return Array.isArray(settings) ? settings : [];
  }

  async getOccupationTree(): Promise<OccupationCategorizationInterface[]> {
    const tree = await this.jobService.getOccupationCategorizations();
    return Array.isArray(tree) ? tree : [];
  }

  async getNotifications(offset: number, limit: number): Promise<NotificationInterface[]> {
    const notifications = await this.notificationService.getNotifications(offset, limit);
    return Array.isArray(notifications) ? notifications : [];
  }

  async saveNotificationSetting(selectedId: number | 'new', setting: NotificationSettingInterface): Promise<void> {
    if (selectedId === 'new') {
      const payload = { ...setting };
      delete (payload as Partial<NotificationSettingInterface>).id;
      await this.notificationService.createNotificationSetting(payload);
      return;
    }
    await this.notificationService.updateNotificationSetting(selectedId, setting);
  }

  async deleteNotificationSetting(id: number): Promise<void> {
    await this.notificationService.deleteNotificationSetting(id);
  }

  async markNotificationSeen(id: number): Promise<void> {
    await this.notificationService.notificationSeenByUser(id);
  }

  async toggleNotificationBookmark(notification: NotificationInterface, save: boolean): Promise<void> {
    const hasJobnet = Boolean(notification.jobnetPostingId);
    const jobId = hasJobnet ? notification.jobnetPostingId : notification.jobPostingId;
    if (!jobId) {
      return;
    }
    await this.jobService.bookmarkJobV2(jobId, save, hasJobnet ? 'star' : 'arbejd.com');
  }

  async searchPlaces(query: string): Promise<Array<{ place_id?: string; description?: string }>> {
    const response = (await this.placesService.searchPlaces(query)) as {
      predictions?: Array<{ place_id?: string; description?: string }>;
    };
    return response.predictions ?? [];
  }

  async getPlaceDetails(placeId: string): Promise<{
    address: string;
    latitude: number | null;
    longitude: number | null;
  } | null> {
    const response = (await this.placesService.getPlaceDetails(placeId)) as {
      result?: {
        formatted_address?: string;
        geometry?: { location?: { lat?: number; lng?: number } };
      };
    };

    const result = response.result;
    if (!result?.formatted_address) {
      return null;
    }

    return {
      address: result.formatted_address,
      latitude: typeof result.geometry?.location?.lat === 'number' ? result.geometry.location.lat : null,
      longitude: typeof result.geometry?.location?.lng === 'number' ? result.geometry.location.lng : null,
    };
  }
}

export const aiJobAgentViewModel = new AiJobAgentViewModel();
