import sqlite3
import traceback
from typing import List, Dict
from breed_health_info import breed_health_info, default_health_note
from breed_noise_info import breed_noise_info
from dog_database import get_dog_description
from scoring_calculation_system import  UserPreferences, calculate_compatibility_score

def format_recommendation_html(recommendations: List[Dict], is_description_search: bool = False) -> str:
    """將推薦結果格式化為HTML"""
    def _convert_to_display_score(score: float, score_type: str = None) -> int:
        """
        更改為生成更明顯差異的顯示分數
        """
        try:
            # 基礎分數轉換(保持相對關係但擴大差異)
            if score_type == 'bonus':  # Breed Bonus 使用不同的轉換邏輯
                base_score = 35 + (score * 60)  # 35-95 範圍,差異更大
            else:
                # 其他類型的分數轉換
                if score <= 0.3:
                    base_score = 40 + (score * 45)  # 40-53.5 範圍
                elif score <= 0.6:
                    base_score = 55 + ((score - 0.3) * 55)  # 55-71.5 範圍
                elif score <= 0.8:
                    base_score = 72 + ((score - 0.6) * 60)  # 72-84 範圍
                else:
                    base_score = 85 + ((score - 0.8) * 50)  # 85-95 範圍

            # 添加不規則的微調,但保持相對關係
            import random
            if score_type == 'bonus':
                adjustment = random.uniform(-2, 2)
            else:
                # 根據分數範圍決定調整幅度
                if score > 0.8:
                    adjustment = random.uniform(-3, 3)
                elif score > 0.6:
                    adjustment = random.uniform(-4, 4)
                else:
                    adjustment = random.uniform(-2, 2)

            final_score = base_score + adjustment

            # 確保最終分數在合理範圍內並避免5的倍數
            final_score = min(95, max(40, final_score))
            rounded_score = round(final_score)
            if rounded_score % 5 == 0:
                rounded_score += random.choice([-1, 1])

            return rounded_score

        except Exception as e:
            print(f"Error in convert_to_display_score: {str(e)}")
            return 70


    def _generate_progress_bar(score: float) -> float:
        """       
        - 確保100%時完全填滿
        - 更線性的視覺呈現
        - 保持合理的視覺比例
        """
        # 基礎寬度計算
        if score >= 1.0:
            return 100.0  # 確保100%時完全填滿
        
        # 一般情況的寬度計算
        if score > 0.9:
            # 高分區間線性延伸
            width = 90 + (score - 0.9) * 100
        elif score > 0.7:
            # 中高分區間稍微展開
            width = 70 + (score - 0.7) * 100
        else:
            # 基礎線性關係
            width = score * 100
        
        # 加入微小的隨機變化,使顯示更自然
        import random
        width += random.uniform(-0.5, 0.5)
        
        # 確保範圍合理
        return min(99.5, max(20, width)) if score < 1.0 else 100.0

    html_content = "<div class='recommendations-container'>"

    for rec in recommendations:
        breed = rec['breed']
        scores = rec['scores']
        info = rec['info']
        rank = rec.get('rank', 0)
        final_score = rec.get('final_score', scores['overall'])
        bonus_score = rec.get('bonus_score', 0)

        if is_description_search:
            display_scores = {
                'space': _convert_to_display_score(scores['space'], 'space'),
                'exercise': _convert_to_display_score(scores['exercise'], 'exercise'),
                'grooming': _convert_to_display_score(scores['grooming'], 'grooming'),
                'experience': _convert_to_display_score(scores['experience'], 'experience'),
                'noise': _convert_to_display_score(scores['noise'], 'noise')
            }
        else:
            display_scores = scores  # 圖片識別使用原始分數

        progress_bars = {
            'space': _generate_progress_bar(scores['space']),
            'exercise': _generate_progress_bar(scores['exercise']),
            'grooming': _generate_progress_bar(scores['grooming']),
            'experience': _generate_progress_bar(scores['experience']),
            'noise': _generate_progress_bar(scores['noise'])
        }

        health_info = breed_health_info.get(breed, {"health_notes": default_health_note})
        noise_info = breed_noise_info.get(breed, {
            "noise_notes": "Noise information not available",
            "noise_level": "Unknown",
            "source": "N/A"
        })

        # 解析噪音資訊
        noise_notes = noise_info.get('noise_notes', '').split('\n')
        noise_characteristics = []
        barking_triggers = []
        noise_level = ''

        current_section = None
        for line in noise_notes:
            line = line.strip()
            if 'Typical noise characteristics:' in line:
                current_section = 'characteristics'
            elif 'Noise level:' in line:
                noise_level = line.replace('Noise level:', '').strip()
            elif 'Barking triggers:' in line:
                current_section = 'triggers'
            elif line.startswith('•'):
                if current_section == 'characteristics':
                    noise_characteristics.append(line[1:].strip())
                elif current_section == 'triggers':
                    barking_triggers.append(line[1:].strip())

        # 生成特徵和觸發因素的HTML
        noise_characteristics_html = '\n'.join([f'<li>{item}</li>' for item in noise_characteristics])
        barking_triggers_html = '\n'.join([f'<li>{item}</li>' for item in barking_triggers])

        # 處理健康資訊
        health_notes = health_info.get('health_notes', '').split('\n')
        health_considerations = []
        health_screenings = []

        current_section = None
        for line in health_notes:
            line = line.strip()
            if 'Common breed-specific health considerations' in line:
                current_section = 'considerations'
            elif 'Recommended health screenings:' in line:
                current_section = 'screenings'
            elif line.startswith('•'):
                if current_section == 'considerations':
                    health_considerations.append(line[1:].strip())
                elif current_section == 'screenings':
                    health_screenings.append(line[1:].strip())

        health_considerations_html = '\n'.join([f'<li>{item}</li>' for item in health_considerations])
        health_screenings_html = '\n'.join([f'<li>{item}</li>' for item in health_screenings])

        # 獎勵原因計算
        bonus_reasons = []
        temperament = info.get('Temperament', '').lower()
        if any(trait in temperament for trait in ['friendly', 'gentle', 'affectionate']):
            bonus_reasons.append("Positive temperament traits")
        if info.get('Good with Children') == 'Yes':
            bonus_reasons.append("Excellent with children")
        try:
            lifespan = info.get('Lifespan', '10-12 years')
            years = int(lifespan.split('-')[0])
            if years >= 12:
                bonus_reasons.append("Above-average lifespan")
        except:
            pass

        html_content += f"""
        <div class="dog-info-card recommendation-card">
            <div class="breed-info">
                <h2 class="section-title">
                    <span class="icon">🏆</span> #{rank} {breed.replace('_', ' ')}
                    <span class="score-badge">
                        Overall Match: {final_score*100:.1f}%
                    </span>
                </h2>
                <div class="compatibility-scores">
                    <div class="score-item">
                        <span class="label">Space Compatibility:</span>
                        <div class="progress-bar">
                            <div class="progress" style="width: {progress_bars['space']}%"></div>
                        </div>
                        <span class="percentage">{display_scores['space'] if is_description_search else scores['space']*100:.1f}%</span>
                    </div>
                    <div class="score-item">
                        <span class="label">Exercise Match:</span>
                        <div class="progress-bar">
                            <div class="progress" style="width: {progress_bars['exercise']}%"></div>
                        </div>
                        <span class="percentage">{display_scores['exercise'] if is_description_search else scores['exercise']*100:.1f}%</span>
                    </div>
                    <div class="score-item">
                        <span class="label">Grooming Match:</span>
                        <div class="progress-bar">
                            <div class="progress" style="width: {progress_bars['grooming']}%"></div>
                        </div>
                        <span class="percentage">{display_scores['grooming'] if is_description_search else scores['grooming']*100:.1f}%</span>
                    </div>
                    <div class="score-item">
                        <span class="label">Experience Match:</span>
                        <div class="progress-bar">
                            <div class="progress" style="width: {progress_bars['experience']}%"></div>
                        </div>
                        <span class="percentage">{display_scores['experience'] if is_description_search else scores['experience']*100:.1f}%</span>
                    </div>
                    <div class="score-item">
                        <span class="label">
                            Noise Compatibility:
                            <span class="tooltip">
                                <span class="tooltip-icon">ⓘ</span>
                                <span class="tooltip-text">
                                    <strong>Noise Compatibility Score:</strong><br>
                                    • Based on your noise tolerance preference<br>
                                    • Considers breed's typical noise level<br>
                                    • Accounts for living environment
                                </span>
                            </span>
                        </span>
                        <div class="progress-bar">
                            <div class="progress" style="width: {progress_bars['noise']}%"></div>
                        </div>
                        <span class="percentage">{display_scores['noise'] if is_description_search else scores['noise']*100:.1f}%</span>
                    </div>
                    {f'''
                    <div class="score-item bonus-score">
                        <span class="label">
                            Breed Bonus:
                            <span class="tooltip">
                                <span class="tooltip-icon">ⓘ</span>
                                <span class="tooltip-text">
                                    <strong>Breed Bonus Points:</strong><br>
                                    • {('<br>• '.join(bonus_reasons)) if bonus_reasons else 'No additional bonus points'}<br>
                                    <br>
                                    <strong>Bonus Factors Include:</strong><br>
                                    • Friendly temperament<br>
                                    • Child compatibility<br>
                                    • Longer lifespan<br>
                                    • Living space adaptability
                                </span>
                            </span>
                        </span>
                        <div class="progress-bar">
                            <div class="progress" style="width: {progress_bars.get('bonus', bonus_score*100)}%"></div>
                        </div>
                        <span class="percentage">{bonus_score*100:.1f}%</span>
                    </div>
                    ''' if bonus_score > 0 else ''}
                </div>
                <div class="breed-details-section">
                    <h3 class="subsection-title">
                        <span class="icon">📋</span> Breed Details
                    </h3>
                    <div class="details-grid">
                        <div class="detail-item">
                            <span class="tooltip">
                                <span class="icon">📏</span>
                                <span class="label">Size:</span>
                                <span class="tooltip-icon">ⓘ</span>
                                <span class="tooltip-text">
                                    <strong>Size Categories:</strong><br>
                                    • Small: Under 20 pounds<br>
                                    • Medium: 20-60 pounds<br>
                                    • Large: Over 60 pounds
                                </span>
                                <span class="value">{info['Size']}</span>
                            </span>
                        </div>
                        <div class="detail-item">
                            <span class="tooltip">
                                <span class="icon">🏃</span>
                                <span class="label">Exercise Needs:</span>
                                <span class="tooltip-icon">ⓘ</span>
                                <span class="tooltip-text">
                                    <strong>Exercise Needs:</strong><br>
                                    • Low: Short walks<br>
                                    • Moderate: 1-2 hours daily<br>
                                    • High: 2+ hours daily<br>
                                    • Very High: Constant activity
                                </span>
                                <span class="value">{info['Exercise Needs']}</span>
                            </span>
                        </div>
                        <div class="detail-item">
                            <span class="tooltip">
                                <span class="icon">👨‍👩‍👧‍👦</span>
                                <span class="label">Good with Children:</span>
                                <span class="tooltip-icon">ⓘ</span>
                                <span class="tooltip-text">
                                    <strong>Child Compatibility:</strong><br>
                                    • Yes: Excellent with kids<br>
                                    • Moderate: Good with older children<br>
                                    • No: Better for adult households
                                </span>
                                <span class="value">{info['Good with Children']}</span>
                            </span>
                        </div>
                        <div class="detail-item">
                            <span class="tooltip">
                                <span class="icon">⏳</span>
                                <span class="label">Lifespan:</span>
                                <span class="tooltip-icon">ⓘ</span>
                                <span class="tooltip-text">
                                    <strong>Average Lifespan:</strong><br>
                                    • Short: 6-8 years<br>
                                    • Average: 10-15 years<br>
                                    • Long: 12-20 years<br>
                                    • Varies by size: Larger breeds typically have shorter lifespans
                                </span>
                            </span>
                            <span class="value">{info['Lifespan']}</span>
                        </div>
                    </div>
                </div>
                <div class="description-section">
                    <h3 class="subsection-title">
                        <span class="icon">📝</span> Description
                    </h3>
                    <p class="description-text">{info.get('Description', '')}</p>
                </div>
                <div class="noise-section">
                    <h3 class="section-header">
                        <span class="icon">🔊</span> Noise Behavior
                        <span class="tooltip">
                            <span class="tooltip-icon">ⓘ</span>
                            <span class="tooltip-text">
                                <strong>Noise Behavior:</strong><br>
                                • Typical vocalization patterns<br>
                                • Common triggers and frequency<br>
                                • Based on breed characteristics
                            </span>
                        </span>
                    </h3>
                    <div class="noise-info">
                        <div class="noise-details">
                            <h4 class="section-header">Typical noise characteristics:</h4>
                            <div class="characteristics-list">
                                <div class="list-item">Moderate to high barker</div>
                                <div class="list-item">Alert watch dog</div>
                                <div class="list-item">Attention-seeking barks</div>
                                <div class="list-item">Social vocalizations</div>
                            </div>

                            <div class="noise-level-display">
                                <h4 class="section-header">Noise level:</h4>
                                <div class="level-indicator">
                                    <span class="level-text">Moderate-High</span>
                                    <div class="level-bars">
                                        <span class="bar"></span>
                                        <span class="bar"></span>
                                        <span class="bar"></span>
                                    </div>
                                </div>
                            </div>

                            <h4 class="section-header">Barking triggers:</h4>
                            <div class="triggers-list">
                                <div class="list-item">Separation anxiety</div>
                                <div class="list-item">Attention needs</div>
                                <div class="list-item">Strange noises</div>
                                <div class="list-item">Excitement</div>
                            </div>
                        </div>
                        <div class="noise-disclaimer">
                            <p class="disclaimer-text source-text">Source: Compiled from various breed behavior resources, 2024</p>
                            <p class="disclaimer-text">Individual dogs may vary in their vocalization patterns.</p>
                            <p class="disclaimer-text">Training can significantly influence barking behavior.</p>
                            <p class="disclaimer-text">Environmental factors may affect noise levels.</p>
                        </div>
                    </div>
                </div>

                <div class="health-section">
                    <h3 class="section-header">
                        <span class="icon">🏥</span> Health Insights
                        <span class="tooltip">
                            <span class="tooltip-icon">ⓘ</span>
                            <span class="tooltip-text">
                                Health information is compiled from multiple sources including veterinary resources, breed guides, and international canine health databases.
                                Each dog is unique and may vary from these general guidelines.
                            </span>
                        </span>
                    </h3>
                    <div class="health-info">
                        <div class="health-details">
                            <div class="health-block">
                                <h4 class="section-header">Common breed-specific health considerations:</h4>
                                <div class="health-grid">
                                    <div class="health-item">Patellar luxation</div>
                                    <div class="health-item">Progressive retinal atrophy</div>
                                    <div class="health-item">Von Willebrand's disease</div>
                                    <div class="health-item">Open fontanel</div>
                                </div>
                            </div>

                            <div class="health-block">
                                <h4 class="section-header">Recommended health screenings:</h4>
                                <div class="health-grid">
                                    <div class="health-item screening">Patella evaluation</div>
                                    <div class="health-item screening">Eye examination</div>
                                    <div class="health-item screening">Blood clotting tests</div>
                                    <div class="health-item screening">Skull development monitoring</div>
                                </div>
                            </div>
                        </div>
                        <div class="health-disclaimer">
                            <p class="disclaimer-text source-text">Source: Compiled from various veterinary and breed information resources, 2024</p>
                            <p class="disclaimer-text">This information is for reference only and based on breed tendencies.</p>
                            <p class="disclaimer-text">Each dog is unique and may not develop any or all of these conditions.</p>
                            <p class="disclaimer-text">Always consult with qualified veterinarians for professional advice.</p>
                        </div>
                    </div>
                </div>

                <div class="action-section">
                    <a href="https://www.akc.org/dog-breeds/{breed.lower().replace('_', '-')}/"
                       target="_blank"
                       class="akc-button">
                        <span class="icon">🌐</span>
                        Learn more about {breed.replace('_', ' ')} on AKC website
                    </a>
                </div>
            </div>
        </div>
        """

    html_content += "</div>"
    return html_content

