import config
import re
import random
import boto3
from slack_bolt import App
from slack_bolt.adapter.socket_mode import SocketModeHandler
from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError
from elasticsearch import Elasticsearch
import json
import ast
import sys
import time

# elastic 연결
cloud_id = 'univ=============================='
username = 'e==========='
password = 'wNl==========='

app = App(token=config.bot_token)
slack_client = WebClient(token=config.bot_token)

############################################################
##### ---------- 결과물 1 투자사 성향 MBTI  ---------- #####
############################################################
@app.message(re.compile("투자사성향/(.*?)"))
def search_elasticsearch(message, say, context):
    try:
        # say("hi")
        investName = message['text']  # Get the user's message text
        match = re.match(r"(.*?)", investName)
        
        # Elasticsearch 연결 설정
        # Elasticsearch 클러스터 연결
        es = Elasticsearch(
            cloud_id=cloud_id,
            basic_auth=(username, password),
        )
    
        body={
          "query": {
            "bool": {
              "must": [
                {
                  "match": {
                    "투자사 이름": investName
                  }
                }
              ]
            }
          }
        }
        
        
        response = es.search(index="investor_mbti_luck4", body=body)
        # ppps=response['hits']["max_score"]
        # say(str(ppps)) 
        
        hits = response["hits"]["hits"][0]["_source"]
        if hits:
          # ********* MBTI 첫번째 글자 ***************
          mbti1_dict=hits['MBTI_1']
          category_dict={
          'seed_value':int(mbti1_dict['seed']),
          'pre_all_value':int(mbti1_dict['pre-all']),
          'series_atoc_value':int(mbti1_dict['series A-C']),
          'series_dtog_value':int(mbti1_dict['series D-G']),
          'preIPOandM&A':int(mbti1_dict['M&A'])+int(mbti1_dict['pre-IPO']),
          'extra-all':int(mbti1_dict['extra-all'])
            
          }
          
          sorted_category = sorted(category_dict.items(), key=lambda x: x[1], reverse=True)
          
          # 가장 value가 큰 key를 가져오기
          max_key = sorted_category[0][0]
          if(max_key=='seed_value'):
              mbti_1_char='M'
              mbti_1_char_exp = 'Minimal : 이 투자사는 주로 seed 단계의 기업들에게 투자합니다'
          elif(max_key=='pre_all_value'):
              mbti_1_char='S'
              mbti_1_char_exp = 'Substantial : 이 투자사는 주로 pre 단계의 기업들에게 투자합니다'

          elif(max_key=='series_atoc_value'):
              mbti_1_char='C'
              mbti_1_char_exp = 'Considerable: 이 투자사는 주로 series-A ~ series-C 단계의 기업들에게 투자합니다'
              
          elif(max_key=='series_dtog_value'):
              mbti_1_char='H'
              mbti_1_char_exp = 'Huge: 이 투자사는 주로 series-D ~ series-G 단계의 기업들에게 투자합니다'
          elif(max_key=='extra-all'):
              mbti_1_char='E'
              mbti_1_char_exp = 'Excessive: 이 투자사들은 보조금,지원금 형태의 투자를 자주 합니다.'

          # ********* MBTI 두번째 글자 ***************
          mbti2 =hits['MBTI_2']
          
          if (int(mbti2) > 60305844116305):
            mbti_2_char = 'N'
            mbti_2_char_exp = "Nuturing: 이 투자사의 최근 투자 금액 성향 은 평균적인 추세 이하입니다"
          else:
            mbti_2_char = 'S'
            mbti_2_char_exp = "Slight: 이 투자사의 최근 투자 금액 성향 은 평균적인 추세 이상입니다"
            
          
          # ********* MBTI 세번째 글자 ***************
          mbti3 =hits['MBTI_3']
          if(float(mbti3)>1.701):
            mbti_3_char='T'
            mbti_3_char_exp = "Twice: 이 투자사는 한 스타트업에 중복해서 투자하는 성향을 보입니다"
            
          else:
            mbti_3_char='F'
            mbti_3_char_exp = "Fleeting: 이 투자사의 최근 한 스타트업에 일회적으로 투자하는 성향을 보입니다"
          
          
          # ********* MBTI 네번째 글자 ***************
          
          mbti4 =hits['MBTI_4']
          
          if (int(mbti4) > 60):
            mbti_4_char = 'J'
            mbti_4_char_exp = "Judicious: 이 투자사는 창업 3년 이상 기업 및 해당 기업의 두번째 이상의 투자사로 비교적 안정적인 투자성향을 보입니다."
          else:
            mbti_4_char = 'P'
            mbti_4_char_exp = "Peril: 이 투자사는 창업 3년 미만 기업 및 해당 기업의 첫 투자사로 비교적 공격적인 투자성향을 보입니다."
          
          
          # say(f"MBTI_1:{mbti_1_char}")
          # say(f"MBTI_2:{mbti_2_char}")
          # say(f"MBTI_3:{mbti_3_char}")
          # say(f"MBTI_4:{mbti_4_char}")
          
          message = {
              "text": "안녕하세요, 이 부분이 메시지의 주 내용입니다.",
              "blocks": [
                  {
                      "type": "section",
                      "text": {
                          "type": "mrkdwn",
                          "text": f"*💸 투자성향 MBTI 유형 분석기 💸!* \\n 투자자 크롤링 정보를 바탕으로, 최신 성향을 반영한 투자 성향을 나타내는 네가지 글자 조합\\n\\n* 🤔 투자자 {investName} 의 투자성향 MBTI는?:*\\n *✅  {mbti_1_char}* : {mbti_1_char_exp} \\n *✅  {mbti_2_char}* : {mbti_2_char_exp} \\n *✅  {mbti_3_char}* : {mbti_3_char_exp} \\n *✅  {mbti_4_char} *: {mbti_4_char_exp} \\n  "
                      }
                  }
              ]
          }
          say(message)
          
          
        else:
            say("검색 결과가 없습니다.")
        
    except Exception as e:
        say(f'오류가 발생했습니다: {str(e)}')
        
        
    
    
    

