# CREATE FLASK APP


from flask import Flask, request, jsonify
from flasgger import Swagger
import json
import psycopg2
import psycopg2.extras
import sys
import aux_function as  aux


app = Flask(__name__)
swagger = Swagger(app)
template = {
  "swagger": "2.0",
  "info": {
    "title": "DHL Visual Check API",
    "description": "API for DHL Visual Check",
    "contact": {
      "responsibleOrganization": "3CO Sistemas S.L.",
      "responsibleDeveloper": "3CO Sistemas S.L.",
      "email": "me@me.com",
      "url": "www.me.com",
    },
    "termsOfService": "http:/3cosolutions.com/",
    "version": "1.0.1"
  },
  "basePath": "/apidocs",  # base bash for blueprint registration
  "schemes": [
    "http",
    "https"
  ],
  "operationId": "getmyData"
}

@app.route('/api/rest/infoParcel', methods=['POST'])
def peticion():
    """
    Receive the data of the parcel to be registered
    ---
    parameters:
      - name: visual_check
        in: body
        required: true
        schema:
          id: visual_check
          required:
            - pick_details
          properties:
            pick_details:
              type: object
              required:
                - warehouse_id
                - inventory_id
                - carrier
                - wave_name
                - position
              properties:
                warehouse_id:
                  type: string
                  description: The warehouse_id of the parcel
                inventory_id:
                  type: string
                  description: The inventory_id of the parcel
                carrier:
                  type: string
                  description: The carrier of the parcel
                wave_name:
                  type: string
                  description: The wave_name of the parcel
                position:
                  type: string
                  description: The position of the parcel
    responses:
      200:
        description: The parcel has been registered
        schema: 
          id: infoParcel
          properties:
            warehouse_id:
              type: string
              description: The warehouse_id of the parcel
            inventory_id:
              type: string
              description: The inventory_id of the parcel
            carrier:
              type: string
              description: The carrier of the parcel
            wave_name:
              type: string
              description: The wave_name of the parcel
            position:
              type: string
              description: The position of the parcel
      500:
        description: Error registering the parcel
"""
    data = request.get_json()
    # check if ParcelId,ChuteId,Posicion is in the request and is not empty
    if 'visual_check' not in data:
        return jsonify({'error': 'Structure is not valid'}), 500
    else:
        data = data['visual_check']
        if 'pick_details' not in data:
            return jsonify({'error': 'Structure is not valid'}), 500
        else:
            data = data['pick_details']
            if 'warehouse_id' not in data or 'inventory_id' not in data or 'carrier' not in data or 'wave_name' not in data or 'position' not in data:
                return jsonify({'error': 'Missing data'}), 500
    # insert the new data
    aux.graba_log('infoParcel', json.dumps(data))
    #return jsonify({'error': 'Data recieved'}), 200

    sql = f"INSERT INTO DHL_LINK_ID (warehouse_id, inventory_id, carrier, wave_name, position) VALUES ('{data['warehouse_id']}', '{data['inventory_id']}', '{data['carrier']}', '{data['wave_name']}', '{data['position']}')"
    try:
        cursor.execute(sql)
    except psycopg2.errors.UniqueViolation as pk_error:
        conn.rollback()
        return jsonify({'error': 'ParcelId already exists'}), 500
    conn.commit()
    return jsonify(data)


@app.route('/api/rest/isOnline', methods=['GET'])
def isOnline():
    return jsonify({"isOnline":"online"})



@app.route('/api/rest/lastParcel', methods=['GET'])
def lastParcel():
    sql = "SELECT * FROM DHL_LINK_ID ORDER BY momento_in DESC LIMIT 1"
    cursor.execute(sql)
    columns = [column[0] for column in cursor.description]
    data = [dict(zip(columns, row)) for row in cursor.fetchall()]
    # with data object generate a JSON response returning the values inside with the keys
    if data is None:
        return jsonify({'error': 'No data'}), 500
    return jsonify(data), 200

@app.route('/api/rest/allParcels/<limit>', methods=['GET'])
def allParcels(limit):
    sql = f"SELECT * FROM DHL_LINK_ID ORDER BY momento_in DESC LIMIT {limit}"
    cursor.execute(sql)
    columns = [column[0] for column in cursor.description]
    data = [dict(zip(columns, row)) for row in cursor.fetchall()]
    if data is None:
        return jsonify({'error': 'No data'}), 500
    return jsonify(data)

@app.route('/api/rest/<parcel>', methods=['GET'])
def getParcel(parcel):
    sql = f"SELECT * FROM DHL_LINK_ID WHERE inventory_id = '{parcel}'"
    cursor.execute(sql)
    columns = [column[0] for column in cursor.description]
    data = [dict(zip(columns, row)) for row in cursor.fetchall()]
    if data is None:
        return jsonify({'error': 'No data'}), 500
    return jsonify(data)

@app.route('/api/rest/allParcelsUnregistered/<almacen>', methods=['GET'])
def getParcels(almacen):
    """
    Update the registered field of the parcel with the inventory_id
    ---
    parameters:
      - name: almacen
        in: path
        type: string
        required: true
        description: The warehouse_id of the parcels to be updated
    responses:
        200:
            description: The parcel has been updated
            schema: 
            id: registerParcel
            properties:
                inventory_id:
                type: string
                description: The inventory_id of the parcel
                registered:
                type: string
                description: The new value of the registered
        500:
            description: Error updating
        
    """
    if (almacen == 'all'):
        sql = "SELECT * FROM DHL_LINK_ID WHERE registered = 'N'"
        cursor.execute(sql)
        columns = [column[0] for column in cursor.description]
        data = [dict(zip(columns, row)) for row in cursor.fetchall()]
        if data is None:
            return jsonify({'error': 'No data'}), 500
    else:
        sql = f"SELECT * FROM DHL_LINK_ID WHERE registered = 'N' and warehouse_id = '{almacen}'"
        cursor.execute(sql)
        columns = [column[0] for column in cursor.description]
        data = [dict(zip(columns, row)) for row in cursor.fetchall()]
        if data is None:
            return jsonify({'error': 'No data'}), 500
    return jsonify(data)

@app.route('/api/rest/registerParcel/<inventory_id>', methods=['PUT'])
def registerParcel(inventory_id):
    """
    Update the registered field of the parcel with the inventory_id
    ---
    parameters:
      - name: inventory_id
        in: path
        type: string
        required: true
        description: The inventory_id of the parcel to be updated
    responses:
        200:
            description: The parcel has been updated
            schema: 
            id: registerParcel
            properties:
                inventory_id:
                type: string
                description: The inventory_id of the parcel
                registered:
                type: string
                description: The new value of the registered field
        500:
            description: Error updating
        
    """
    sql = f"UPDATE DHL_LINK_ID SET registered = 'S' WHERE inventory_id = '{inventory_id}'"
    cursor.execute(sql)
    conn.commit()
    return jsonify({'inventory_id': inventory_id, 'registered': 'S'}), 200
    

try:
    jsonConfig = open('config.json')
    cfg = json.load(jsonConfig)
    jsonConfig.close()
except Exception as e:
    aux.graba_log('config', 'Error al abrir o parsear el JSON de configuracion')
    sys.exit(1)

try:
    db = cfg['db']
    conn = psycopg2.connect(db)
    cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
except:
    aux.graba_log('config', 'Error al abrir la base de datos SQLite')
    sys.exit(1)
if conn is not None:
    if __name__ == '__main__':
        app.run(host='0.0.0.0',debug=False, port=7557, ssl_context=('certificate.crt','private.key'))