
const express = require('express');

const PlacesService = require('../services/places');
const PlacesDBApi = require('../db/api/places');
const wrapAsync = require('../helpers').wrapAsync;


const router = express.Router();

const { parse } = require('json2csv');


const {
    checkCrudPermissions,
} = require('../middlewares/check-permissions');

router.use(checkCrudPermissions('places'));


/**
 *  @swagger
 *  components:
 *    schemas:
 *      Places:
 *        type: object
 *        properties:
 
 *          name:
 *            type: string
 *            default: name
 *          nama:
 *            type: string
 *            default: nama
 *          kategori:
 *            type: string
 *            default: kategori
 *          subkategori:
 *            type: string
 *            default: subkategori
 *          short_description:
 *            type: string
 *            default: short_description
 *          full_description:
 *            type: string
 *            default: full_description
 *          address:
 *            type: string
 *            default: address
 *          alamat:
 *            type: string
 *            default: alamat
 *          kelurahan:
 *            type: string
 *            default: kelurahan
 *          kecamatan:
 *            type: string
 *            default: kecamatan
 *          city:
 *            type: string
 *            default: city
 *          kota:
 *            type: string
 *            default: kota
 *          province:
 *            type: string
 *            default: province
 *          provinsi:
 *            type: string
 *            default: provinsi
 *          postal_code:
 *            type: string
 *            default: postal_code
 *          kode_pos:
 *            type: string
 *            default: kode_pos
 *          phone_number:
 *            type: string
 *            default: phone_number
 *          telepon:
 *            type: string
 *            default: telepon
 *          whatsapp_number:
 *            type: string
 *            default: whatsapp_number
 *          whatsapp:
 *            type: string
 *            default: whatsapp
 *          email:
 *            type: string
 *            default: email
 *          website_url:
 *            type: string
 *            default: website_url
 *          website:
 *            type: string
 *            default: website
 *          google_maps_url:
 *            type: string
 *            default: google_maps_url
 *          jam_buka:
 *            type: string
 *            default: jam_buka
 
 *          rating_count:
 *            type: integer
 *            format: int64
 *          review_count:
 *            type: integer
 *            format: int64
 *          status:
 *            type: string
 *            default: aktif
 *          verified:
 *            type: boolean
 *          featured:
 *            type: boolean
 *          popularitas:
 *            type: integer
 *            format: int64
 
 *          latitude:
 *            type: integer
 *            format: int64
 *          longitude:
 *            type: integer
 *            format: int64
 *          average_price:
 *            type: integer
 *            format: int64
 *          rating_average:
 *            type: integer
 *            format: int64
 *          rating:
 *            type: number
 *            format: float
 
 *          
 *          
 */

/**
 *  @swagger
 * tags:
 *   name: Places
 *   description: The Places managing API
 */

/**
*  @swagger
*  /api/places:
*    post:
*      security:
*        - bearerAuth: []
*      tags: [Places]
*      summary: Add new item
*      description: Add new item
*      requestBody:
*        required: true
*        content:
*          application/json:
*            schema:
*              properties:
*                data:
*                  description: Data of the updated item
*                  type: object
*                  $ref: "#/components/schemas/Places"
*      responses:
*        200:
*          description: The item was successfully added
*          content:
*            application/json:
*              schema:
*                $ref: "#/components/schemas/Places"
*        401:
*          $ref: "#/components/responses/UnauthorizedError"
*        405:
*          description: Invalid input data
*        500:
*          description: Some server error
*/
router.post('/', wrapAsync(async (req, res) => {
    const referer = req.headers.referer || `${req.protocol}://${req.hostname}${req.originalUrl}`;
    const link = new URL(referer);
    const placeData = req.body.data || req.body;
    const payload = await PlacesService.create(placeData, req.currentUser, true, link.host);
    res.status(200).send(payload);
}));

