/* eslint-disable @typescript-eslint/no-explicit-any */
import {Getter, inject} from '@loopback/core';
import {BelongsToAccessor, DefaultCrudRepository, repository} from '@loopback/repository';
import {DblelloDataSource} from '../datasources';
import {BuyerMaster, LogProperty, LogPropertyRelations, PostPropertyMaster, SellerMaster, Usertype} from '../models';
import {BuyerMasterRepository} from './buyer-master.repository';
import {PostPropertyMasterRepository} from './post-property-master.repository';
import {SellerMasterRepository} from './seller-master.repository';
import {UsertypeRepository} from './usertype.repository';

export class LogPropertyRepository extends DefaultCrudRepository<
  LogProperty,
  typeof LogProperty.prototype.logPropertyId,
  LogPropertyRelations
> {

  public readonly usertype: BelongsToAccessor<Usertype, typeof LogProperty.prototype.logPropertyId>;
  public readonly buyer: BelongsToAccessor<BuyerMaster, typeof LogProperty.prototype.logPropertyId>;
  public readonly seller: BelongsToAccessor<SellerMaster, typeof LogProperty.prototype.logPropertyId>;
  public readonly postProperty: BelongsToAccessor<PostPropertyMaster, typeof LogProperty.prototype.logPropertyId>;

  constructor(
    @inject('datasources.dblello') dataSource: DblelloDataSource,
    @repository.getter('UsertypeRepository') protected usertypeRepoGetter: Getter<UsertypeRepository>,
    @repository.getter('BuyerMasterRepository') protected buyerRepoGetter: Getter<BuyerMasterRepository>,
    @repository.getter('SellerMasterRepository') protected sellerRepoGetter: Getter<SellerMasterRepository>,
    @repository.getter('PostPropertyMasterRepository') protected postPropertyRepoGetter: Getter<PostPropertyMasterRepository>,
  ) {
    super(LogProperty, dataSource);
    this.usertype = this.createBelongsToAccessorFor('usertype', usertypeRepoGetter);
    this.buyer = this.createBelongsToAccessorFor('buyer', buyerRepoGetter);
    this.seller = this.createBelongsToAccessorFor('seller', sellerRepoGetter);
    this.postProperty = this.createBelongsToAccessorFor('postProperty', postPropertyRepoGetter);

    this.registerInclusionResolver('usertype', this.usertype.inclusionResolver);
    this.registerInclusionResolver('buyer', this.buyer.inclusionResolver);
    this.registerInclusionResolver('seller', this.seller.inclusionResolver);
    this.registerInclusionResolver('postProperty', this.postProperty.inclusionResolver);

    // Override the default inclusion resolver for buyer to only include when fkUsertypeId = 1
    this.registerInclusionResolver('buyer', async (entities: LogProperty[]) => {
      const buyerRepo = await buyerRepoGetter();
      const results: (BuyerMaster | undefined)[] = [];

      for (const entity of entities) {
        // Only fetch buyer if usertype is 1 (buyer)
        if (entity.fkUsertypeId === 1 && entity.fkBuyerIdSellerId) {
          try {
            const buyer = await buyerRepo.findById(entity.fkBuyerIdSellerId, {
              include: [{relation: 'city'}, {relation: 'gender'}, {relation: 'usertype'}]
            });
            results.push(buyer);
          } catch (error) {
            // Buyer not found, push undefined
            results.push(undefined);
          }
        } else {
          // Not a buyer, push undefined
          results.push(undefined);
        }
      }

      return results;
    });

    // Override the default inclusion resolver for seller to only include when fkUsertypeId != 1
    this.registerInclusionResolver('seller', async (entities: LogProperty[]) => {
      const sellerRepo = await sellerRepoGetter();
      const results: (SellerMaster | undefined)[] = [];

      for (const entity of entities) {
        // Only fetch seller if usertype is NOT 1 (i.e., seller or other)
        if (entity.fkUsertypeId !== 1 && entity.fkBuyerIdSellerId) {
          try {
            const seller = await sellerRepo.findById(entity.fkBuyerIdSellerId, {
              include: [{relation: 'city'}, {relation: 'package'}, {relation: 'user'}, {relation: 'gender'}]
            });
            results.push(seller);
          } catch (error) {
            // Seller not found, push undefined
            results.push(undefined);
          }
        } else {
          // Not a seller, push undefined
          results.push(undefined);
        }
      }

      return results;
    });
  }
}
