/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-unused-vars */
import {
  Count,
  CountSchema,
  Filter,
  FilterExcludingWhere,
  repository,
  Where,
} from '@loopback/repository';
import {
  del,
  get,
  getModelSchemaRef,
  param,
  patch,
  post,
  put,
  requestBody,
  response,
} from '@loopback/rest';
import {LogProperty, LogPropertyRelations} from '../models';
import {LogPropertyRepository} from '../repositories';

export class LogPropertyController {
  constructor(
    @repository(LogPropertyRepository)
    public logPropertyRepository: LogPropertyRepository,
  ) { }

  // Helper function to remove unwanted fields from log property
  private cleanLogProperty(logProperty: any): any {
    const {
      isDefault,
      isOn,
      isActive,
      createdDate,
      createdBy,
      modifiedDate,
      modifiedBy,
      deletedDate,
      deletedBy,
      deleteRemark,
      lastChanged,
      ...cleanedLogProperty
    } = logProperty;

    return cleanedLogProperty;
  }

  // Helper function to clean nested objects
  private cleanNestedObjects(logProperty: any): any {
    // Clean usertype if exists
    if (logProperty.usertype) {
      const {
        isDefault: userTypeIsDefault,
        isOn: userTypeIsOn,
        isActive: userTypeIsActive,
        createdDate: userTypeCreatedDate,
        createdBy: userTypeCreatedBy,
        modifiedDate: userTypeModifiedDate,
        modifiedBy: userTypeModifiedBy,
        deletedDate: userTypeDeletedDate,
        deletedBy: userTypeDeletedBy,
        deleteRemark: userTypeDeleteRemark,
        lastChanged: userTypeLastChanged,
        ...cleanedUsertype
      } = logProperty.usertype;

      logProperty.usertype = cleanedUsertype;
    }

    // Clean buyer if exists
    if (logProperty.buyer) {
      const {
        isDefault: buyerIsDefault,
        isOn: buyerIsOn,
        isActive: buyerIsActive,
        createdDate: buyerCreatedDate,
        createdBy: buyerCreatedBy,
        modifiedDate: buyerModifiedDate,
        modifiedBy: buyerModifiedBy,
        deletedDate: buyerDeletedDate,
        deletedBy: buyerDeletedBy,
        deleteRemark: buyerDeleteRemark,
        lastChanged: buyerLastChanged,
        ...cleanedBuyer
      } = logProperty.buyer;

      // Clean nested city if exists
      if (cleanedBuyer.city) {
        const {
          isDefault: cityIsDefault,
          isOn: cityIsOn,
          isActive: cityIsActive,
          createdDate: cityCreatedDate,
          createdBy: cityCreatedBy,
          modifiedDate: cityModifiedDate,
          modifiedBy: cityModifiedBy,
          deletedDate: cityDeletedDate,
          deletedBy: cityDeletedBy,
          deleteRemark: cityDeleteRemark,
          lastChanged: cityLastChanged,
          ...cleanedCity
        } = cleanedBuyer.city;

        cleanedBuyer.city = cleanedCity;
      }

      // Clean nested gender if exists
      if (cleanedBuyer.gender) {
        const {
          isDefault: genderIsDefault,
          isOn: genderIsOn,
          isActive: genderIsActive,
          createdDate: genderCreatedDate,
          createdBy: genderCreatedBy,
          modifiedDate: genderModifiedDate,
          modifiedBy: genderModifiedBy,
          deletedDate: genderDeletedDate,
          deletedBy: genderDeletedBy,
          deleteRemark: genderDeleteRemark,
          lastChanged: genderLastChanged,
          ...cleanedGender
        } = cleanedBuyer.gender;

        cleanedBuyer.gender = cleanedGender;
      }

      // Clean nested usertype if exists
      if (cleanedBuyer.usertype) {
        const {
          isDefault: buyerUserTypeIsDefault,
          isOn: buyerUserTypeIsOn,
          isActive: buyerUserTypeIsActive,
          createdDate: buyerUserTypeCreatedDate,
          createdBy: buyerUserTypeCreatedBy,
          modifiedDate: buyerUserTypeModifiedDate,
          modifiedBy: buyerUserTypeModifiedBy,
          deletedDate: buyerUserTypeDeletedDate,
          deletedBy: buyerUserTypeDeletedBy,
          deleteRemark: buyerUserTypeDeleteRemark,
          lastChanged: buyerUserTypeLastChanged,
          ...cleanedBuyerUsertype
        } = cleanedBuyer.usertype;

        cleanedBuyer.usertype = cleanedBuyerUsertype;
      }

      logProperty.buyer = cleanedBuyer;
    }

    // Clean seller if exists
    if (logProperty.seller) {
      const {
        isDefault: sellerIsDefault,
        isOn: sellerIsOn,
        isActive: sellerIsActive,
        createdDate: sellerCreatedDate,
        createdBy: sellerCreatedBy,
        modifiedDate: sellerModifiedDate,
        modifiedBy: sellerModifiedBy,
        deletedDate: sellerDeletedDate,
        deletedBy: sellerDeletedBy,
        deleteRemark: sellerDeleteRemark,
        lastChanged: sellerLastChanged,
        ...cleanedSeller
      } = logProperty.seller;

      // Clean nested city if exists
      if (cleanedSeller.city) {
        const {
          isDefault: cityIsDefault,
          isOn: cityIsOn,
          isActive: cityIsActive,
          createdDate: cityCreatedDate,
          createdBy: cityCreatedBy,
          modifiedDate: cityModifiedDate,
          modifiedBy: cityModifiedBy,
          deletedDate: cityDeletedDate,
          deletedBy: cityDeletedBy,
          deleteRemark: cityDeleteRemark,
          lastChanged: cityLastChanged,
          ...cleanedCity
        } = cleanedSeller.city;

        cleanedSeller.city = cleanedCity;
      }

      // Clean nested package if exists
      if (cleanedSeller.package) {
        const {
          isDefault: packageIsDefault,
          isOn: packageIsOn,
          isActive: packageIsActive,
          createdDate: packageCreatedDate,
          createdBy: packageCreatedBy,
          modifiedDate: packageModifiedDate,
          modifiedBy: packageModifiedBy,
          deletedDate: packageDeletedDate,
          deletedBy: packageDeletedBy,
          deleteRemark: packageDeleteRemark,
          lastChanged: packageLastChanged,
          ...cleanedPackage
        } = cleanedSeller.package;
        cleanedSeller.package = cleanedPackage;
      }

      // Clean nested user if exists
      if (cleanedSeller.user) {
        const {
          isDefault: userIsDefault,
          isOn: userIsOn,
          isActive: userIsActive,
          createdDate: userCreatedDate,
          createdBy: userCreatedBy,
          modifiedDate: userModifiedDate,
          modifiedBy: userModifiedBy,
          deletedDate: userDeletedDate,
          deletedBy: userDeletedBy,
          deleteRemark: userDeleteRemark,
          lastChanged: userLastChanged,
          ...cleanedUser
        } = cleanedSeller.user;

        cleanedSeller.user = cleanedUser;
      }

      // Clean nested gender if exists
      if (cleanedSeller.gender) {
        const {
          isDefault: genderIsDefault,
          isOn: genderIsOn,
          isActive: genderIsActive,
          createdDate: genderCreatedDate,
          createdBy: genderCreatedBy,
          modifiedDate: genderModifiedDate,
          modifiedBy: genderModifiedBy,
          deletedDate: genderDeletedDate,
          deletedBy: genderDeletedBy,
          deleteRemark: genderDeleteRemark,
          lastChanged: genderLastChanged,
          ...cleanedGender
        } = cleanedSeller.gender;

        cleanedSeller.gender = cleanedGender;
      }

      logProperty.seller = cleanedSeller;
    }

    // Clean postProperty if exists
    if (logProperty.postProperty) {
      const {
        isDefault: postPropertyIsDefault,
        isOn: postPropertyIsOn,
        isActive: postPropertyIsActive,
        createdDate: postPropertyCreatedDate,
        createdBy: postPropertyCreatedBy,
        modifiedDate: postPropertyModifiedDate,
        modifiedBy: postPropertyModifiedBy,
        deletedDate: postPropertyDeletedDate,
        deletedBy: postPropertyDeletedBy,
        deleteRemark: postPropertyDeleteRemark,
        lastChanged: postPropertyLastChanged,
        ...cleanedPostProperty
      } = logProperty.postProperty;



      logProperty.postProperty = cleanedPostProperty;
    }

    return logProperty;
  }