/**
 * @swagger
 * /api/budgets/bulk-import:
 *  post:
 *    security:
 *      - bearerAuth: []
 *    tags: [Places]
 *    summary: Bulk import items
 *    description: Bulk import items
 *    requestBody:
 *      required: true
 *      content:
 *        application/json:
 *         schema:
 *          properties:
 *            data:
 *              description: Data of the updated items
 *              type: array
 *              items:
 *                $ref: "#/components/schemas/Places"
 *    responses:
 *      200:
 *        description: The items were successfully imported
 *    content:
 *      application/json:
 *        schema:
 *          $ref: "#/components/schemas/Places"
 *      401:
 *        $ref: "#/components/responses/UnauthorizedError"
 *      405:
 *        description: Invalid input data
 *      500:
 *        description: Some server error
 *
 */
router.post('/bulk-import', wrapAsync(async (req, res) => {
    const referer = req.headers.referer || `${req.protocol}://${req.hostname}${req.originalUrl}`;
    const link = new URL(referer);
    await PlacesService.bulkImport(req, res, true, link.host);
    const payload = true;
    res.status(200).send(payload);
}));

/**
  *  @swagger
  *  /api/places/{id}:
  *    put:
  *      security:
  *        - bearerAuth: []
  *      tags: [Places]
  *      summary: Update the data of the selected item
  *      description: Update the data of the selected item
  *      parameters:
  *        - in: path
  *          name: id
  *          description: Item ID to update
  *          required: true
  *          schema:
  *            type: string
  *      requestBody:
  *        description: Set new item data
  *        required: true
  *        content:
  *          application/json:
  *            schema:
  *              properties:
  *                id:
  *                  description: ID of the updated item
  *                  type: string
  *                data:
  *                  description: Data of the updated item
  *                  type: object
  *                  $ref: "#/components/schemas/Places"
  *              required:
  *                - id
  *      responses:
  *        200:
  *          description: The item data was successfully updated
  *          content:
  *            application/json:
  *              schema:
  *                $ref: "#/components/schemas/Places"
  *        400:
  *          description: Invalid ID supplied
  *        401:
  *          $ref: "#/components/responses/UnauthorizedError"
  *        404:
  *          description: Item not found
  *        500:
  *          description: Some server error
  */
router.put('/:id', wrapAsync(async (req, res) => {
  const placeData = req.body.data || req.body;
  const placeId = req.body.id || req.params.id;
  await PlacesService.update(placeData, placeId, req.currentUser);
  const payload = true;
  res.status(200).send(payload);
}));

/**
  * @swagger
  *  /api/places/{id}:
  *    delete:
  *      security:
  *        - bearerAuth: []
  *      tags: [Places]
  *      summary: Delete the selected item
  *      description: Delete the selected item
  *      parameters:
  *        - in: path
  *          name: id
  *          description: Item ID to delete
  *          required: true
  *          schema:
  *            type: string
  *      responses:
  *        200:
  *          description: The item was successfully deleted
  *          content:
  *            application/json:
  *              schema:
  *                $ref: "#/components/schemas/Places"
  *        400:
  *          description: Invalid ID supplied
  *        401:
  *          $ref: "#/components/responses/UnauthorizedError"
  *        404:
  *          description: Item not found
  *        500:
  *          description: Some server error
  */
router.delete('/:id', wrapAsync(async (req, res) => {
  await PlacesService.remove(req.params.id, req.currentUser);
  const payload = true;
  res.status(200).send(payload);
}));

/**
  *  @swagger
  *  /api/places/deleteByIds:
  *    post:
  *      security:
  *        - bearerAuth: []
  *      tags: [Places]
  *      summary: Delete the selected item list
  *      description: Delete the selected item list
  *      requestBody:
  *        required: true
  *        content:
  *          application/json:
  *            schema:
  *              properties:
  *                ids:
  *                  description: IDs of the updated items
  *                  type: array
  *      responses:
  *        200:
  *          description: The items was successfully deleted
  *          content:
  *            application/json:
  *              schema:
  *                $ref: "#/components/schemas/Places"
  *        401:
  *          $ref: "#/components/responses/UnauthorizedError"
  *        404:
  *          description: Items not found
  *        500:
  *          description: Some server error
  */
router.post('/deleteByIds', wrapAsync(async (req, res) => {
    const ids = req.body.data || req.body.ids;
    await PlacesService.deleteByIds(ids, req.currentUser);
    const payload = true;
    res.status(200).send(payload);
  }));