###############################################################
##### ---------- 결과물 2 투자사/스타트업 검색 ---------- #####
###############################################################

    
    
############# 2 -1 ############ ############ ############ ############
# [국내/키워드] 해당 키워드가 있는 투자사 이름들 다 가져오기##########   

@app.message(re.compile(r"국내/키워드/(.*?)"))

def search_keyword_elasticsearch(message, say, context):
  name_list2 = []
  try:
    investName = message['text'] 
    match = re.match(r"(.*?)", investName)
        
        # Elasticsearch 연결 설정
        # Elasticsearch 클러스터 연결
    es = Elasticsearch(
        cloud_id=cloud_id,
        basic_auth=(username, password),
    )
    
    body={
      "query": {
        "bool": {
          "should": [
            {
              "match": {
                "주요 투자분야": investName
              }
            },
            {
              "match": {
                "투자사 이름": investName
              }
            }
          ]
        }
      }
    }
    response = es.search(index="luck4_insight", body=body)
    info = response['hits']['hits']
    
    if info:
      for info_2 in info:
        name = info_2['_source']['투자사 이름']
        name_list2.append(name)
                
    else:
        say("검색 결과가 없습니다.")
    
  except Exception as e:
    print(e)
    
  message = {
    "blocks": [
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": f"*💸 해당 키워드가 있는 투자사들 이름들을 알려드립니다 💸!* \\n {name_list2}"
        }
      }
    ]
  }
  say(message)
    

############# 2 -2 ############ ############ ##########
# [국내/이름] 투자사별 전체 insight 정보 출력##########   