def get_breed_recommendations(user_prefs: UserPreferences, top_n: int = 10) -> List[Dict]:
    """基於使用者偏好推薦狗品種,確保正確的分數排序"""
    print("Starting get_breed_recommendations")
    recommendations = []
    seen_breeds = set()

    try:
        # 獲取所有品種
        conn = sqlite3.connect('animal_detector.db')
        cursor = conn.cursor()
        cursor.execute("SELECT Breed FROM AnimalCatalog")
        all_breeds = cursor.fetchall()
        conn.close()

        # 收集所有品種的分數
        for breed_tuple in all_breeds:
            breed = breed_tuple[0]
            base_breed = breed.split('(')[0].strip()

            if base_breed in seen_breeds:
                continue
            seen_breeds.add(base_breed)

            # 獲取品種資訊
            breed_info = get_dog_description(breed)
            if not isinstance(breed_info, dict):
                continue

            # 獲取噪音資訊
            noise_info = breed_noise_info.get(breed, {
                "noise_notes": "Noise information not available",
                "noise_level": "Unknown",
                "source": "N/A"
            })

            # 將噪音資訊整合到品種資訊中
            breed_info['noise_info'] = noise_info

            # 計算基礎相容性分數
            compatibility_scores = calculate_compatibility_score(breed_info, user_prefs)

            # 計算品種特定加分
            breed_bonus = 0.0

            # 壽命加分
            try:
                lifespan = breed_info.get('Lifespan', '10-12 years')
                years = [int(x) for x in lifespan.split('-')[0].split()[0:1]]
                longevity_bonus = min(0.02, (max(years) - 10) * 0.005)
                breed_bonus += longevity_bonus
            except:
                pass

            # 性格特徵加分
            temperament = breed_info.get('Temperament', '').lower()
            positive_traits = ['friendly', 'gentle', 'affectionate', 'intelligent']
            negative_traits = ['aggressive', 'stubborn', 'dominant']

            breed_bonus += sum(0.01 for trait in positive_traits if trait in temperament)
            breed_bonus -= sum(0.01 for trait in negative_traits if trait in temperament)

            # 與孩童相容性加分
            if user_prefs.has_children:
                if breed_info.get('Good with Children') == 'Yes':
                    breed_bonus += 0.02
                elif breed_info.get('Good with Children') == 'No':
                    breed_bonus -= 0.03

            # 噪音相關加分
            if user_prefs.noise_tolerance == 'low':
                if noise_info['noise_level'].lower() == 'high':
                    breed_bonus -= 0.03
                elif noise_info['noise_level'].lower() == 'low':
                    breed_bonus += 0.02
            elif user_prefs.noise_tolerance == 'high':
                if noise_info['noise_level'].lower() == 'high':
                    breed_bonus += 0.01

            # 計算最終分數
            breed_bonus = round(breed_bonus, 4)
            final_score = round(compatibility_scores['overall'] + breed_bonus, 4)

            recommendations.append({
                'breed': breed,
                'base_score': round(compatibility_scores['overall'], 4),
                'bonus_score': round(breed_bonus, 4),
                'final_score': final_score,
                'scores': compatibility_scores,
                'info': breed_info,
                'noise_info': noise_info  # 添加噪音資訊到推薦結果
            })
        # 嚴格按照 final_score 排序
        recommendations.sort(key=lambda x: (round(-x['final_score'], 4), x['breed'] ))  # 負號使其降序排列,並確保4位小數

        # 選擇前N名並確保正確排序
        final_recommendations = []
        last_score = None
        rank = 1

        for rec in recommendations:
            if len(final_recommendations) >= top_n:
                break

            current_score = rec['final_score']

            # 確保分數遞減
            if last_score is not None and current_score > last_score:
                continue

            # 添加排名資訊
            rec['rank'] = rank
            final_recommendations.append(rec)

            last_score = current_score
            rank += 1

        # 驗證最終排序
        for i in range(len(final_recommendations)-1):
            current = final_recommendations[i]
            next_rec = final_recommendations[i+1]

            if current['final_score'] < next_rec['final_score']:
                print(f"Warning: Sorting error detected!")
                print(f"#{i+1} {current['breed']}: {current['final_score']}")
                print(f"#{i+2} {next_rec['breed']}: {next_rec['final_score']}")

                # 交換位置
                final_recommendations[i], final_recommendations[i+1] = \
                    final_recommendations[i+1], final_recommendations[i]

        # 打印最終結果以供驗證
        print("\nFinal Rankings:")
        for rec in final_recommendations:
            print(f"#{rec['rank']} {rec['breed']}")
            print(f"Base Score: {rec['base_score']:.4f}")
            print(f"Bonus: {rec['bonus_score']:.4f}")
            print(f"Final Score: {rec['final_score']:.4f}\n")

        return final_recommendations

    except Exception as e:
        print(f"Error in get_breed_recommendations: {str(e)}")
        print(f"Traceback: {traceback.format_exc()}")
        return []