/**
  *  @swagger
  *  /api/places:
  *    get:
  *      security:
  *        - bearerAuth: []
  *      tags: [Places]
  *      summary: Get all places
  *      description: Get all places
  *      responses:
  *        200:
  *          description: Places list successfully received
  *          content:
  *            application/json:
  *              schema:
  *                type: array
  *                items:
  *                  $ref: "#/components/schemas/Places"
  *        401:
  *          $ref: "#/components/responses/UnauthorizedError"
  *        404:
  *          description: Data not found
  *        500:
  *          description: Some server error
*/
router.get('/', wrapAsync(async (req, res) => {
  const filetype = req.query.filetype
  
  const currentUser = req.currentUser;
  const payload = await PlacesDBApi.findAll(
    req.query,  { currentUser }
  );
  if (filetype && filetype === 'csv') {
    const fields = ['id','name','nama','kategori','subkategori','short_description','full_description','address','alamat','kelurahan','kecamatan','city','kota','province','provinsi','postal_code','kode_pos','phone_number','telepon','whatsapp_number','whatsapp','email','website_url','website','google_maps_url','jam_buka',
        'rating_count','review_count','status','is_verified','verified','featured','popularitas',
        'sumber','external_id','external_type','last_synced_at',
        'latitude','longitude','average_price','rating_average','rating',
      
        ];
    const opts = { fields };
    try {
      const csv = parse(payload.rows, opts);
      res.status(200).attachment(csv);
      res.send(csv)

    } catch (err) {
      console.error(err);
    }
  } else {
    res.status(200).send(payload);
  }

}));

/**
 *  @swagger
 *  /api/places/count:
 *    get:
 *      security:
 *        - bearerAuth: []
 *      tags: [Places]
 *      summary: Count all places
 *      description: Count all places
 *      responses:
 *        200:
 *          description: Places count successfully received
 *          content:
 *            application/json:
 *              schema:
 *                type: array
 *                items:
 *                  $ref: "#/components/schemas/Places"
 *        401:
 *          $ref: "#/components/responses/UnauthorizedError"
 *        404:
 *          description: Data not found
 *        500:
 *          description: Some server error
 */
router.get('/count', wrapAsync(async (req, res) => {
  
    const currentUser = req.currentUser;
    const payload = await PlacesDBApi.findAll(
        req.query,
         null, 
        { countOnly: true, currentUser }
    );

    res.status(200).send(payload);
}));

/**
 *  @swagger
 *  /api/places/autocomplete:
 *    get:
 *      security:
 *        - bearerAuth: []
 *      tags: [Places]
 *      summary: Find all places that match search criteria
 *      description: Find all places that match search criteria
 *      responses:
 *        200:
 *          description: Places list successfully received
 *          content:
 *            application/json:
 *              schema:
 *                type: array
 *                items:
 *                  $ref: "#/components/schemas/Places"
 *        401:
 *          $ref: "#/components/responses/UnauthorizedError"
 *        404:
 *          description: Data not found
 *        500:
 *          description: Some server error
 */
router.get('/autocomplete', async (req, res) => {
  
  const payload = await PlacesDBApi.findAllAutocomplete(
    req.query.query,
    req.query.limit,
    req.query.offset,
    
  );

  res.status(200).send(payload);
});

/**
  * @swagger
  *  /api/places/{id}:
  *    get:
  *      security:
  *        - bearerAuth: []
  *      tags: [Places]
  *      summary: Get selected item
  *      description: Get selected item
  *      parameters:
  *        - in: path
  *          name: id
  *          description: ID of item to get
  *          required: true
  *          schema:
  *            type: string
  *      responses:
  *        200:
  *          description: Selected item successfully received
  *          content:
  *            application/json:
  *              schema:
  *                $ref: "#/components/schemas/Places"
  *        400:
  *          description: Invalid ID supplied
  *        401:
  *          $ref: "#/components/responses/UnauthorizedError"
  *        404:
  *          description: Item not found
  *        500:
  *          description: Some server error
  */
router.get('/:id', wrapAsync(async (req, res) => {
  const payload = await PlacesDBApi.findBy(
    { id: req.params.id },
  );
  
  

  res.status(200).send(payload);
}));

router.use('/', require('../helpers').commonErrorHandler);

module.exports = router;
