// import {
//   Count,
//   CountSchema,
//   Filter,
//   FilterExcludingWhere,
//   repository,
//   Where,
// } from '@loopback/repository';
// import {
//   del,
//   get,
//   getModelSchemaRef,
//   param,
//   patch,
//   post,
//   put,
//   requestBody,
//   response,
// } from '@loopback/rest';
// import {BuyerMaster} from '../models';
// import {BuyerMasterRepository} from '../repositories';

// export class BuyermasterController {
//   constructor(
//     @repository(BuyerMasterRepository)
//     public buyerMasterRepository: BuyerMasterRepository,
//   ) { }

//   @post('/buyer-masters')
//   @response(200, {
//     description: 'BuyerMaster model instance',
//     content: {'application/json': {schema: getModelSchemaRef(BuyerMaster)}},
//   })
//   async create(
//     @requestBody({
//       content: {
//         'application/json': {
//           schema: getModelSchemaRef(BuyerMaster, {
//             title: 'NewBuyerMaster',
//             exclude: ['buyerId'],
//           }),
//         },
//       },
//     })
//     buyerMaster: Omit<BuyerMaster, 'buyerId'>,
//   ): Promise<BuyerMaster> {
//     return this.buyerMasterRepository.create(buyerMaster);
//   }

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

//   @get('/buyer-masters')
//   @response(200, {
//     description: 'Array of BuyerMaster model instances',
//     content: {
//       'application/json': {
//         schema: {
//           type: 'array',
//           items: getModelSchemaRef(BuyerMaster, {includeRelations: true}),
//         },
//       },
//     },
//   })
//   async find(
//     @param.filter(BuyerMaster) filter?: Filter<BuyerMaster>,
//   ): Promise<BuyerMaster[]> {
//     return this.buyerMasterRepository.find(filter);
//   }

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

//   @get('/buyer-masters/{id}')
//   @response(200, {
//     description: 'BuyerMaster model instance',
//     content: {
//       'application/json': {
//         schema: getModelSchemaRef(BuyerMaster, {includeRelations: true}),
//       },
//     },
//   })
//   async findById(
//     @param.path.number('id') id: number,
//     @param.filter(BuyerMaster, {exclude: 'where'}) filter?: FilterExcludingWhere<BuyerMaster>
//   ): Promise<BuyerMaster> {
//     return this.buyerMasterRepository.findById(id, filter);
//   }

//   @patch('/buyer-masters/{id}')
//   @response(204, {
//     description: 'BuyerMaster PATCH success',
//   })
//   async updateById(
//     @param.path.number('id') id: number,
//     @requestBody({
//       content: {
//         'application/json': {
//           schema: getModelSchemaRef(BuyerMaster, {partial: true}),
//         },
//       },
//     })
//     buyerMaster: BuyerMaster,
//   ): Promise<void> {
//     await this.buyerMasterRepository.updateById(id, buyerMaster);
//   }

//   @put('/buyer-masters/{id}')
//   @response(204, {
//     description: 'BuyerMaster PUT success',
//   })
//   async replaceById(
//     @param.path.number('id') id: number,
//     @requestBody() buyerMaster: BuyerMaster,
//   ): Promise<void> {
//     await this.buyerMasterRepository.replaceById(id, buyerMaster);
//   }

//   @del('/buyer-masters/{id}')
//   @response(204, {
//     description: 'BuyerMaster DELETE success',
//   })
//   async deleteById(@param.path.number('id') id: number): Promise<void> {
//     await this.buyerMasterRepository.deleteById(id);
//   }
// }


import {inject} from '@loopback/core';
import {
  Count,
  CountSchema,
  Filter,
  FilterExcludingWhere,
  repository,
  Where,
} from '@loopback/repository';
import {
  del,
  get,
  getModelSchemaRef,
  param,
  patch,
  post,
  Request,
  requestBody,
  response,
  RestBindings
} from '@loopback/rest';
import fs from 'fs';
import multer from 'multer';
import path from 'path';
import {URL} from '../config/constants';
import {BuyerMaster} from '../models';
import {BuyerMasterRepository} from '../repositories';

// ---------- Configure Upload Directory ----------
const uploadDir = path.join(__dirname, '../../uploads/buyer-profiles');
if (!fs.existsSync(uploadDir)) {
  fs.mkdirSync(uploadDir, {recursive: true});
}

const storage = multer.diskStorage({
  destination: function (_req, _file, cb) {
    cb(null, uploadDir);
  },
  filename: function (_req, file, cb) {
    cb(null, `${Date.now()}-${file.originalname}`);
  },
});

const upload = multer({storage});

export class BuyermasterController {
  constructor(
    @repository(BuyerMasterRepository)
    public buyerMasterRepository: BuyerMasterRepository,
  ) { }

  @post('/buyer-masters/text')
  @response(200, {
    description: 'BuyerMaster model instance',
    content: {'application/json': {schema: getModelSchemaRef(BuyerMaster)}},
  })
  async create(
    @requestBody({
      content: {
        'application/json': {
          schema: getModelSchemaRef(BuyerMaster, {
            title: 'NewBuyerMaster',
            exclude: ['buyerId'],
          }),
        },
      },
    })
    buyerMaster: Omit<BuyerMaster, 'buyerId'>,
  ): Promise<BuyerMaster> {
    return this.buyerMasterRepository.create(buyerMaster);
  }