  @post('/log-properties')
  @response(200, {
    description: 'LogProperty model instance',
    content: {'application/json': {schema: getModelSchemaRef(LogProperty)}},
  })
  async create(
    @requestBody({
      content: {
        'application/json': {
          schema: getModelSchemaRef(LogProperty, {
            title: 'NewLogProperty',
            exclude: ['logPropertyId'],
          }),
        },
      },
    })
    logProperty: Omit<LogProperty, 'logPropertyId'>,
  ): Promise<LogProperty> {
    return this.logPropertyRepository.create(logProperty);
  }

  @get('/log-properties/count')
  @response(200, {
    description: 'LogProperty model count',
    content: {'application/json': {schema: CountSchema}},
  })
  async count(
    @param.where(LogProperty) where?: Where<LogProperty>,
  ): Promise<Count> {
    return this.logPropertyRepository.count(where);
  }

  @get('/log-properties')
  @response(200, {
    description: 'Array of LogProperty model instances with relations',
    content: {
      'application/json': {
        schema: {
          type: 'array',
          items: getModelSchemaRef(LogProperty, {includeRelations: true}),
        },
      },
    },
  })
  async find(
    @param.filter(LogProperty) filter?: Filter<LogProperty>,
  ): Promise<(LogProperty & LogPropertyRelations)[]> {
    // Include usertype, buyer, and seller relations
    const enhancedFilter = {
      ...filter,
      include: [
        {relation: 'usertype'},
        {relation: 'buyer'},
        {relation: 'seller'},
        {relation: 'postProperty'}
      ],
    };
    const logProperties = await this.logPropertyRepository.find(enhancedFilter);

    // Clean each log property
    return logProperties.map(logProperty => {
      let cleanedLogProperty = this.cleanLogProperty(logProperty);
      cleanedLogProperty = this.cleanNestedObjects(cleanedLogProperty);
      return cleanedLogProperty;
    });
  }