@app.message(re.compile(r"국내/이름/(.*?)"))
def search_insight_elasticsearch(message, say, context):
  
  category_list = []
  correct_name_list = []
    
  # say("hi")
  investName = message['text']  # Get the user's message text
  match = re.match(r"국내/이름/(.*?)", investName)
  investor = match.group(1)
  print(investor)

  # Elasticsearch 연결 설정
  # Elasticsearch 클러스터 연결
  es = Elasticsearch(
      cloud_id=cloud_id,            
      basic_auth=(username, password),
  )
  
  ### 투자사 이름을 제대로 칠 경우 ###
  while True:
    try:
        
        body={
          "query": {
            "bool": {
              "must": [
                {
                  "match": {
                    "투자사 이름": investName
                  }
                }
                
              ]
            }
          }
        }
        response = es.search(index="luck4_insight", body=body)
        info = response['hits']['hits'][0]["_source"]
        
        if info:
            ##### 투자 한 카테고리 가져오기 ####
            categories_str = info['주요 투자분야']
            categories_list = ast.literal_eval(categories_str)
        
            for category in categories_list:
              c = category['category']
              category_list.append(c)
              
              
            #### 나머지 정보
            total_startup_num = info['투자 기업수']
            total_invest_num = info['총 투자 횟수']
            invest_stage = info['선호 투자 단계']
            startup_num = info['스타트업이 첫  투자']
            three_year_num = info['창업 3년미만기업']
        else:
            say("검색 결과가 없습니다.")
            
        
        message = {
            "blocks": [
                {
                    "type": "section",
                    "text": {
                        "type": "mrkdwn",
                        "text": f"*🧵 국내 투자사 검색 결과 🧵* \\n 📂 *총 투자 기업수*:{total_startup_num} \\n 📂 *총 투자 횟수*: {total_invest_num}\\n 📂 *선호 투자 단계*: {invest_stage} \\n 📂 *스타트업이 첫 투자*: {startup_num} \\n 📂 *창업 3년 미만 기업에 투자한 횟수*: {three_year_num} \\n 📂 *투자 분야 카테고리*: \\n {category_list}"
                    }
                }
            ]
        }
        say(message)
        break
            
            
    #### 투자사 이름을 잘못 친경우 ###
    except Exception as e:
        print(e)
        # wildcard_value = investor+"*"
        # print(wildcard_value)

        # body = {
        #   "query": {
        #     "wildcard": {
        #       "투자사 이름": {
        #         # "value": "신*"
        #         "value": wildcard_value
        #       }
        #     }
        #   }
        # }

        
        # response = es.search(index="luck4_insight", body=body)
        # info = response['hits']['hits']
        # print("여기")
        
        # if info:
        #     print("info")
        
        #     for i in info:
        #         # print("here")
        #         name = i['_source']['투자사 이름']
        #         # print("name:"+name)
        #         correct_name_list.append(name)
            
        
        
        #     say(f'{correct_name_list} \\n\\n 중에 어떤것을 말씀하시는 것인가요? 다시 입력해주세요\\n 투자사 이름을 정확히 기입해주세요. \\n 형식 : (투자사 이름) 전체 검색 해줘')
            
            
        # else:
        #     say("검색결과가 없습니다")
        #     break
        
        
        
        
############# 2 -3 ############ ############ ##########
# [국내/분야] 분야별 해당 투자사 이름 나열##########   

@app.message(re.compile("국내/분야/(.*?)"))
def search_insight_category_elasticsearch(message, say, context):
  name_list = []
  try:
      # say("hi")
      investName = message['text']  # Get the user's message text
      match = re.match(r"(.*?)", investName)
      
      # Elasticsearch 연결 설정
      # Elasticsearch 클러스터 연결
      es = Elasticsearch(
          cloud_id=cloud_id,
          basic_auth=(username, password),
      )
  
      body={
        "query": {
          "bool": {
            "must": [
              {
                "match": {
                  "주요 투자분야": investName
                }
              }
              
            ]
          }
        }
      }
      response = es.search(index="luck4_insight", body=body)
      info = response['hits']['hits']
      
      
      if info:
          
          for info_2 in info:
              
              name = info_2['_source']['투자사 이름']
              name_list.append(name)
              
      else:
          say("검색 결과가 없습니다.")
      
  except Exception as e:
      say(f'오류가 발생했습니다: {str(e)}')
      
      
  message = {
      "blocks": [
          {
              "type": "section",
              "text": {
                  "type": "mrkdwn",
                  "text": f"*💸 {investName} 카테고리에 투자한 회사 알려드립니다💸!* \\n {name_list}"
              }
          }
      ]
  }
  say(message)
    
    
