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,
  Response,
  RestBindings,
} from '@loopback/rest';
import fs from 'fs';
import multer from 'multer';
import path from 'path';
import {URL} from '../config/constants';
import {RealEstateMaster} from '../models';
import {RealEstateMasterRepository} from '../repositories';

const uploadDir = path.join(__dirname, '../../uploads/real-estate-images');
if (!fs.existsSync(uploadDir)) {
  fs.mkdirSync(uploadDir, {recursive: true});
}

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

export class RealestetemasterController {
  constructor(
    @repository(RealEstateMasterRepository)
    public realEstateMasterRepository: RealEstateMasterRepository,
  ) { }

  /**
   * ✅ Create real estate with only JSON (no file)
   */
  @post('/real-estate-masters')
  @response(200, {
    description: 'RealEstateMaster model instance',
    content: {'application/json': {schema: getModelSchemaRef(RealEstateMaster)}},
  })
  async create(
    @requestBody({
      content: {
        'application/json': {
          schema: getModelSchemaRef(RealEstateMaster, {
            title: 'NewRealEstateMaster',
            exclude: ['blogId'],
          }),
        },
      },
    })
    realEstateMaster: Omit<RealEstateMaster, 'blogId'>,
  ): Promise<RealEstateMaster> {
    return this.realEstateMasterRepository.create(realEstateMaster);
  }

  /**
   * ✅ Create real estate with image upload (multipart/form-data)
   */
  @post('/real-estate-masters/upload')
  @response(200, {
    description: 'RealEstateMaster model instance with image upload',
  })
  async createWithImage(
    @requestBody.file()
    request: Request,
    @inject(RestBindings.Http.RESPONSE) response: Response,
  ): Promise<any> {
    return new Promise((resolve, reject) => {
      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}).single('blogImage'); // frontend must send `blogImage`

      upload(request, response, async (err: any) => {
        if (err) return reject(err);

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

        try {
          const newEstate = await this.realEstateMasterRepository.create({
            blogTitle: body.blogTitle,
            blogDescription: body.blogDescription,
            blogStartAmount: body.blogStartAmount,
            blogEndAmount: body.blogEndAmount,
            blogDate: body.blogDate,
            blogImage: file ? file.filename : null,
            lastChanged: new Date().toISOString(),
            createdAt: new Date().toISOString()
          });

          resolve({
            success: true,
            data: newEstate,
            imageUrl: file ? `${BASE_URL}/${file.filename}` : FALLBACK_URL,
          });
        } catch (e) {
          reject(e);
        }
      });
    });
  }

  /**
   * ✅ Fetch all with image URL resolution
   */
  @get('/real-estate-masters')
  @response(200, {
    description: 'Array of RealEstateMaster model instances',
    content: {
      'application/json': {
        schema: {
          type: 'array',
          items: getModelSchemaRef(RealEstateMaster, {includeRelations: true}),
        },
      },
    },
  })
  async find(
    @param.filter(RealEstateMaster) filter?: Filter<RealEstateMaster>,
  ): Promise<any[]> {
    const data = await this.realEstateMasterRepository.find({
      ...filter,
      order: ['created_date DESC'],
    });

    return data.map(item => {
      let imageUrl = item.blogImage?.trim();

      if (imageUrl && (imageUrl.startsWith('http://') || imageUrl.startsWith('https://'))) {
        return {...item, blogImage: imageUrl};
      }

      if (imageUrl) {
        const filename = path.basename(imageUrl);
        const localPath = path.join(uploadDir, filename);

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

      return {...item, blogImage: FALLBACK_URL};
    });
  }
  @get('/real-estate-masters/count')
  @response(200, {
    description: 'RealEstateMaster model count',
    content: {'application/json': {schema: CountSchema}},
  })
  async count(
    @param.where(RealEstateMaster) where?: Where<RealEstateMaster>,
  ): Promise<Count> {
    return this.realEstateMasterRepository.count(where);
  }

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


  // @get('/real-estate-masters')
  // @response(200, {
  //   description: 'Array of RealEstateMaster model instances',
  //   content: {
  //     'application/json': {
  //       schema: {
  //         type: 'array',
  //         items: getModelSchemaRef(RealEstateMaster, {includeRelations: true}),
  //       },
  //     },
  //   },
  // })
  // async find(
  //   @param.filter(RealEstateMaster) filter?: Filter<RealEstateMaster>,
  // ): Promise<any[]> {
  //   const data = await this.realEstateMasterRepository.find({
  //     ...filter,
  //     order: ['created_date DESC'],
  //   });

  //   return data.map(item => {
  //     let imageUrl = item.blogImage?.trim();

  //     // ✅ Case 1: Already a live URL (Unsplash, etc.)
  //     if (imageUrl && (imageUrl.startsWith('http://') || imageUrl.startsWith('https://'))) {
  //       return {
  //         ...item,
  //         blogImage: imageUrl,
  //       };
  //     }

  //     // ✅ Case 2: Local image (stored filename like "1755673228599-partner1.avif")
  //     if (imageUrl) {
  //       const filename = path.basename(imageUrl);
  //       const localPath = path.join(__dirname, '../../uploads/real-estate-images', filename);

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

  //     // ✅ Case 3: Nothing found → fallback
  //     return {
  //       ...item,
  //       blogImage: FALLBACK_URL,
  //     };
  //   });
  // }


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

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

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

  @put('/real-estate-masters/{id}')
  @response(204, {
    description: 'RealEstateMaster PUT success',
  })
  async replaceById(
    @param.path.number('id') id: number,
    @requestBody() realEstateMaster: RealEstateMaster,
  ): Promise<void> {
    await this.realEstateMasterRepository.replaceById(id, realEstateMaster);
  }

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