  @patch('/log-properties')
  @response(200, {
    description: 'LogProperty PATCH success count',
    content: {'application/json': {schema: CountSchema}},
  })
  async updateAll(
    @requestBody({
      content: {
        'application/json': {
          schema: getModelSchemaRef(LogProperty, {partial: true}),
        },
      },
    })
    logProperty: LogProperty,
    @param.where(LogProperty) where?: Where<LogProperty>,
  ): Promise<Count> {
    return this.logPropertyRepository.updateAll(logProperty, where);
  }

  @get('/log-properties/{id}')
  @response(200, {
    description: 'LogProperty model instance with relations',
    content: {
      'application/json': {
        schema: getModelSchemaRef(LogProperty, {includeRelations: true}),
      },
    },
  })
  async findById(
    @param.path.number('id') id: number,
    @param.filter(LogProperty, {exclude: 'where'}) filter?: FilterExcludingWhere<LogProperty>
  ): Promise<LogProperty & LogPropertyRelations> {
    // Include usertype, buyer, and seller relations
    const enhancedFilter = {
      ...filter,
      include: [
        {relation: 'usertype'},
        {relation: 'buyer'},
        {relation: 'seller'},
        {relation: 'postProperty'}
      ],
    };
    const logProperty = await this.logPropertyRepository.findById(id, enhancedFilter);

    // Clean the log property
    let cleanedLogProperty = this.cleanLogProperty(logProperty);
    cleanedLogProperty = this.cleanNestedObjects(cleanedLogProperty);

    return cleanedLogProperty;
  }

