import {inject} from '@loopback/core';
import {
  Count,
  CountSchema,
  Filter,
  FilterExcludingWhere,
  repository,
  Where,
} from '@loopback/repository';
import {
  del,
  get,
  getModelSchemaRef,
  param,
  patch,
  post,
  put,
  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 {OurPartnerMaster} from '../models';
import {OurPartnerMasterRepository} from '../repositories';
// const BASE_URL = 'http://localhost:3001/uploads/partner-images';

const BASE_URL = `${URL}/uploads/partner-images`;
const FALLBACK_URL = `${BASE_URL}/default.jpg`;

// ✅ helper function
function resolvePhoto(photo?: string | null): string {
  if (!photo) return FALLBACK_URL;

  if (photo.startsWith('http://') || photo.startsWith('https://')) {
    return photo.trim();
  }

  const filename = path.basename(photo);
  const localPath = path.join(__dirname, '../../uploads/partner-images', filename);

  if (fs.existsSync(localPath)) {
    return `${BASE_URL}/${filename}`;
  }

  return FALLBACK_URL;
}

export class OurpartnermasterController {
  constructor(
    @repository(OurPartnerMasterRepository)
    public ourPartnerMasterRepository: OurPartnerMasterRepository,
  ) { }

  // 📌 upload middleware
  private getMulterUpload() {
    const storage = multer.diskStorage({
      destination: (req, file, cb) => {
        const dir = path.join(__dirname, '../../uploads/partner-images');
        if (!fs.existsSync(dir)) fs.mkdirSync(dir, {recursive: true});
        cb(null, dir);
      },
      filename: (req, file, cb) => {
        cb(null, Date.now() + '-' + file.originalname);
      },
    });
    return multer({storage});
  }

  // ✅ Create with photo upload
  @post('/our-partner-masters/uploads')
  @response(200, {
    description: 'OurPartnerMaster with photo',
  })
  async createWithPhoto(
    @inject(RestBindings.Http.REQUEST) request: Request,
  ): Promise<OurPartnerMaster> {
    const upload = this.getMulterUpload().single('photo');

    return new Promise((resolve, reject) => {
      upload(request, {} as any, async err => {
        if (err) return reject(err);

        const file = (request as any).file as Express.Multer.File;

        const partner = await this.ourPartnerMasterRepository.create({
          ...request.body,
          partnerLogo: file?.filename || null, // ✅ Save file name into DB
          createdAt: new Date().toISOString(),
          lastChanged: new Date().toISOString(),
          isActive: 1,
        });

        resolve(partner);
      });
    });
  }



  @post('/our-partner-masters')
  @response(200, {
    description: 'OurPartnerMaster model instance',
    content: {'application/json': {schema: getModelSchemaRef(OurPartnerMaster)}},
  })
  async create(
    @requestBody({
      content: {
        'application/json': {
          schema: getModelSchemaRef(OurPartnerMaster, {
            title: 'NewOurPartnerMaster',
            exclude: ['partnerId'],
          }),
        },
      },
    })
    ourPartnerMaster: Omit<OurPartnerMaster, 'partnerId'>,
  ): Promise<OurPartnerMaster> {
    return this.ourPartnerMasterRepository.create(ourPartnerMaster);
  }

  @get('/our-partner-masters')
  @response(200, {
    description: 'Array of OurPartnerMaster model instances',
  })
  async find(
    @param.filter(OurPartnerMaster) filter?: Filter<OurPartnerMaster>,
  ): Promise<any[]> {
    const data = await this.ourPartnerMasterRepository.find(filter);
    return data.map(item => ({
      ...item,
      partnerLogo: resolvePhoto(item.partnerLogo),
    }));
  }

  @get('/our-partner-masters/{id}')
  @response(200, {
    description: 'OurPartnerMaster model instance',
  })
  async findById(
    @param.path.number('id') id: number,
    @param.filter(OurPartnerMaster, {exclude: 'where'}) filter?: FilterExcludingWhere<OurPartnerMaster>,
  ): Promise<any> {
    const item = await this.ourPartnerMasterRepository.findById(id, filter);
    return {...item, photo: resolvePhoto(item.photo)};
  }

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

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

  @put('/our-partner-masters/{id}')
  @response(204, {
    description: 'OurPartnerMaster PUT success',
  })
  async replaceById(
    @param.path.number('id') id: number,
    @requestBody() ourPartnerMaster: OurPartnerMaster,
  ): Promise<void> {
    await this.ourPartnerMasterRepository.replaceById(id, ourPartnerMaster);
  }

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