from fastapi import APIRouter, HTTPException, Request, Depends
from fastapi.responses import RedirectResponse
import openai
from openai import OpenAI
import re
import boto3
import os
import time
import db_module
from schemas import ChatMessage, SpeechText, QuizMessage, LineUser, MedicineText, UserQuestion
from config import logger, openai_api_key
import httpx
import json
import pandas as pd
import PyPDF2
from sklearn.feature_extraction.text import TfidfVectorizer
import logging

router = APIRouter()

openai.api_key = openai_api_key
client = OpenAI(api_key=openai_api_key)

s3_client = boto3.client('s3')
bucket_name = 'shanri-ai-chatbot-for-text-to-speech'

# 파일 경로 설정
PDF_FILE = "/home/GPT/reference.pdf"
EXCEL_FILE = "/home/GPT/QA.xlsx"


async def ask_openai(messages):
    valid_messages = [msg for msg in messages if msg.get('content')]
    response = openai.chat.completions.create(
        model="gpt-4o",
        messages=valid_messages
    )
    answer = response.choices[0].message.content.strip()
    return answer


async def synthesize_speech(text, user_id):
    response = client.audio.speech.create(
        model="tts-1",
        voice="nova",
        input=text,
    )
    audio_file = f"tmp/audio-{user_id}-{time.time()}.mp3"
    with open(audio_file, 'wb') as f:
        for chunk in response.iter_bytes():
            f.write(chunk)
    s3_key = f"{user_id}-{time.time()}.mp3"
    s3_client.upload_file(audio_file, bucket_name, s3_key)
    os.remove(audio_file)
    return f"https://{bucket_name}.s3.amazonaws.com/{s3_key}"


# PDF 파일에서 텍스트 추출
def load_pdf_data(file_path):
    text = ""

    try:
        with open(file_path, "rb") as file:
            reader = PyPDF2.PdfReader(file)
            for page in reader.pages:
                text += page.extract_text() + "\n"
    except Exception as e:
        print(f"Error reading PDF: {e}")

    return text


# 엑셀 파일 로드 (전체 시트 순환, 부분 일치 검색을 위한 리스트 저장)
def load_excel_data(file_path):
    data = []
    xls = pd.ExcelFile(file_path)

    for sheet_name in xls.sheet_names:
        df = pd.read_excel(xls, sheet_name=sheet_name, dtype=str)  # 컬럼명을 자동 인식

        # 컬럼명이 "question"과 "answer"인지 확인
        if "question" in df.columns and "answer" in df.columns:
            for _, row in df.iterrows():
                question = row["question"].strip() if pd.notna(row["question"]) else None
                answer = row["answer"].strip() if pd.notna(row["answer"]) else None
                if question:
                    data.append((question, answer))

    return data


def initialize_data():
    logging.info("Loading initial data...")
    pdf_text = load_pdf_data(PDF_FILE)
    qa_data = load_excel_data(EXCEL_FILE)
    logging.info("Initial Data Load Completed")

    return pdf_text, qa_data


pdf_text, qa_data = initialize_data()


# 질문과 가장 관련 있는 PDF 텍스트 추출 - 라이브러리를 사용했지만 잘 작동되지않는 경우가 있음 -> 추후에 우리의 알고리즘으로 대체체
def find_relevant_text(question, pdf_text, max_length=1000):
    sentences = pdf_text.split("\n")  # 문장 단위로 나누기
    vectorizer = TfidfVectorizer().fit_transform([question] + sentences)
    similarities = (vectorizer * vectorizer.T).toarray()[0][1:]

    # 유사도가 높은 문장 정렬 후 상위 몇 개만 선택
    top_sentences = [sentences[i] for i in similarities.argsort()[-10:]]

    return "\n".join(top_sentences)[:max_length]


# GPT를 이용해 질문 키워드 기반 답변 생성 (PDF 관련 내용 포함)
async def generate_gpt_answer(question, reference_text):
    response = openai.chat.completions.create(
        model="gpt-3.5-turbo",
        messages=[
            {"role": "system", "content": "与えられた質問を見て、referenceの内容を活用して一つの文章で回答を作成してください。"},
            {"role": "system", "content": f"reference:\n{reference_text}"},
            {"role": "system", "content": "回答に何を参照したかは言わないでほしい。"},
            {"role": "user", "content": question}
        ]
    )

    return response.choices[0].message.content


@router.get("/health")
async def health_check():
    return {"status": "healthy"}


@router.post("/api/speech")
async def speech(speech_text: SpeechText):
    text = speech_text.text
    chat_token = speech_text.chat_token
    if not text:
        raise HTTPException(status_code=400, detail="Text is required")
    audio_file = await synthesize_speech(text, chat_token)
    return {"audio_file": audio_file}


# 질문을 받아서 처리하는 API
@router.post('/api/ask_question')
async def ask_question(user_question: UserQuestion):
    question_text = user_question.question.strip()
    if not question_text:
        raise HTTPException(status_code=400, detail="Question is required")

    # 엑셀에서 질문 포함 여부 검색
    matched_answers = [answer for question, answer in qa_data if question_text in question]

    if matched_answers and matched_answers[0] is not None:
        return {"answer": matched_answers[0]}  # 첫 번째 일치 항목 반환

    # 관련 PDF 내용을 찾아 GPT로 답변 생성
    relevant_text = find_relevant_text(question_text, pdf_text)
    generated_answer = await generate_gpt_answer(question_text, relevant_text)
    return {"answer": generated_answer}



