from fastapi import APIRouter, HTTPException
from fastapi.responses import RedirectResponse
import openai
from openai import OpenAI
import boto3
import os
import time
from schemas import SpeechText, UserQuestion
from config import logger, openai_api_key
from datetime import datetime
import chromadb
from chromadb.config import Settings
import re
from datetime import datetime

# 🔧 ChromaDB 설정
chroma_client = chromadb.HttpClient(
    host="localhost",
    port=8001,
    settings=Settings(chroma_api_impl="rest")
)
collection_profile = chroma_client.get_collection("segue_profile_split4")
collection_qna = chroma_client.get_collection("segue_qna_by_question2")

# 🔧 OpenAI 설정
openai.api_key = openai_api_key
client = OpenAI(api_key=openai_api_key)

# 🔧 S3 설정
s3_client = boto3.client('s3')
bucket_name = 'shanri-ai-chatbot-for-text-to-speech'

router = APIRouter()

# ✅ 음성 합성
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}"

# ✅ QnA 검색
async def search_qna_answer(question: str) -> str:
    response = client.embeddings.create(
        model="text-embedding-3-small",
        input=question
    )
    query_embedding = response.data[0].embedding

    results = collection_qna.query(
        query_embeddings=[query_embedding],
        n_results=1
    )

    if not results or not results['documents'] or not results['documents'][0]:
        return "情報がありません。"

    answer = results['documents'][0][0]
    distance = results['distances'][0][0]

    if distance > 0.3:
        return "情報がありません。"
    return answer

# # ✅ Profile 검색
# async def search_profile_context(question: str) -> str | None:
#     response = client.embeddings.create(
#         model="text-embedding-3-small",
#         input=question
#     )
#     query_embedding = response.data[0].embedding

#     results = collection_profile.query(
#         query_embeddings=[query_embedding],
#         n_results=1
#     )

#     if not results or not results['documents'] or not results['documents'][0]:
#         return None

#     return "\n\n".join(results['documents'][0])

# ✅ page_type 복정 함수
def correct_page_type_by_keyword(question: str, original_page_type: str) -> str:
    if any(k in question for k in ["キャッシュフロー", "貸借対照表", "財務諸表"]):
        print("[DEBUG] キーワードにより 'finance' に上書きされました")
        return "finance"
    elif any(k in question for k in ["売上高", "営業利益", "経常利益", "純利益"]):
        print("[DEBUG] キーワードにより 'performance' に上書きされました")
        return "performance"
    elif any(k in question for k in ["商品", "製品"]):
        print("[DEBUG] キーワードにより 'business' に上書きされました")
        return "business"
    return original_page_type