  @patch('/log-properties/{id}')
  @response(204, {
    description: 'LogProperty PATCH success',
  })
  async updateById(
    @param.path.number('id') id: number,
    @requestBody({
      content: {
        'application/json': {
          schema: getModelSchemaRef(LogProperty, {partial: true}),
        },
      },
    })
    logProperty: LogProperty,
  ): Promise<void> {
    await this.logPropertyRepository.updateById(id, logProperty);
  }

  @put('/log-properties/{id}')
  @response(204, {
    description: 'LogProperty PUT success',
  })
  async replaceById(
    @param.path.number('id') id: number,
    @requestBody() logProperty: LogProperty,
  ): Promise<void> {
    await this.logPropertyRepository.replaceById(id, logProperty);
  }

  @del('/log-properties/{id}')
  @response(204, {
    description: 'LogProperty DELETE success',
  })
  async deleteById(@param.path.number('id') id: number): Promise<void> {
    await this.logPropertyRepository.deleteById(id);
  }

  // Get logs by buyer ID
  @get('/log-properties/buyer/{buyerId}')
  @response(200, {
    description: 'Array of LogProperty for a specific buyer',
    content: {
      'application/json': {
        schema: {
          type: 'array',
          items: getModelSchemaRef(LogProperty, {includeRelations: true}),
        },
      },
    },
  })
  async findByBuyer(
    @param.path.number('buyerId') buyerId: number,
  ): Promise<(LogProperty & LogPropertyRelations)[]> {
    const logProperties = await this.logPropertyRepository.find({
      where: {
        fkBuyerIdSellerId: buyerId,
        fkUsertypeId: 1, // Buyer usertype
      },
      include: [
        {relation: 'usertype'},
        {relation: 'buyer'},
        {relation: 'postProperty'}
      ],
    });

    // Clean each log property
    return logProperties.map(logProperty => {
      let cleanedLogProperty = this.cleanLogProperty(logProperty);
      cleanedLogProperty = this.cleanNestedObjects(cleanedLogProperty);
      return cleanedLogProperty;
    });
  }

  // Get logs by seller ID
  @get('/log-properties/seller/{sellerId}')
  @response(200, {
    description: 'Array of LogProperty for a specific seller',
    content: {
      'application/json': {
        schema: {
          type: 'array',
          items: getModelSchemaRef(LogProperty, {includeRelations: true}),
        },
      },
    },
  })
  async findBySeller(
    @param.path.number('sellerId') sellerId: number,
  ): Promise<(LogProperty & LogPropertyRelations)[]> {
    const logProperties = await this.logPropertyRepository.find({
      where: {
        fkBuyerIdSellerId: sellerId,
        fkUsertypeId: {neq: 1},
      },
      include: [
        {relation: 'usertype'},
        {relation: 'seller'},
        {relation: 'postProperty'}
      ],
    });

    // Clean each log property
    return logProperties.map(logProperty => {
      let cleanedLogProperty = this.cleanLogProperty(logProperty);
      cleanedLogProperty = this.cleanNestedObjects(cleanedLogProperty);
      return cleanedLogProperty;
    });
  }

  @get('/log-properties/user/{userId}/{userTypeId}/count')
  @response(200, {
    description: 'LogProperty count for specific user',
    content: {'application/json': {schema: CountSchema}},
  })
  async getLogCountByUser(
    @param.path.number('userId') userId: number,
    @param.path.number('userTypeId') userTypeId: number,
  ): Promise<Count> {

    const whereCondition = {
      fkBuyerIdSellerId: userId,
      fkUsertypeId: userTypeId,
      isActive: 1,          // remove if not needed
     
    };

    console.log('LOG COUNT WHERE =>', whereCondition);

    return this.logPropertyRepository.count(whereCondition);
  }

}
