from flask import Flask, render_template, request, jsonify
from database import DatabaseManager
from models import create_stock_model, get_stock_class
import talib
from util import (
    get_dataframe,
    detect_trend_lines,
    detect_all_inverse_head_and_shoulders,
    check_ma_golden_cross,
    check_macd_golden_cross,
    check_rci_golden_cross,
    check_rising_condition,
    check_rise,
)
from scipy.signal import find_peaks

# Flaskアプリケーションを作成


def create_app():
    app = Flask(__name__)

    # データベースマネージャーの設定
    db_manager = DatabaseManager()
    session = db_manager.get_session()

    # ルートの定義
    @app.route("/")
    def index():
        # 銘柄コード
        code = 9984

        # 銘柄を取得
        stock_class = get_stock_class(db_manager.Base)
        stock = session.query(stock_class).where(stock_class.code == code).one()

        # 株価データを取得
        df = get_dataframe(code)
        # データフレームを辞書形式に変換し、テンプレートに渡せる形式に
        chart_data = df.to_dict(orient="list")

        # ローソク足チャート
        # return render_template("candle.html", stock=stock, chart_data=chart_data)
        # 移動平均線とボリンジャーバンド
        return render_template("candle_line.html", stock=stock, chart_data=chart_data)
        # オシレーターと出来高
        # return render_template('candle_line_osc.html',  stock=stock, chart_data=chart_data)
        # ツールチップ
        #return render_template("index.html", stock=stock, chart_data=chart_data)

    # 銘柄詳細
    @app.route("/stock/<string:code>")
    def stock_detail(code):
        # 銘柄を取得
        stock_class = get_stock_class(db_manager.Base)
        stock = session.query(stock_class).where(stock_class.code == code).one()

        # 株価データ取得
        df = get_dataframe(code)
        # データフレームを辞書形式に変換し、テンプレートに渡せる形式に
        chart_data = df.to_dict(orient="list")

        # 直近3日間で上がるパターンに合致しているか
        is_rise = check_rise(df)

        # stocksテーブル 全件取得
        stocks = session.query(stock_class).all()

        return render_template(
            "trendline.html",
            stock=stock,
            chart_data=chart_data,
            stocks=stocks,
            is_rise=is_rise,
        )

    # トレンドラインの更新　Ajaxで利用
    @app.route("/update_trendlines/<string:code>")
    def update_trendlines(code):
        # 各値を取得
        lookback = int(request.args.get("lookback", 100))
        min_touches = int(request.args.get("min_touches", 5))
        order = int(request.args.get("order", 5))

        # 株価データ取得
        df = get_dataframe(code)

        # トレンドラインを算出
        trend_lines = detect_trend_lines(df, lookback, min_touches, order)

        return jsonify(trend_lines)

    # 逆三尊パターン
    @app.route("/shoulders/<string:code>")
    def stock_shoulders(code):
        # 株価データ取得
        df = get_dataframe(code)
        # データフレームを辞書形式に変換し、テンプレートに渡せる形式に
        chart_data = df.to_dict(orient="list")

        # stocksテーブル 全件取得
        stock_class = get_stock_class(db_manager.Base)
        stocks = session.query(stock_class).all()

        stock = session.query(stock_class).where(stock_class.code == code).one()

        # 株価データの平滑化
        smoothed_prices = talib.SMA(df["low"], timeperiod=5)

        # ボトム
        bottoms, _ = find_peaks(
            -smoothed_prices, distance=5, prominence=df["low"].values[-1] * 0.05
        )

        # 逆三尊パターンを検出
        patterns = detect_all_inverse_head_and_shoulders(
            smoothed_prices, bottoms, threshold_ratio=0.05, min_distance=5
        )

        # patternsをPython標準のint型に変換（numpy型が含まれる場合に備える）
        patterns = [
            [int(left), int(center), int(right)] for left, center, right in patterns
        ]

        return render_template(
            "shoulders.html",
            stock=stock,
            stocks=stocks,
            chart_data=chart_data,
            patterns=patterns,
            smoothed_prices=smoothed_prices.tolist(),
            bottoms=bottoms.tolist(),
        )

    return app
