import streamlit as st
import requests
import os
import html
import json

API_URL = os.getenv("PUBLIC_API_URL", "https://nec.clients.septem.pro") + "/llm"
NO_INFO_TEXT = "Информация отсутствует"
IMAGE_EXTS = ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'tiff', 'webp']

@st.cache_data
def load_layout():
    path = os.path.join(os.path.dirname(__file__), "criteria_interface_layout.json")
    if not os.path.exists(path):
        return {}
    with open(path, "r", encoding="utf-8") as f:
        return json.load(f).get("by_shipping_type", {})

LAYOUT = load_layout()

if 'session_id' not in st.session_state:
    st.session_state.session_id = None
if 'current_report' not in st.session_state:
    st.session_state.current_report = None
if 'report_loaded' not in st.session_state:
    st.session_state.report_loaded = False
if 'ui_theme' not in st.session_state:
    st.session_state.ui_theme = "light"

THEME_CONFIG = {
    "light": {
        "app_bg": "#f5f7fb", "card_bg": "#ffffff", "text": "#111827",
        "muted": "#6b7280", "border": "#d0d7de", "code_bg": "#f6f8fa",
        "hover": "#e9ecef", "shadow": "0 2px 4px rgba(0,0,0,0.05)"
    },
    "dark": {
        "app_bg": "#0f172a", "card_bg": "#111827", "text": "#e5e7eb",
        "muted": "#94a3b8", "border": "#334155", "code_bg": "#1f2937",
        "hover": "#374151", "shadow": "0 2px 8px rgba(0,0,0,0.45)"
    },
}

def apply_ui_theme():
    colors = THEME_CONFIG[st.session_state.ui_theme]
    st.markdown(f"""
    <style>
    :root {{
        --septem-app-bg: {colors["app_bg"]};
        --septem-card-bg: {colors["card_bg"]};
        --septem-text: {colors["text"]};
        --septem-muted: {colors["muted"]};
        --septem-border: {colors["border"]};
        --septem-code-bg: {colors["code_bg"]};
        --septem-hover: {colors["hover"]};
        --septem-shadow: {colors["shadow"]};
    }}
    div[data-testid="stAppViewContainer"] {{ background: var(--septem-app-bg); }}
    div[data-testid="stSidebar"] {{ background: var(--septem-card-bg); }}
    </style>""", unsafe_allow_html=True)

def load_report(session_id: str):
    try:
        resp = requests.post(f"{API_URL}/generate-cargo-report", json={"session_id": session_id})
        if resp.status_code == 200:
            st.session_state.current_report = resp.json()
        else:
            st.error(f"Ошибка загрузки отчёта: {resp.status_code}")
    except Exception as e:
        st.error(f"Не удалось соединиться с сервером: {e}")

def criterion_card_html(number, criterion, value):
    if value is None:
        display = NO_INFO_TEXT
    elif isinstance(value, bool):
        display = "✅ Да" if value else "❌ Нет"
    else:
        display = str(value)
    return f"""
    <div style='border:1px solid var(--septem-border); border-radius:8px; padding:8px 12px;
                margin-bottom:8px; background:var(--septem-card-bg); box-sizing:border-box;'>
        <b>{html.escape(str(number))}. {html.escape(criterion)}</b><br>
        <span style='color:var(--septem-muted);'>Ответ:</span> {html.escape(display)}
    </div>"""