# 해외/이름/검색 키워드
@app.message(re.compile("해외/이름/(.*?)"))
def search_mercury_investor_by_name(message, say, context):
  try:
    say("안녕하세요 😊 검색하신 해외 투자자의 인사이트를 찾아드립니다🚀")
    investName = message['text']  # Get the user's message text
    match = re.match(r"해외/이름/(.*?)", investName)
    
    search_keyword = investName[6:]
    # say(search_keyword)
    
    # Elasticsearch 연결 설정
    # Elasticsearch 클러스터 연결
    es = Elasticsearch(
        cloud_id=cloud_id,
        basic_auth=(username, password),
    )

    body={
      "size" : 5,
      "query": {
        "wildcard": {
          "name.keyword": f"*{search_keyword}*"
        }
      }
    }
    
    response = es.search(index="luck4_db_elastic", body=body)
    
    if(response["hits"]["total"]["value"]==0):
      say("봇 생성 중 에러가 발생하여 프로그램을 종료합니다.")
      raise SystemExit("봇 생성 중 에러가 발생하여 프로그램을 종료합니다.")
      # return
    
    hits = response["hits"]["hits"] # 검색 결과가 배열로 저장이 되어있다
    
    
  except Exception as e:
    say("봇 생성 중 에러가 발생하여 프로그램을 종료합니다.")
    raise SystemExit("봇 생성 중 에러가 발생하여 프로그램을 종료합니다.")
    # print(e)
    # return
  
    
  result_message = {
      "blocks": [
          {
              "type": "section",
              "text": {
                  "type": "mrkdwn",
                  "text": f"*🌏 해외 투자사 검색 결과 🌏*\\n검색하신 키워드 {search_keyword} 에 해당하는 해외 투자사 정보입니다:\\n"
              }
          },
          {
            "type":"divider"
          }
      ]
  }
  
  result_count=0
  
  for hit in hits:
    result_count+=1
    if(result_count==6): 
      say("봇 생성 중 에러가 발생하여 프로그램을 종료합니다.")
      sys.exit(0)
      raise SystemExit("봇 생성 중 에러가 발생하여 프로그램을 종료합니다.")
      # return
    # 이름
    inv_name = hit["_source"]["name"]
    inv_name = inv_name.replace("\\n", "").replace("\\r", "")
    
    inv_role = hit["_source"]["role"]
    inv_type = hit["_source"]["type"]
    inv_bio = hit["_source"]["bio"]
    inv_stages = hit["_source"]["stages"]
    inv_geography = hit["_source"]["geography"]
    inv_checkrange= hit["_source"]["checkrange"]
    inv_industries_list= hit["_source"]["industries"]
    inv_industries=",".join(map(str, inv_industries_list))
    inv_aboutinvest= hit["_source"]["aboutinvest"]
    
    inv_linkedinlink= hit["_source"]["linkedinlink"] if "_source" in hit and "linkedinlink" in hit["_source"] else "none"
    inv_twitterlink = hit["_source"]["twitterlink"] if "_source" in hit and "twitterlink" in hit["_source"] else "none"
    # inv_twitterlink= hit["_source"]["twitterlink"]
    inv_fundlink= hit["_source"]["fundlink"] if "_source" in hit and "fundlink" in hit["_source"] else "none"
    inv_email= hit["_source"]["email"] if "_source" in hit and "email" in hit["_source"] else "none"
    
    
    result_message["blocks"].append(
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": f" *🕵 {result_count}번째 검색결과* \\n\\n 📁 투자자 이름: {inv_name} \\n 📁 투자자 직책: {inv_role} \\n 📁 투자자 유형: {inv_type} \\n📁 투자자 선호 투자단계: {inv_stages} \\n📁 투자자 지역: {inv_geography} \\n 📁 투자 금액: {inv_checkrange} \\n 📁 선호 투자 분야: {inv_industries} \\n  🚩 투자 성향: {inv_aboutinvest} \\n"
          
        }
      }
    )
    result_message["blocks"].append(
      {
        "type" : "divider"
      }
    )
  
  say(result_message)
  return
      
      
              

    

