import { ProfileRepository } from '@app/domain/profiles/profile.repository';
import { from, map, Observable } from 'rxjs';
import { Profile, ProfilePaginated } from '@app/domain/profiles/profile.model';
import { Injectable } from '@angular/core';
import PocketBase, { ListResult } from 'pocketbase';
import { environment } from '@env/environment';
import { ProfileDTO } from '@app/domain/profiles/dto/create-profile.dto';
import { SearchFilters } from '@app/domain/search/search-filters';
import { SettingsProfileDto } from '@app/domain/profiles/dto/settings-profile.dto';

@Injectable({ providedIn: 'root' })
export class PbProfileRepository implements ProfileRepository {
  private pb = new PocketBase(environment.baseUrl);

  private defaultOptions = {
    expand: 'utilisateur,secteur',
  };

  list(params?: SearchFilters): Observable<ProfilePaginated> {
    const requestOptions = {
      ...this.defaultOptions,
      sort: this.onSortSetting(params),
      filter: this.onFilterSetting(params).join(' && '),
    };

    return from(
      this.pb.collection('profiles').getList<Profile>(params?.page, params?.perPage, requestOptions)
    );
  }

  getById(profileId: string): Observable<Profile> {
    return from(
      this.pb.collection('profiles').getOne<Profile>(`${profileId}`, { expand: 'utilisateur' })
    );
  }

  getByUserId(userId: string): Observable<Profile> {
    return from(
      this.pb
        .collection('profiles')
        .getFirstListItem<Profile>(`utilisateur.id="${userId}"`, { expand: 'utilisateur' })
    );
  }

  create(profile: ProfileDTO): Observable<Profile> {
    return from(this.pb.collection('profiles').create<Profile>(profile));
  }

  update(id: string, data: Partial<Profile>): Observable<Profile> {
    return from(this.pb.collection('profiles').update<Profile>(id, data));
  }

  updateCoordinates(profileId: string, latitude: number, longitude: number): Observable<Profile> {
    const coordinates = { lat: latitude, lon: longitude };
    return from(
      this.pb.collection('profiles').update<Profile>(profileId, { coordonnees: coordinates })
    );
  }

  updateSettings(profileId: string, settings: SettingsProfileDto): Observable<Profile> {
    const settingsData = {
      estVisible: settings.isProfilePublic,
      estGeolocaliser: settings.allowGeolocation,
      partageMail: settings.showEmail,
      partagePhone: settings.showPhone,
    };
    return from(this.pb.collection('profiles').update<Profile>(profileId, settingsData));
  }

  private onFilterSetting(params?: SearchFilters): string[] {
    const filters: string[] = [
      'utilisateur.verified = true',
      "utilisateur.name != ''",
      "profession != 'Profession non renseignée'",
      "secteur != ''",
    ];

    if (params) {
      if (params.secteur) {
        filters.push(`secteur.nom ~ '${params.secteur}'`);
      }

      if (params.profession) {
        filters.push(`profession ~ '${params.profession}'`);
      }
      if (params.search) {
        filters.push(`utilisateur.name ~ '${params.search}'`);
      }

      if (params.verified) {
        filters.push('estVerifier = true');
      }
    }

    return filters;
  }

  private onSortSetting(params?: SearchFilters): string {
    let sortSetting = '-created';

    if (params?.sort) {
      switch (params.sort) {
        case 'recent':
          sortSetting = '-created'; // Du plus récent au plus vieux
          break;
        case 'name-asc':
          sortSetting = '+utilisateur.name'; // Alphabétique A-Z
          break;
        case 'name-desc':
          sortSetting = '-utilisateur.name'; // Alphabétique Z-A
          break;
        case 'verified':
          sortSetting = '-estVerifier,-created';
          break;
        default:
          sortSetting = '-created';
      }
    }

    return sortSetting;
  }
}