def display_criteria_with_layout(report):
    criteria_results = report.get("criteria_results", [])
    if not criteria_results:
        st.info("Нет данных по критериям")
        return

    # Индексируем по номеру
    by_num = {item["number"]: item for item in criteria_results if "number" in item}

    shipping_type = report.get("shipping_type", "")
    layout_blocks = LAYOUT.get(shipping_type, {}).get("blocks", [])

    shown_numbers = set()

    # Рисуем блоки из layout
    for block in layout_blocks:
        if block["type"] == "pair":
            left = block["left"]
            right = block["right"]
            num_l = int(left["num"])
            num_r = int(right["num"])
            crit_l = by_num.get(num_l)
            crit_r = by_num.get(num_r)
            if crit_l and crit_r:
                left_card = criterion_card_html(num_l, crit_l["criterion"], crit_l["value"])
                right_card = criterion_card_html(num_r, crit_r["criterion"], crit_r["value"])
                st.markdown(
                    f'<div style="display:flex; gap:8px; margin-bottom:8px;">{left_card}{right_card}</div>',
                    unsafe_allow_html=True
                )
                shown_numbers.add(num_l)
                shown_numbers.add(num_r)
        elif block["type"] == "left_12":
            num = int(block["num"])
            crit = by_num.get(num)
            if crit:
                st.markdown(criterion_card_html(num, crit["criterion"], crit["value"]), unsafe_allow_html=True)
                shown_numbers.add(num)

    # Оставшиеся критерии, не попавшие в layout
    remaining = [item for item in criteria_results if item["number"] not in shown_numbers]
    if remaining:
        st.markdown("---")
        for item in remaining:
            st.markdown(criterion_card_html(item["number"], item["criterion"], item["value"]), unsafe_allow_html=True)

def display_all_attachments(report):
    sources = report.get('sources', [])
    if not sources:
        st.info("Нет писем с вложениями")
        return
    all_att = []
    for email_idx, source in enumerate(sources):
        for att_idx, att in enumerate(source.get('attachments', [])):
            ext = att['filename'].split('.')[-1].lower() if '.' in att['filename'] else ''
            if ext in IMAGE_EXTS:
                continue
            all_att.append({
                'email_idx': email_idx,
                'att_idx': att_idx,
                'filename': att['filename'],
                'subject': source.get('subject', ''),
                'size': att.get('size', 0),
            })
    if not all_att:
        st.info("Нет доступных вложений (изображения скрыты)")
        return
    for att in all_att:
        cols = st.columns([3,1,1])
        cols[0].markdown(f"**📄 {att['filename']}**")
        cols[0].caption(f"Из письма: {att['subject']}")
        url = f"{API_URL}/attachments/{st.session_state.session_id}/{att['email_idx']}/{att['att_idx']}"
        cols[1].link_button("👁️ Открыть", url)
        cols[2].link_button("📥 Скачать", url)

def main():
    st.set_page_config(page_title="SEPTEM Cargo Analytics", page_icon="🚚", layout="wide")
    col1, col2 = st.columns([8, 2])
    with col1:
        st.title("🚚 SEPTEM Cargo Analytics")
    with col2:
        theme_label = st.selectbox("Тема", ["Светлая", "Тёмная"],
                                   index=0 if st.session_state.ui_theme == "light" else 1)
        new_theme = "light" if theme_label == "Светлая" else "dark"
        if new_theme != st.session_state.ui_theme:
            st.session_state.ui_theme = new_theme
            st.rerun()
    apply_ui_theme()

    query_params = st.query_params
    session_id = query_params.get("session_id", [None])
    if isinstance(session_id, list):
        session_id = session_id[0] if session_id else None

    if session_id and not st.session_state.report_loaded:
        st.session_state.session_id = session_id
        with st.spinner("Анализируем письма..."):
            load_report(session_id)
        st.session_state.report_loaded = True

    with st.sidebar:
        st.header("📋 Сессия")
        if st.session_state.session_id:
            st.success(f"ID: {st.session_state.session_id[:8]}...")
            if st.button("🔄 Обновить отчёт"):
                load_report(st.session_state.session_id)
                st.rerun()
        else:
            st.info("Нет активной сессии")
        if st.session_state.current_report:
            report = st.session_state.current_report
            st.metric("Писем", report.get('emails_count', 0))

    if st.session_state.current_report:
        display_report(st.session_state.current_report)
    else:
        st.info("Отправьте письма через Outlook и нажмите «Анализировать», чтобы увидеть результат.")

def display_report(report):
    tab1, tab2 = st.tabs(["📦 Обзор", "📎 Вложения"])
    with tab1:
        st.subheader(f"Перевозка: {report.get('shipping_type', 'Не определён')}")
        display_criteria_with_layout(report)
        st.info("✉️ Генерация писем будет добавлена в следующей версии.")
    with tab2:
        display_all_attachments(report)

if __name__ == "__main__":
    main()