# 해외/분야/검색 키워드
@app.message(re.compile("해외/분야/(.*?)"))
def search_mercury_investor_by_industry(message, say, context):
  try:
    say("안녕하세요 😊 검색하신 카테고리에 해당하는 해외 투자자의 인사이트를 찾아드립니다🚀")
    categoryName = message['text']  # Get the user's message text
    match = re.match(r"해외/분야/(.*?)", categoryName)
    
    search_keyword = categoryName[6:]
    # say(search_keyword)
    
    # Elasticsearch 연결 설정
    # Elasticsearch 클러스터 연결
    es = Elasticsearch(
        cloud_id=cloud_id,
        basic_auth=(username, password),
    )

    body={
      "size" : 5,
      "query": {
        "wildcard": {
          "industries": f"*{search_keyword}*"
        }
      }
    }
    
    response = es.search(index="luck4_db_elastic", body=body)
    
    if(response["hits"]["total"]["value"]==0): return
    
    hits = response["hits"]["hits"] # 검색 결과가 배열로 저장이 되어있다
    
    
  except Exception as e:
    print(e)
    return
  
  result_message = {
      "blocks": [
          {
              "type": "section",
              "text": {
                  "type": "mrkdwn",
                  "text": f"*🌏 해외 투자사 검색 결과 🌏*\\n검색하신 분야 {search_keyword} 에 투자하는 해외 투자사 정보입니다:\\n"
              }
          },
          {
            "type":"divider"
          }
      ]
  }
    
  result_count=0
  
  for hit in hits:
    result_count+=1
    if(result_count==6): 
      sys.exit(0)
      return
    # 이름
    inv_name = hit["_source"]["name"]
    inv_name = inv_name.replace("\\n", "").replace("\\r", "")
    
    inv_role = hit["_source"]["role"]
    inv_type = hit["_source"]["type"]
    inv_bio = hit["_source"]["bio"]
    inv_stages = hit["_source"]["stages"]
    inv_geography = hit["_source"]["geography"]
    inv_checkrange= hit["_source"]["checkrange"]
    inv_industries_list= hit["_source"]["industries"]
    inv_industries=",".join(map(str, inv_industries_list))
    inv_aboutinvest= hit["_source"]["aboutinvest"]
    
    inv_linkedinlink= hit["_source"]["linkedinlink"] if "_source" in hit and "linkedinlink" in hit["_source"] else "none"
    inv_twitterlink = hit["_source"]["twitterlink"] if "_source" in hit and "twitterlink" in hit["_source"] else "none"
    # inv_twitterlink= hit["_source"]["twitterlink"]
    inv_fundlink= hit["_source"]["fundlink"] if "_source" in hit and "fundlink" in hit["_source"] else "none"
    inv_email= hit["_source"]["email"] if "_source" in hit and "email" in hit["_source"] else "none"
    
    
    result_message["blocks"].append(
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": f" *🕵 {result_count}번째 검색결과* \\n\\n 📁 투자자 이름: {inv_name} \\n 📁 투자자 직책: {inv_role} \\n 📁 투자자 유형: {inv_type} \\n📁 투자자 선호 투자단계: {inv_stages} \\n📁 투자자 지역: {inv_geography} \\n 📁 투자 금액: {inv_checkrange} \\n 📁 선호 투자 분야: {inv_industries} \\n  🚩 투자 성향: {inv_aboutinvest} \\n"
          
        }
      }
    )
    result_message["blocks"].append(
      {
        "type" : "divider"
      }
    )
  
  say(result_message)
  return
      
      
              
    
    
    
