import sqlite3
import gradio as gr
from dog_database import get_dog_description, dog_data
from breed_health_info import breed_health_info
from breed_noise_info import breed_noise_info
from scoring_calculation_system import UserPreferences, calculate_compatibility_score
from recommendation_html_format import format_recommendation_html, get_breed_recommendations
from search_history import create_history_tab, create_history_component
from smart_breed_matcher import SmartBreedMatcher
from description_search_ui import create_description_search_tab

def create_recommendation_tab(UserPreferences, get_breed_recommendations, format_recommendation_html, history_component):

    with gr.TabItem("Breed Recommendation"):
        with gr.Tabs():
            with gr.Tab("Find by Criteria"):
                gr.HTML("""
                    <div style='
                        text-align: center;
                        padding: 20px 0;
                        margin: 15px 0;
                        background: linear-gradient(to right, rgba(66, 153, 225, 0.1), rgba(72, 187, 120, 0.1));
                        border-radius: 10px;
                    '>
                        <p style='
                            font-size: 1.2em;
                            margin: 0;
                            padding: 0 20px;
                            line-height: 1.5;
                            background: linear-gradient(90deg, #4299e1, #48bb78);
                            -webkit-background-clip: text;
                            -webkit-text-fill-color: transparent;
                            font-weight: 600;
                        '>
                            Tell us about your lifestyle, and we'll recommend the perfect dog breeds for you!
                        </p>
                    </div>
                """)

                with gr.Row():
                    with gr.Column():
                        living_space = gr.Radio(
                            choices=["apartment", "house_small", "house_large"],
                            label="What type of living space do you have?",
                            info="Choose your current living situation",
                            value="apartment"
                        )

                        exercise_time = gr.Slider(
                            minimum=0,
                            maximum=180,
                            value=60,
                            label="Daily exercise time (minutes)",
                            info="Consider walks, play time, and training"
                        )

                        grooming_commitment = gr.Radio(
                            choices=["low", "medium", "high"],
                            label="Grooming commitment level",
                            info="Low: monthly, Medium: weekly, High: daily",
                            value="medium"
                        )

                    with gr.Column():
                        experience_level = gr.Radio(
                            choices=["beginner", "intermediate", "advanced"],
                            label="Dog ownership experience",
                            info="Be honest - this helps find the right match",
                            value="beginner"
                        )

                        has_children = gr.Checkbox(
                            label="Have children at home",
                            info="Helps recommend child-friendly breeds"
                        )

                        noise_tolerance = gr.Radio(
                            choices=["low", "medium", "high"],
                            label="Noise tolerance level",
                            info="Some breeds are more vocal than others",
                            value="medium"
                        )

                get_recommendations_btn = gr.Button("Find My Perfect Match! 🔍", variant="primary")
                recommendation_output = gr.HTML(label="Breed Recommendations")

            with gr.Tab("Find by Description"):
                description_input, description_search_btn, description_output, loading_msg = create_description_search_tab()


        def on_find_match_click(*args):
            try:
                user_prefs = UserPreferences(
                    living_space=args[0],
                    exercise_time=args[1],
                    grooming_commitment=args[2],
                    experience_level=args[3],
                    has_children=args[4],
                    noise_tolerance=args[5],
                    space_for_play=True if args[0] != "apartment" else False,
                    other_pets=False,
                    climate="moderate",
                    health_sensitivity="medium",  # 新增: 默認中等敏感度
                    barking_acceptance=args[5]    # 使用 noise_tolerance 作為 barking_acceptance
                )

                recommendations = get_breed_recommendations(user_prefs, top_n=10)

                history_results = [{
                    'breed': rec['breed'],
                    'rank': rec['rank'],
                    'overall_score': rec['final_score'],
                    'base_score': rec['base_score'],
                    'bonus_score': rec['bonus_score'],
                    'scores': rec['scores']
                } for rec in recommendations]

                # 保存到歷史記錄,也需要更新保存的偏好設定
                history_component.save_search(
                    user_preferences={
                        'living_space': args[0],
                        'exercise_time': args[1],
                        'grooming_commitment': args[2],
                        'experience_level': args[3],
                        'has_children': args[4],
                        'noise_tolerance': args[5],
                        'health_sensitivity': "medium",
                        'barking_acceptance': args[5]
                    },
                    results=history_results
                )

                return format_recommendation_html(recommendations, is_description_search=False)

            except Exception as e:
                print(f"Error in find match: {str(e)}")
                import traceback
                print(traceback.format_exc())
                return "Error getting recommendations"
        

        def on_description_search(description: str):
            try:
                # 初始化匹配器
                matcher = SmartBreedMatcher(dog_data)
                breed_recommendations = matcher.match_user_preference(description, top_n=10)

                # 從描述中提取用戶偏好
                user_prefs = UserPreferences(
                    living_space="apartment" if any(word in description.lower()
                        for word in ["apartment", "flat", "condo"]) else "house_small",
                    exercise_time=120 if any(word in description.lower()
                        for word in ["active", "exercise", "running", "athletic", "high energy"]) else 60,
                    grooming_commitment="high" if any(word in description.lower()
                        for word in ["grooming", "brush", "maintain"]) else "medium",
                    experience_level="experienced" if any(word in description.lower()
                        for word in ["experienced", "trained", "professional"]) else "intermediate",
                    has_children=any(word in description.lower()
                        for word in ["children", "kids", "family", "child"]),
                    noise_tolerance="low" if any(word in description.lower()
                        for word in ["quiet", "peaceful", "silent"]) else "medium",
                    space_for_play=any(word in description.lower()
                        for word in ["yard", "garden", "outdoor", "space"]),
                    other_pets=any(word in description.lower()
                        for word in ["other pets", "cats", "dogs"]),
                    climate="moderate",
                    health_sensitivity="high" if any(word in description.lower()
                        for word in ["health", "medical", "sensitive"]) else "medium",
                    barking_acceptance="low" if any(word in description.lower()
                        for word in ["quiet", "no barking"]) else None
                )

                final_recommendations = []

                for smart_rec in breed_recommendations:
                    breed_name = smart_rec['breed']
                    breed_info = get_dog_description(breed_name)
                    if not isinstance(breed_info, dict):
                        continue

                    # 獲取基礎分數
                    base_score = smart_rec.get('base_score', 0.7)
                    similarity = smart_rec.get('similarity', 0)
                    is_preferred = smart_rec.get('is_preferred', False)

                    bonus_reasons = []
                    bonus_score = 0

                    # 1. 尺寸評估
                    size = breed_info.get('Size', '')
                    if size in ['Small', 'Tiny']:
                        if "apartment" in description.lower():
                            bonus_score += 0.05
                            bonus_reasons.append("Suitable size for apartment (+5%)")
                        else:
                            bonus_score -= 0.25
                            bonus_reasons.append("Size too small (-25%)")
                    elif size == 'Medium':
                        bonus_score += 0.15
                        bonus_reasons.append("Ideal size (+15%)")
                    elif size == 'Large':
                        if "apartment" in description.lower():
                            bonus_score -= 0.05
                            bonus_reasons.append("May be too large for apartment (-5%)")
                    elif size == 'Giant':
                        bonus_score -= 0.20
                        bonus_reasons.append("Size too large (-20%)")

                    # 2. 運動需求評估
                    exercise_needs = breed_info.get('Exercise_Needs', '')
                    if any(word in description.lower() for word in ['active', 'energetic', 'running']):
                        if exercise_needs in ['High', 'Very High']:
                            bonus_score += 0.20
                            bonus_reasons.append("Exercise needs match (+20%)")
                        elif exercise_needs == 'Low':
                            bonus_score -= 0.15
                            bonus_reasons.append("Insufficient exercise level (-15%)")
                    else:
                        if exercise_needs == 'Moderate':
                            bonus_score += 0.10
                            bonus_reasons.append("Moderate exercise needs (+10%)")

                    # 3. 美容需求評估
                    grooming = breed_info.get('Grooming_Needs', '')
                    if user_prefs.grooming_commitment == "high":
                        if grooming == 'High':
                            bonus_score += 0.10
                            bonus_reasons.append("High grooming match (+10%)")
                    else:
                        if grooming == 'High':
                            bonus_score -= 0.15
                            bonus_reasons.append("High grooming needs (-15%)")
                        elif grooming == 'Low':
                            bonus_score += 0.10
                            bonus_reasons.append("Low grooming needs (+10%)")

                    # 4. 家庭適應性評估
                    if user_prefs.has_children:
                        if breed_info.get('Good_With_Children'):
                            bonus_score += 0.15
                            bonus_reasons.append("Excellent with children (+15%)")
                        temperament = breed_info.get('Temperament', '').lower()
                        if any(trait in temperament for trait in ['gentle', 'patient', 'friendly']):
                            bonus_score += 0.05
                            bonus_reasons.append("Family-friendly temperament (+5%)")

                    # 5. 噪音評估
                    if user_prefs.noise_tolerance == "low":
                        noise_level = breed_noise_info.get(breed_name, {}).get('noise_level', 'Unknown')
                        if noise_level == 'High':
                            bonus_score -= 0.10
                            bonus_reasons.append("High noise level (-10%)")
                        elif noise_level == 'Low':
                            bonus_score += 0.10
                            bonus_reasons.append("Low noise level (+10%)")

                    # 6. 健康考慮
                    if user_prefs.health_sensitivity == "high":
                        health_score = smart_rec.get('health_score', 0.5)
                        if health_score > 0.8:
                            bonus_score += 0.10
                            bonus_reasons.append("Excellent health score (+10%)")
                        elif health_score < 0.5:
                            bonus_score -= 0.10
                            bonus_reasons.append("Health concerns (-10%)")

                    # 7. 品種偏好獎勵
                    if is_preferred:
                        bonus_score += 0.15
                        bonus_reasons.append("Directly mentioned breed (+15%)")
                    elif similarity > 0.8:
                        bonus_score += 0.10
                        bonus_reasons.append("Very similar to preferred breed (+10%)")

                    # 計算最終分數
                    final_score = min(0.95, base_score + bonus_score)

                    space_score = _calculate_space_compatibility(
                        breed_info.get('Size', 'Medium'),
                        user_prefs.living_space
                    )

                    exercise_score = _calculate_exercise_compatibility(
                        breed_info.get('Exercise_Needs', 'Moderate'),
                        user_prefs.exercise_time
                    )

                    grooming_score = _calculate_grooming_compatibility(
                        breed_info.get('Grooming_Needs', 'Moderate'),
                        user_prefs.grooming_commitment
                    )

                    experience_score = _calculate_experience_compatibility(
                        breed_info.get('Care_Level', 'Moderate'),
                        user_prefs.experience_level
                    )

                    scores = {
                        'overall': final_score,
                        'space': space_score,
                        'exercise': exercise_score,
                        'grooming': grooming_score,
                        'experience': experience_score,
                        'noise': smart_rec.get('scores', {}).get('noise', 0.0),
                        'health': smart_rec.get('health_score', 0.5),
                        'temperament': smart_rec.get('scores', {}).get('temperament', 0.0)
                    }


                    final_recommendations.append({
                        'rank': 0,
                        'breed': breed_name,
                        'scores': scores,
                        'base_score': round(base_score, 4),
                        'bonus_score': round(bonus_score, 4),
                        'final_score': round(final_score, 4),
                        'match_reason': ' • '.join(bonus_reasons) if bonus_reasons else "Standard match",
                        'info': breed_info,
                        'noise_info': breed_noise_info.get(breed_name, {}),
                        'health_info': breed_health_info.get(breed_name, {})
                    })

                # 根據最終分數排序
                final_recommendations.sort(key=lambda x: (-x['final_score'], x['breed']))

                # 更新排名
                for i, rec in enumerate(final_recommendations, 1):
                    rec['rank'] = i

                # 保存到歷史記錄
                history_results = [{
                    'breed': rec['breed'],
                    'rank': rec['rank'],
                    'final_score': rec['final_score']
                } for rec in final_recommendations[:10]]

                history_component.save_search(
                    user_preferences=None,
                    results=history_results,
                    search_type="description",
                    description=description
                )

                result = format_recommendation_html(final_recommendations, is_description_search=True)
                return [gr.update(value=result), gr.update(visible=False)]

            except Exception as e:
                error_msg = f"Error processing your description. Details: {str(e)}"
                return [gr.update(value=error_msg), gr.update(visible=False)]


        def _calculate_space_compatibility(size: str, living_space: str) -> float:
            """住宿空間適應性評分"""
            if living_space == "apartment":
                scores = {
                    'Tiny': 0.6,         # 公寓可以,但不是最佳
                    'Small': 0.8,        # 公寓較好
                    'Medium': 1.0,       # 最佳選擇
                    'Medium-Large': 0.6, # 可能有點大
                    'Large': 0.4,        # 太大了
                    'Giant': 0.2        # 不建議
                }
            else:  # house
                scores = {
                    'Tiny': 0.4,         # 房子太大了
                    'Small': 0.6,        # 可以但不是最佳
                    'Medium': 0.8,       # 不錯的選擇
                    'Medium-Large': 1.0, # 最佳選擇
                    'Large': 0.9,        # 也很好
                    'Giant': 0.7         # 可以考慮
                }
            return scores.get(size, 0.5)

        def _calculate_exercise_compatibility(exercise_needs: str, exercise_time: int) -> float:
            """運動需求相容性評分"""
            # 轉換運動時間到評分標準
            if exercise_time >= 120:  # 高運動量
                scores = {
                    'Very High': 1.0,
                    'High': 0.8,
                    'Moderate': 0.5,
                    'Low': 0.2
                }
            elif exercise_time >= 60:  # 中等運動量
                scores = {
                    'Very High': 0.5,
                    'High': 0.7,
                    'Moderate': 1.0,
                    'Low': 0.8
                }
            else:  # 低運動量
                scores = {
                    'Very High': 0.2,
                    'High': 0.4,
                    'Moderate': 0.7,
                    'Low': 1.0
                }
            return scores.get(exercise_needs, 0.5)

        def _calculate_grooming_compatibility(grooming_needs: str, grooming_commitment: str) -> float:
            """美容需求相容性評分"""
            if grooming_commitment == "high":
                scores = {
                    'High': 1.0,
                    'Moderate': 0.8,
                    'Low': 0.5
                }
            elif grooming_commitment == "medium":
                scores = {
                    'High': 0.6,
                    'Moderate': 1.0,
                    'Low': 0.8
                }
            else:  # low
                scores = {
                    'High': 0.3,
                    'Moderate': 0.6,
                    'Low': 1.0
                }
            return scores.get(grooming_needs, 0.5)

        def _calculate_experience_compatibility(care_level: str, experience_level: str) -> float:
            if experience_level == "experienced":
                care_scores = {
                    'High': 1.0,
                    'Moderate': 0.8,
                    'Low': 0.6
                }
            elif experience_level == "intermediate":
                care_scores = {
                    'High': 0.6,
                    'Moderate': 1.0,
                    'Low': 0.8
                }
            else:  # beginner
                care_scores = {
                    'High': 0.3,
                    'Moderate': 0.7,
                    'Low': 1.0
                }
            return care_scores.get(care_level, 0.7)

        def show_loading():
            return [gr.update(value=""), gr.update(visible=True)]


        get_recommendations_btn.click(
            fn=on_find_match_click,
            inputs=[
                living_space,
                exercise_time,
                grooming_commitment,
                experience_level,
                has_children,
                noise_tolerance
            ],
            outputs=recommendation_output
        )

        description_search_btn.click(
            fn=show_loading,  # 先顯示加載消息
            outputs=[description_output, loading_msg]
        ).then(  # 然後執行搜索
            fn=on_description_search,
            inputs=[description_input],
            outputs=[description_output, loading_msg]
        )

    return {
        'living_space': living_space,
        'exercise_time': exercise_time,
        'grooming_commitment': grooming_commitment,
        'experience_level': experience_level,
        'has_children': has_children,
        'noise_tolerance': noise_tolerance,
        'get_recommendations_btn': get_recommendations_btn,
        'recommendation_output': recommendation_output,
        'description_input': description_input,
        'description_search_btn': description_search_btn,
        'description_output': description_output
    }