  // ---------- CREATE with file ----------
  @post('/buyer-masters')
  @response(200, {
    description: 'Create BuyerMaster with profile photo and relations',
    content: {'application/json': {schema: getModelSchemaRef(BuyerMaster)}},
  })
  async createWithFile(
    @requestBody.file() request: Request,
    @inject(RestBindings.Http.RESPONSE) response: any,
  ): Promise<BuyerMaster> {
    return new Promise<BuyerMaster>((resolve, reject) => {
      upload.single('profilePhoto')(request, response, async (err: any) => {
        if (err) return reject(err);

        const file = (request as any).file;
        const fields = (request as any).body;

        try {
          const newBuyer = await this.buyerMasterRepository.create({
            buyerName: fields.buyerName,
            buyerEmail: fields.buyerEmail,
            buyerMobile: fields.buyerMobile,
            fkcityId: fields.fkcityId,
            buyerGender: fields.buyerGender,
            fkusertypeId: fields.fkusertypeId,
            profilePhoto: file ? `${URL}/uploads/buyer-profiles/${file.filename}` : undefined,
            isActive: 1,
            lastChanged: new Date().toISOString(),
          });

          // Fetch with relations
          const buyerWithRelations = await this.buyerMasterRepository.findById(newBuyer.buyerId!, {
            include: ['city', 'gender', 'usertype'],
          });

          resolve(buyerWithRelations);
        } catch (e) {
          reject(e);
        }
      });
    });
  }

  // ---------- COUNT ----------
  @get('/buyer-masters/count')
  @response(200, {
    description: 'BuyerMaster model count',
    content: {'application/json': {schema: CountSchema}},
  })
  async count(
    @param.where(BuyerMaster) where?: Where<BuyerMaster>,
  ): Promise<Count> {
    return this.buyerMasterRepository.count(where);
  }

  // ---------- FIND ALL ----------
  @get('/buyer-masters')
  @response(200, {
    description: 'Array of BuyerMaster model instances with relations',
    content: {
      'application/json': {
        schema: {
          type: 'array',
          items: getModelSchemaRef(BuyerMaster, {includeRelations: true}),
        },
      },
    },
  })
  async find(
    @param.filter(BuyerMaster) filter?: Filter<BuyerMaster>,
  ): Promise<BuyerMaster[]> {
    const f: Filter<BuyerMaster> = {
      ...filter,
      include: ['city', 'gender', 'usertype'],
    };
    return this.buyerMasterRepository.find(f);
  }

  // ---------- FIND BY ID ----------
  @get('/buyer-masters/{id}')
  @response(200, {
    description: 'BuyerMaster model instance with relations',
    content: {
      'application/json': {
        schema: getModelSchemaRef(BuyerMaster, {includeRelations: true}),
      },
    },
  })
  async findById(
    @param.path.number('id') id: number,
    @param.filter(BuyerMaster, {exclude: 'where'}) filter?: FilterExcludingWhere<BuyerMaster>,
  ): Promise<BuyerMaster> {
    const f: FilterExcludingWhere<BuyerMaster> = {
      ...filter,
      include: ['city', 'gender', 'usertype'],
    };
    return this.buyerMasterRepository.findById(id, f);
  }

  // ---------- UPDATE with file ----------
  @patch('/buyer-masters/{id}')
  @response(204, {description: 'BuyerMaster PATCH success'})
  async updateByIdWithFile(
    @param.path.number('id') id: number,
    @requestBody.file() request: Request,
    @inject(RestBindings.Http.RESPONSE) response: any,
  ): Promise<BuyerMaster> {
    return new Promise<BuyerMaster>((resolve, reject) => {
      upload.single('profilePhoto')(request, response, async (err: any) => {
        if (err) return reject(err);

        const file = (request as any).file;
        const fields = (request as any).body;

        try {
          const existingBuyer = await this.buyerMasterRepository.findById(id);

          await this.buyerMasterRepository.updateById(id, {
            buyerName: fields.buyerName,
            buyerEmail: fields.buyerEmail,
            buyerMobile: fields.buyerMobile,
            fkcityId: fields.fkcityId,
            buyerGender: fields.buyerGender,
            fkusertypeId: fields.fkusertypeId,
            profilePhoto: file
              ? `${URL}/uploads/buyer-profiles/${file.filename}`
              : existingBuyer.profilePhoto,
            lastChanged: new Date().toISOString(),
            isActive: fields.isActive,
          });

          // Return updated buyer with relations
          const updatedBuyer = await this.buyerMasterRepository.findById(id, {
            include: ['city', 'gender', 'usertype'],
          });
          resolve(updatedBuyer);
        } catch (e) {
          reject(e);
        }
      });
    });
  }

  // ---------- DELETE ----------
  @del('/buyer-masters/{id}')
  @response(204, {description: 'BuyerMaster DELETE success'})
  async deleteById(@param.path.number('id') id: number): Promise<void> {
    await this.buyerMasterRepository.deleteById(id);
  }

  // ---------- SOFT DELETE ----------
  @patch('/buyer-masters/soft-delete/{id}')
  async softDelete(
    @param.path.number('id') id: number,
  ): Promise<BuyerMaster> {
    await this.buyerMasterRepository.updateById(id, {
      isActive: 0,
      lastChanged: new Date().toISOString(),
    });

    const softDeletedBuyer = await this.buyerMasterRepository.findById(id, {
      include: ['city', 'gender', 'usertype'],
    });
    return softDeletedBuyer;
  }
}
