
from flask_restx import Resource, Api, Namespace, fields,reqparse
from fog_model.fog_predict import fog_classfication
from fog_model.fog_model import darkchannel
from flask import request,jsonify
from flask import Flask, render_template, request
from werkzeug.utils import secure_filename
import os
from haversine import haversine
from database.database import DB
import torch
from PIL import Image
from pothole_model.pothole import pothole
from datetime import datetime
import pandas as pd
from io import StringIO
import jwt


paths = os.getcwd()

Action = Namespace(
    name="Action",
    description="노드 분석을 위해 사용하는 api.",
)

def find_node(gps_address_y,gps_address_x):
  db=DB()
  nn_end = None
  end_delta = float("inf")
  value=0.0001
  near_nodes=[]
  while near_nodes==[]:
    value=value*10
    near_nodes=db.db_get_near_node(gps_address_y,gps_address_x,value)
    
  for n in near_nodes:
    e_dist = haversine((gps_address_x,gps_address_y), n)
    if e_dist < end_delta :
      nn_end = n
      end_delta = e_dist
  return nn_end



@Action.route('/image_summit')
class fileUpload(Resource):
    @Action.doc(responses={200: 'Success'})
    @Action.doc(responses={500: 'Register Failed'})
    def post(self):
      if request.method == 'POST':
         current_time = datetime.now()
         timestamp = current_time.strftime("%Y%m%d%H%M%S")
# 시간을 원하는 형식으로 포맷팅하기 (예: 년-월-일 시:분:초)
         formatted_time = current_time.strftime("%Y-%m-%d %H:%M:%S")
          # 포맷팅된 현재 시간 출력
         token = request.headers.get('Authorization')
         print(token)
         #print(token)
         if not token:
             return jsonify({'result': 'fail', 'msg': '토큰이 없습니다.'})
        
         else:
            # Decode the token to verify it
            decoded_token = jwt.decode(token, "secret", algorithms=['HS256'])
            print(decoded_token)
            user_id = decoded_token['id']
         print("현재 시간,저장요청:", formatted_time)
         f = request.files['file']
         save_path = f"images/{timestamp}/{user_id}"
         os.makedirs(save_path, exist_ok=True)
         new_filename = f"{save_path}/{user_id}_{timestamp}.jpg"
         print(f)
         f.save(new_filename)
         print("저장완료", formatted_time)

         return {
                'save': 'done'  # str으로 반환하여 return
            }, 200



@Action.route('/image_anal')
class fileUpload(Resource):
    @Action.doc(responses={200: 'Success'})
    @Action.doc(responses={500: 'Register Failed'})
    def post(self):
      if request.method == 'POST':
         current_time = datetime.now()
         formatted_time = current_time.strftime("%Y-%m-%d %H:%M:%S")
         print("현재 시간:", formatted_time)


         fc = fog_classfication()
         dir = os.getcwd()
         filename = request.json['filename']
         file_type = request.json['file_type']
         gps_address_x = float(request.json['gps_x'])
         gps_address_y = float(request.json['gps_y'])
         total_path = dir+ "\\"+ filename + file_type
         model_fc= fc.predict(total_path)
         
         #model_yolo= torch.hub.load(paths +'/yolov5/', 'custom', path=paths+'/yolov5/best.pt', source='local')
         #im = Image.open(total_path)
         #results = model_yolo(im)
         #li_detect=list(results.pandas().xyxy[0]['name'])
         if model_fc == "normal":
          #if 'vest' in li_detect and 'cone' in li_detect:
            nn_end = find_node(gps_address_y,gps_address_x)
            return {
                'node': nn_end,  
                'fog' : 'normal',
                'construction' : 'construction'
            }, 200
            '''
          #else:
            return {
                'node': None,  
                'fog' : 'normal',
                'construction' : 'normal'
            }, 200
            '''
         else:
           # if 'vest' in li_detect and 'cone' in li_detect:
              nn_end = find_node(gps_address_y,gps_address_x)
              db=DB()
              current_time = datetime.now()
              formatted_time = current_time.strftime("%Y-%m-%d %H:%M:%S")
              db.db_add_report(filename,gps_address_x,gps_address_y)
              print("현재 시간:", formatted_time)
              return {
                'node': nn_end,  
                'fog' : 'fog',
                'construction' : 'construction'
            }, 200
              
              '''
            #else:
              nn_end = find_node(gps_address_y,gps_address_x)
              return {
                'node': nn_end,  
                'fog' : 'fog',
                'construction' : 'normal'
              }, 200
'''
              
@Action.route('/pothole_report')
class fileUpload(Resource):
    @Action.doc(responses={200: 'Success'})
    @Action.doc(responses={500: 'Register Failed'})
    def post(self):
      if request.method == 'POST':
         pc = pothole()
         dir = os.getcwd()
         report_id = request.json['report_id']
         pothole_id = request.json['pothole_id']
         pothole_x = float(request.json['pothole_x'])
         pothole_y = float(request.json['pothole_y'])
         pc.report(report_id,pothole_id,pothole_x,pothole_y)       
         return {
                'report': 'done'  # str으로 반환하여 return
            }, 200

@Action.route('/gps_update')
class fileUpload(Resource):
    def post(self):
        token = request.headers.get('Authorization')
        if not token:
            return jsonify({'result': 'fail', 'msg': '토큰이 없습니다.'})
        else:
            # Decode the token to verify it
            decoded_token = jwt.decode(token, "secret", algorithms=['HS256'])
            #print(decoded_token)
            user_id = decoded_token['id']
    
        db = DB()
        data = request.get_json()
        if len(data["trip_id"]) !=64:
            return jsonify({500 :"ERROR! INVALID TRIP_ID!"})
            
        if len(data["trip_log"]["timestamp"]) == 0:
            return jsonify({500 :"ERROR! 'trip_log' is empty!"})
        
        time_stamp_len = len(data["trip_log"]["timestamp"])
        latitude_len = len(data["trip_log"]["latitude"])
        longitude_len = len(data["trip_log"]["longitude"])
       
        if time_stamp_len != latitude_len or latitude_len != longitude_len:
            return jsonify(
                {
                    500: f"ERROR! Mismatching length of data in trip_log! \n timestamp : {time_stamp_len} \n latitude : {latitude_len} \n longitude : {longitude_len}"
                }
            )
         
        df = pd.DataFrame(data["trip_log"])
        df["user_id"] = data["user_id"]
        df["trip_id"] = data["trip_id"]
        
       	
        columns = df.columns
        data_csv_block = df.to_csv(header=False, index=False)
        
        # GPS 데이터베이스에 삽입
        db.insert_gps_data(data_csv_block, columns)
        return jsonify({'result': 'success'})
            
            
@Action.route('/pothole_display')
class fileUpload(Resource):
    @Action.doc(responses={200: 'Success'})
    @Action.doc(responses={500: 'Register Failed'})
    def get(self):
      if request.method == 'GET':
         pc = pothole()
         dir = os.getcwd()
         #timestamp = request.json['timestamp']
         value=pc.display()       
         return {
                'pothole': list(value)  # str으로 반환하여 return
            }, 200