# ✅ Profile 검색 (메타데이터 기반 전체 반환)
async def search_profile_context_by_metadata(question: str) -> str | None:
    # ✅ Step 1: GPT로 page_type 추론
    system_prompt = """
以下のカテゴリの中から、質問が該当するカテゴリを1つ選び、カテゴリ名（英語）だけを出力してください。
- overview
- history
- welfare
- training
- message
- performance
- executives
- sustainability
- strategy
- stock
- business
- finance
- philosophy

【注意】
- 売上高、営業利益、経常利益、純利益 などの業績に関する質問は「performance」としてください。
- 財務諸表、貸借対照表、キャッシュフロー に関する質問は「finance」としてください。

回答はカテゴリ名だけで、他の言葉は含めないでください。
"""
    chat = client.chat.completions.create(
        model="gpt-4o",
        messages=[
            {"role": "system", "content": system_prompt},
            {"role": "user", "content": question}
        ]
    )
    page_type = chat.choices[0].message.content.strip().lower()

    page_type = correct_page_type_by_keyword(question, page_type)

    print(f"[DEBUG] 推論された page_type: {page_type}")

    # ✅ Step 2: GPT 또는 룰로 year 추출
    def extract_year_range(question: str) -> list[int]:
        current_year = datetime.now().year
        years = set()

        # ① 명시적 연도 (예: 2021年, 2022年)
        matches = re.findall(r"(20[0-3][0-9])年", question)
        years.update(int(y) for y in matches)

        # ② 연도 범위 (예: 2022〜2023年 or 2022-2023年)
        range_match = re.search(r"(20[0-3][0-9])\s*[〜~\-]\s*(20[0-3][0-9])年", question)
        if range_match:
            start, end = int(range_match.group(1)), int(range_match.group(2))
            years.update(range(start, end + 1))

        # ③ 「過去3年」「過去5年」 등의 표현
        past_match = re.search(r"過去(\d)年", question)
        if past_match:
            n = int(past_match.group(1))
            years.update(current_year - i for i in range(1, n + 1))

        # ④ 「昨年」「一昨年」
        if "昨年" in question:
            years.add(current_year - 1)
        if "一昨年" in question:
            years.add(current_year - 2)

        return sorted(years)

    year_list = extract_year_range(question)

    # ✅ Step 3: where 조건 구성
    if page_type == "performance" and year_list:
        where = {
            "$and": [
                {"page_type": page_type},
                {"year": {"$in": year_list}}
            ]
        }
    else:
        where = {"page_type": page_type}

    # ✅ Step 4: 문서 전체 검색
    # results = collection_profile.get(
    #     where=where,
    #     limit=100
    #  )
    
    response = client.embeddings.create(
    model="text-embedding-3-small",
    input=question
    )
    query_embedding = response.data[0].embedding

    results = collection_profile.query(
        query_embeddings=[query_embedding],
        n_results=100,
        where=where
    )

    docs = results.get("documents", [])
    if not docs or not docs[0]:
        return None

    joined_docs = "\n\n".join(docs[0])
    return joined_docs

