import pyperclip

SNIPPETS = {
    1: """#### Задание:
* Обучение модели - выборку проверить на дисбаланс, если необходимо устранить. Рассмотреть не менее 3 моделей классификации. Обучить выбранную модель, оценить ее качество.
* Организовать непрерывное обучение 
* Расссмотреть не менее 3 моделей регрессии, выбрать модель

#### Результат модуля:
* Выбрана модель классификации
* 
* Аналитическая записка с данными, графиками, выводами
""",
    2: """labels = cluster.labels_
cluster_sizes = np.bincount(labels)
print("Размеры кластеров:", cluster_sizes)
""",
    3: """from sklearn.metrics import  davies_bouldin_score
dbi = davies_bouldin_score(X_scaled, labels)
print("Индекс Дэвиса-Болдина:", dbi)""",
    4: """df["Cluster"].value_counts()""",
    5: """indices_to_drop = df[df['Cluster'] == 0].index[:10]
df = df.drop(indices_to_drop)""",
    6: """from sklearn.metrics import accuracy_score, mean_absolute_error, mean_squared_error, precision_score, recall_score, f1_score, confusion_matrix, r2_score
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix

from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC
from sklearn.ensemble import RandomForestClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split""",
    7: """X = df.drop(['Cluster','datetime','data','region'], axis=1)
y = df['Cluster']""",
    8: """X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=42)""",
    9: """knn = KNeighborsClassifier()
knn.fit(X_train, y_train)""",
    10: """import joblib
knn_clf = KNeighborsClassifier().fit(X_train, y_train)
joblib.dump(knn_clf, 'classifier_model.pkl')  

""",
    11: """knn_predict = knn.predict(X_test)""",
    12: """knn_train_predict = knn.predict(X_train)
print('train accuracy: ', accuracy_score(y_train, knn_train_predict, normalize=True))
print('test accuracy: ', accuracy_score(y_test, knn_predict, normalize=True))""",
    13: """knn_accuracy = accuracy_score(y_test, knn_predict, normalize=True)""",
    14: """print(classification_report(y_test, knn_predict))""",
    15: """cm = confusion_matrix(y_test, knn_predict)

sns.heatmap(cm, annot=True, fmt='d', cmap='Reds')
plt.title('Confusion Matrix')
plt.xlabel('Predicted Label')
plt.ylabel('True Label')
plt.show()""",
    16: """from matplotlib.pylab import rc, plot
from sklearn.metrics import roc_curve

sns.set(font_scale=1)
sns.set_color_codes("muted")

plt.figure(figsize=(6, 4))
fpr, tpr, thresholds = roc_curve(y_test, knn_predict, pos_label=1)
lw = 2
plt.plot(fpr, tpr, lw=lw, label='ROC curve ')
plt.plot([0, 1], [0, 1])
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('ROC curve')
plt.savefig("ROC.png")
plt.show()""",
    17: """gnb = GaussianNB()
gnb.fit(X_train, y_train)""",
    18: """svc = SVC()
svc.fit(X_train, y_train)""",
    19: """
metrics_k = ['KNN accurancy', 'SVC accurancy','GNB accuracy']
scores_k = [knn_accuracy, svc_accuracy,gnb_accuracy]

plt.figure(figsize=(10, 6))
plt.bar(metrics_k, scores_k, color=['blue', 'green'])
plt.ylabel('Scores')
plt.title('Comparison of Clustering Metrics')

for i, v in enumerate(scores_k):
    plt.text(i, v, f'{v:.4f}', ha='center', va='bottom')

plt.show()""",
    20: """import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler, LabelEncoder
from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
import warnings; warnings.filterwarnings('ignore')
""",
    21: """X = df.drop(['Cluster','datetime','data','region'], axis=1)
y = df['step_frequency']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

lr = LinearRegression()
lr.fit(X_train_scaled, y_train)
lr_pred = lr.predict(X_test_scaled)
rf = RandomForestRegressor(n_estimators=100, random_state=42)
rf.fit(X_train_scaled, y_train)
rf_pred = rf.predict(X_test_scaled)
gbr = GradientBoostingRegressor(n_estimators=100, random_state=42)
gbr.fit(X_train_scaled, y_train)
gbr_pred = gbr.predict(X_test_scaled)
""",
    22:"""def print_regression_report(y_true, y_pred, model_name):
    mae = mean_absolute_error(y_true, y_pred)
    rmse = np.sqrt(mean_squared_error(y_true, y_pred))
    r2 = r2_score(y_true, y_pred)
    print(f"{model_name}:\\n  MAE: {mae:.2f} шаг/мин | RMSE: {rmse:.2f} | R²: {r2:.3f}")

print_regression_report(y_test, lr_pred, "LinearRegression")
print_regression_report(y_test, rf_pred, "RandomForest")
print_regression_report(y_test, gbr_pred, "GradientBoosting")""",
    23:"""from fastapi import FastAPI, HTTPException
import pandas as pd
import joblib
import numpy as np
import warnings

warnings.filterwarnings("ignore")""",
    24:"""app = FastAPI()
df = pd.read_csv('tracks.csv')
model = joblib.load('classifier_model.pkl')
n_features = model.n_features_in_""",
    25:"""@app.get("/tracks")
def get_tracks():
    return {"track_ids": sorted(df['track_id'].astype(int).unique().tolist())}
""",
    26:"""@app.post("/predict/{track_id}")
def predict_track(track_id: int):
    track = df[df['track_id'] == track_id]
    if len(track) == 0:
        raise HTTPException(404, f"Track {track_id} not found")

    cols = ['track_id', 'point_id'""",
    27:"""   risks = []
    for _, point in track.iterrows():
        features = point[cols].fillna(0).values
        if len(features) < n_features:
            features = np.pad(features, (0, n_features - len(features)), 'constant')
        risk = model.predict(features.reshape(1, -1))[0]
        risks.append(int(risk))
""",
    28:"""  points_with_risk = track[['track_id', 'point_id', 'latitude', 'longitude',
                              'elevation', 'temp', 'speed', 'step_frequency']].copy()
    points_with_risk['risk'] = risks""",
    29:""" points_json = []
    for _, row in points_with_risk.iterrows():
        points_json.append({
            "track_id": int(row['track_id']),
            "point_id": int(row['point_id']),
            "latitude": float(row['latitude']),
            "longitude": float(row['longitude']),
            "elevation": float(row['elevation']),
            "temp": float(row['temp']),
            "speed": float(row['speed']),
            "step_frequency": float(row['step_frequency']),
            "risk": int(row['risk'])
        })""",
    30:""" return {
        "track_id": int(track_id),
        "total_points": int(len(points_json)),
        "points": points_json
    }""",
    31:"""import streamlit as st
import folium
import pandas as pd
import requests
import numpy as np
""",
    32:"""@st.cache_data(ttl=300)
def get_tracks():
    try:
        response = requests.get("http://127.0.0.1:8000/tracks")
        return response.json()["track_ids"]
    except:
        st.error("")
        return []""",
    33:"""track_ids = get_tracks()
selected_track = st.selectbox("Выбери трек:", track_ids)
""",
    34:"""if selected_track is not None and selected_track != "":
    @st.cache_data(ttl=300)
    def get_track_data(track_id):
        try:
            response = requests.post(f"http://127.0.0.1:8000/predict/{track_id}")
            return response.json()
        except:
            st.error("Ошибка API!")
            return None""",
    35:"""track_data = get_track_data(selected_track)

    if track_data and "points" in track_data:
        points = pd.DataFrame(track_data["points"])

        center_lat = points['latitude'].mean()
        center_lon = points['longitude'].mean()

        m = folium.Map(
            location=[center_lat, center_lon],
            zoom_start=14
        )""",
    36:"""avg_risk = points['risk'].mean()
        line_color = 'green' if avg_risk < 1 else 'orange' if avg_risk < 1.5 else 'red'

        folium.PolyLine(
            list(zip(points['latitude'], points['longitude'])),
            color=line_color,
            weight=4,
            opacity=0.8,
            popup=f"Трек {selected_track} (ср. риск: {avg_risk:.1f})"
        ).add_to(m)""",
    37:"""   for _, point in points.iterrows():
            color = 'green' if point['risk'] == 0 else 'orange' if point['risk'] == 1 else 'red'
            folium.CircleMarker(
                location=[point['latitude'], point['longitude']],
                radius=6,
                color=color,
                fill=True,
                fillColor=color,
                fillOpacity=0.7,
                popup=f"Точка {point['point_id']}<br>"
                      f"Риск: {point['risk']}<br>"
                      f"Высота: {point['elevation']:.0f}м<br>"
                      f"Скорость: {point['speed']:.1f}м/с"
            ).add_to(m)""",
    38:"""  legend_html = '''
        <div style="position: fixed; bottom: 50px; right: 50px; width: 220px; height: auto; 
        background-color: white; border:2px solid grey; z-index:9999; 
        font-size:14px; padding: 12px; border-radius: 5px; box-shadow: 0 0 10px rgba(0,0,0,0.2);">
        <p style="margin: 0 0 10px 0;"><b>Легенда рисков</b></p>
        <p style="margin: 8px 0;">
            <span style="color: green; font-size: 18px;">●</span> 
            Низкий риск (0)
        </p>
        <p style="margin: 8px 0;">
            <span style="color: orange; font-size: 18px;">●</span> 
            Средний риск (1)
        </p>
        <p style="margin: 8px 0;">
            <span style="color: red; font-size: 18px;">●</span> 
            Высокий риск (2)
        </p>
        <p style="margin: 5px 0; font-size: 11px; color: #666;">
            Линия: средний риск трека
        </p>
        </div>
        '''""",
    39:"""m.get_root().html.add_child(folium.Element(legend_html))


        st.components.v1.html(m._repr_html_(), height=600)


    else:
        st.error("Трек не найден!")
""",
    40:"""import streamlit as st
import folium
import pandas as pd
import requests
import numpy as np

st.title("Карта")


@st.cache_data(ttl=300)
def get_tracks():
    try:
        response = requests.get("http://127.0.0.1:8000/tracks")
        return response.json()["track_ids"]
    except:
        st.error(" API недоступен! Запусти: python -m uvicorn api:app --reload")
        return []


track_ids = get_tracks()
selected_track = st.selectbox("Выбери трек:", track_ids)

if selected_track is not None and selected_track != "":
    @st.cache_data(ttl=300)
    def get_track_data(track_id):
        try:
            response = requests.post(f"http://127.0.0.1:8000/predict/{track_id}")
            return response.json()
        except:
            st.error("Ошибка API!")
            return None


    track_data = get_track_data(selected_track)

    if track_data and "points" in track_data:
        points = pd.DataFrame(track_data["points"])

        center_lat = points['latitude'].mean()
        center_lon = points['longitude'].mean()

        m = folium.Map(
            location=[center_lat, center_lon],
            zoom_start=14
        )

        avg_risk = points['risk'].mean()
        line_color = 'green' if avg_risk < 1 else 'orange' if avg_risk < 1.5 else 'red'

        folium.PolyLine(
            list(zip(points['latitude'], points['longitude'])),
            color=line_color,
            weight=4,
            opacity=0.8,
            popup=f"Трек {selected_track} (ср. риск: {avg_risk:.1f})"
        ).add_to(m)

        for _, point in points.iterrows():
            color = 'green' if point['risk'] == 0 else 'orange' if point['risk'] == 1 else 'red'
            folium.CircleMarker(
                location=[point['latitude'], point['longitude']],
                radius=6,
                color=color,
                fill=True,
                fillColor=color,
                fillOpacity=0.7,
                popup=f"Точка {point['point_id']}<br>"
                      f"Риск: {point['risk']}<br>"
                      f"Высота: {point['elevation']:.0f}м<br>"
                      f"Скорость: {point['speed']:.1f}м/с"
            ).add_to(m)

        legend_html = '''
        <div style="position: fixed; bottom: 50px; right: 50px; width: 220px; height: auto; 
        background-color: white; border:2px solid grey; z-index:9999; 
        font-size:14px; padding: 12px; border-radius: 5px; box-shadow: 0 0 10px rgba(0,0,0,0.2);">
        <p style="margin: 0 0 10px 0;"><b>Легенда рисков</b></p>
        <p style="margin: 8px 0;">
            <span style="color: green; font-size: 18px;">●</span> 
            Низкий риск (0)
        </p>
        <p style="margin: 8px 0;">
            <span style="color: orange; font-size: 18px;">●</span> 
            Средний риск (1)
        </p>
        <p style="margin: 8px 0;">
            <span style="color: red; font-size: 18px;">●</span> 
            Высокий риск (2)
        </p>
        <p style="margin: 5px 0; font-size: 11px; color: #666;">
            Линия: средний риск трека
        </p>
        </div>
        '''
        m.get_root().html.add_child(folium.Element(legend_html))


        st.components.v1.html(m._repr_html_(), height=600)


    else:
        st.error("Трек не найден!")
""",
    41:"""@echo off
echo Запуск API + Streamlit...
start "FastAPI" cmd /k "cd /d C:PycharmProjects\MapPy && .venv\Scripts\activate && python -m uvicorn api:app --reload --port 8000"
timeout /t 3
start "Streamlit" cmd /k "cd /d C:PycharmProjects\MapPy && .venv\Scripts\activate && streamlit run app.py --server.port 8501"

echo API: http://127.0.0.1:8000/docs
echo Streamlit: http://127.0.0.1:8501
pause
""",
}

def s(id: int = 1) -> bool:

    text = SNIPPETS.get(id, SNIPPETS[1])
    pyperclip.copy(text)
def ClusterKMeans(id: int = 1) -> bool:

    text = SNIPPETS.get(id, SNIPPETS[1])
    pyperclip.copy(text)

def figsize(id: int = 1, id2: int = 1) -> bool:
    text = SNIPPETS.get(id, SNIPPETS[1])
    pyperclip.copy(text)

def x(id: int = 1) -> bool:

    text = SNIPPETS.get(id, SNIPPETS[1])
    pyperclip.copy(text)