# 해외/키워드/검색 키워드
@app.message(re.compile("해외/전체/(.*?)"))
def search_mercury_investor_by_total(message, say, context):
  try:
    # say("안녕하세요 😊 검색하신 키워드에 해당하는 해외 투자자의 인사이트를 찾아드립니다🚀")
    totalName = message['text']  # Get the user's message text
    match = re.match(r"해외/전체/(.*?)", totalName)
    
    search_keyword = totalName[6:]
    say(f"안녕하세요 😊 검색하신 키워드{search_keyword}에 해당하는 해외 투자자의 인사이트를 찾아드립니다🚀")
    # say(search_keyword)
    
    # Elasticsearch 연결 설정
    # Elasticsearch 클러스터 연결
    es = Elasticsearch(
        cloud_id=cloud_id,
        basic_auth=(username, password),
    )

    body={
      "size":5,
      "query": {
        "query_string": {
          "query": f"*{search_keyword}*"
        }
      }
    }
    
    response = es.search(index="luck4_db_elastic", body=body)
    
    if(response["hits"]["total"]["value"]==0): 
      sys.exit(0)
      return
    hits = response["hits"]["hits"] # 검색 결과가 배열로 저장이 되어있다
    
  except Exception as e:
    say("🚨 찾으시는 항목을 찾지 못�����였습니다. 다시 한번 확인해주세요")
    print(e)
    return
  
  result_message = {
      "blocks": [
          {
              "type": "section",
              "text": {
                  "type": "mrkdwn",
                  "text": f"*🌏 해외 투자사 검색 결과 🌏*\\n검색하신 키워드 {search_keyword} 에 투자하는 해외 투자사 정보입니다:\\n"
              }
          },
          {
            "type":"divider"
          }
      ]
  }
    
  result_count=0
  
  for hit in hits:
    result_count+=1
    if(result_count==6): 
      # break
      sys.exit(0)
      return
    # 이름
    inv_name = hit["_source"]["name"]
    inv_name = inv_name.replace("\\n", "").replace("\\r", "")
    
    inv_role = hit["_source"]["role"]
    inv_type = hit["_source"]["type"]
    inv_bio = hit["_source"]["bio"]
    inv_stages = hit["_source"]["stages"]
    inv_geography = hit["_source"]["geography"]
    inv_checkrange= hit["_source"]["checkrange"]
    inv_industries_list= hit["_source"]["industries"]
    inv_industries=",".join(map(str, inv_industries_list))
    inv_aboutinvest= hit["_source"]["aboutinvest"] if "_source" in hit and "aboutinvest" in hit["_source"] else "none"
    
    inv_linkedinlink= hit["_source"]["linkedinlink"] if "_source" in hit and "linkedinlink" in hit["_source"] else "none"
    inv_twitterlink = hit["_source"]["twitterlink"] if "_source" in hit and "twitterlink" in hit["_source"] else "none"
    # inv_twitterlink= hit["_source"]["twitterlink"]
    inv_fundlink= hit["_source"]["fundlink"] if "_source" in hit and "fundlink" in hit["_source"] else "none"
    inv_email= hit["_source"]["email"] if "_source" in hit and "email" in hit["_source"] else "none"
    
    
    result_message["blocks"].append(
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": f" *🕵 {result_count}번째 검색결과* \\n\\n 📁 투자자 이름: {inv_name} \\n 📁 투자자 직책: {inv_role} \\n 📁 투자자 유형: {inv_type} \\n📁 투자자 선호 투자단계: {inv_stages} \\n📁 투자자 지역: {inv_geography} \\n 📁 투자 금액: {inv_checkrange} \\n 📁 선호 투자 분야: {inv_industries} \\n  🚩 투자 성향: {inv_aboutinvest} \\n"
          
        }
      }
    )
    result_message["blocks"].append(
      {
        "type" : "divider"
      }
    )
  
  say(result_message)
  return
      
      

    

# BASE         
if __name__ == '__main__':
    SocketModeHandler(app, config.app_token).start()