# ✅ GPT 대답 생성 로직 (QnA → Profile + GPT → 정보 없음)
async def generate_gpt_answer(question: str) -> str:
    # Step 1: QnA 우선 검색
    answer = await search_qna_answer(question)
    if answer != "情報がありません。":
        return answer

    # Step 2: Profile 검색
    profile_data = await search_profile_context_by_metadata(question)
    print(f"[DEBUG] 取得した profile データ:\n{profile_data}...")
    if not profile_data:
        return "情報がありません。"

    # Step 3: GPT 생성
    if not question.startswith("御社の"):
        question = "御社の" + question

    # BUSINESS_STYLE_EXAMPLES = """
    # ご質問ありがとうございます。セグエグループ株式会社は2014年に設立され、東京都中央区に本社を構えるIT企業でございます。主にセキュリティおよびネットワークソリューションを中心に、企業向けITサービスを提供しております。代表取締役社長の愛須康之が主要株主でございます。ご不明な点がございましたら、どうぞお申し付けください。

    # お問い合わせいただき、誠にありがとうございます。セグエグループ株式会社は2014年設立、本社は東京都中央区にございます。セキュリティやネットワーク分野に強みを持ち、法人のお客様向けにITサービスを展開しております。代表取締役社長の愛須康之が主要株主です。追加のご質問がございましたらご遠慮なくご連絡ください。

    # ご関心をお寄せいただき、ありがとうございます。当社は2014年創業、東京都中央区に本社を置くIT企業です。セキュリティおよびネットワークソリューションを中心に、企業様向けITサービスをご提供しております。代表取締役社長の愛須康之が主要株主となっております。さらなるご要望がございましたら、お知らせください。

    # ご質問いただき、ありがとうございます。セグエグループ株式会社は2014年に設立され、東京都中央区に本社がございます。セキュリティやネットワーク分野に特化し、法人向けITサービスを幅広くご提供しております。代表取締役社長の愛須康之が主要株主です。ご不明な点がございましたら、引き続きご質問を承ります。

    # この度はお問い合わせいただき、ありがとうございます。セグエグループ株式会社は2014年設立、本社は東京都中央区にございます。主にセキュリティおよびネットワークソリューションを中心に、企業向けITサービスを展開しております。代表取締役社長の愛須康之が主要株主でございます。ご確認のうえ、追加でご質問があればお知らせください。

    # ご質問を賜り、誠にありがとうございます。当社は2014年に設立され、東京都中央区に本社を構えております。セキュリティやネットワーク分野に強みを持ち、法人向けITサービスを提供しております。代表取締役社長の愛須康之が主要株主です。ご不明点やご要望がございましたら、どうぞご遠慮なくお尋ねください。

    # ご照会いただき、ありがとうございます。セグエグループ株式会社は2014年設立、東京都中央区に本社を置くIT企業でございます。セキュリティおよびネットワークソリューションを中心に、企業様向けITサービスを提供しております。代表取締役社長の愛須康之が主要株主となっております。ご不明な点がございましたら、追加でご質問ください。

    # お問い合わせいただき、誠にありがとうございます。当社は2014年に設立され、東京都中央区に本社を構えております。セキュリティやネットワーク分野に特化し、法人向けITサービスを展開しております。代表取締役社長の愛須康之が主要株主でございます。ご不明点がございましたら、引き続きご連絡ください。

    # ご質問いただき、感謝申し上げます。セグエグループ株式会社は2014年創業、東京都中央区に本社を置くIT企業です。セキュリティやネットワークソリューションを中心に、企業向けITサービスを提供しております。代表取締役社長の愛須康之が主要株主です。ご質問やご要望がございましたら、いつでもご連絡ください。

    # ご関心をお寄せいただき、誠にありがとうございます。セグエグループ株式会社は2014年に設立され、東京都中央区に本社がございます。セキュリティやネットワークソリューションを中心に、企業様向けITサービスをご提供しております。代表取締役社長の愛須康之が主要株主でございます。ご不明な点や追加のご質問がございましたら、お気軽にお知らせください。
    # """


    messages = [
    {"role": "system", "content": "あなたは「セグエグループ」の会社紹介および就職希望者向けのチャットボットです。"},
    {"role": "system", "content": "以下のルールに従って、ユーザーと会話してください。"},
    {"role": "system", "content": f"1.会話スタイル：丁寧で信頼感のあるビジネス口調で応答してください。"},
    # {"role": "system", "content": f"1.会話スタイル：丁寧で信頼感のあるビジネス口調で応答してください。\n以下の文体を参考にして、類似の語調・構文でご回答ください：\n\n{BUSINESS_STYLE_EXAMPLES}"},
    {"role": "system", "content": "2.トーン：敬語を用いながらも、丁寧で親しみやすい表現を心がけてください。"},
    {"role": "system", "content": "3.情報の制限：返答に使用できるのは、提供されたURLとExcelファイルに含まれる情報のみとします。その他の情報は使用しないでください。"},
    {"role": "system", "content": "4.数値データ形式：数値がある場合は、マークダウン形式の表で表示してください。"},
    {"role": "system", "content": "この制約のもと、ユーザーに寄り添いながら会話を進めてください。"},
    {"role": "system", "content": f"企業サイト情報\n{profile_data}"},
    {"role": "user", "content": question}
]

    print(datetime.now(), "GPT 응답 생성 시작")
    response = client.chat.completions.create(
        model="gpt-4o",
        messages=messages
    )
    print(datetime.now(), "GPT 응답 생성 완료")

    return response.choices[0].message.content.strip()

# ✅ 건강 체크
@router.get("/health")
async def health_check():
    return {"status": "healthy"}

# ✅ 음성 요청 처리
@router.post("/apige/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("/apige/ask_question")
async def gemini_question(user_question: UserQuestion):
    question_text = user_question.question.strip()
    if not question_text:
        raise HTTPException(status_code=400, detail="Question is required")

    generated_answer = await generate_gpt_answer(question_text)
    return {"answer": generated_answer}
