import {inject} from '@loopback/core';
import {
  FilterExcludingWhere,
  repository
} from '@loopback/repository';
import {
  del,
  get,
  getModelSchemaRef,
  param,
  patch,
  post,
  Request,
  response,
  RestBindings
} from '@loopback/rest';
import fs from 'fs';
import multer from 'multer';
import path from 'path';
import {URL} from "../config/constants";
import {LogoMaster} from '../models';
import {LogoMasterRepository} from '../repositories';
export class LogomasterController {
  private uploadPath: string;
  private storage: multer.StorageEngine;
  private upload: any;

  constructor(
    @repository(LogoMasterRepository)
    public logoMasterRepository: LogoMasterRepository,
  ) {
    this.uploadPath = path.resolve(process.cwd(), 'uploads/logos');
    if (!fs.existsSync(this.uploadPath)) {
      fs.mkdirSync(this.uploadPath, {recursive: true});
    }

    this.storage = multer.diskStorage({
      destination: (_req, _file, cb) => cb(null, this.uploadPath),
      filename: (_req, file, cb) => {
        const uniqueSuffix =
          Date.now() + '-' + Math.round(Math.random() * 1e9);
        cb(null, uniqueSuffix + path.extname(file.originalname));
      },
    });

    this.upload = multer({
      storage: this.storage,
      limits: {fileSize: 5 * 1024 * 1024}, // 5MB limit
    }).single('logoImage');
  }

  /** CREATE with file upload */
  @post('/logo-masters')
  @response(200, {
    description: 'LogoMaster model instance',
    content: {'application/json': {schema: getModelSchemaRef(LogoMaster)}},
  })
  async create(
    @inject(RestBindings.Http.REQUEST) req: Request,
  ): Promise<LogoMaster> {
    return new Promise((resolve, reject) => {
      this.upload(req, {} as any, async (err: any) => {
        if (err) return reject(err);

        const body = req.body as Partial<LogoMaster>;
        if (req.file) {
          // ✅ Save only filename
          body.logoImage = req.file.filename;
        }

        try {
          const created = await this.logoMasterRepository.create(body as LogoMaster);
          resolve(created);
        } catch (e) {
          reject(e);
        }
      });
    });
  }

  /** GET all with full URL */
  @get('/logo-masters')
  async find(): Promise<any[]> {
    const logos = await this.logoMasterRepository.find();
    return logos.map(logo => ({
      ...logo,
      logoImage: logo.logoImage
        ? `${URL}/uploads/logos/${logo.logoImage}`
        : null
    }));
  }


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

  /** UPDATE by ID with optional file upload */
  @patch('/logo-masters/{id}')
  @response(204, {description: 'LogoMaster PATCH success'})
  async updateById(
    @inject(RestBindings.Http.REQUEST) req: Request,
    @param.path.number('id') id: number,
  ): Promise<void> {
    return new Promise((resolve, reject) => {
      this.upload(req, {} as any, async (err: any) => {
        if (err) return reject(err);

        const body = req.body as Partial<LogoMaster>;

        if (req.file) {
          // Delete old file if exists
          const existing = await this.logoMasterRepository.findById(id);
          if (existing.logoImage) {
            const oldPath = path.resolve(this.uploadPath, existing.logoImage);
            if (fs.existsSync(oldPath)) {
              fs.unlinkSync(oldPath);
            }
          }
          body.logoImage = req.file.filename;
        }

        await this.logoMasterRepository.updateById(id, body);
        resolve();
      });
    });
  }

  /** DELETE by ID and remove file */
  @del('/logo-masters/{id}')
  @response(204, {description: 'LogoMaster DELETE success'})
  async deleteById(@param.path.number('id') id: number): Promise<void> {
    const existing = await this.logoMasterRepository.findById(id);
    if (existing.logoImage) {
      const filePath = path.resolve(this.uploadPath, existing.logoImage);
      if (fs.existsSync(filePath)) {
        fs.unlinkSync(filePath);
      }
    }
    await this.logoMasterRepository.deleteById(id);
  }
}
