from __future__ import annotations

import datetime as dt
import http.server
import os
import socketserver
import subprocess
import threading
import time
from pathlib import Path


BASE_DIR = Path(__file__).resolve().parent
PORT = int(os.getenv("PORT", "8086"))
UPDATE_HOUR = int(os.getenv("UPDATE_HOUR", "16"))
UPDATE_MINUTE = int(os.getenv("UPDATE_MINUTE", "0"))


def run_fetch() -> None:
    result = subprocess.run(
        ["python", "fetch_stock_data.py"],
        cwd=BASE_DIR,
        check=False,
    )
    print(f"fetch_stock_data.py exited with code {result.returncode}")


def seconds_until_next_update(now: dt.datetime | None = None) -> float:
    now = now or dt.datetime.now()
    target = now.replace(hour=UPDATE_HOUR, minute=UPDATE_MINUTE, second=0, microsecond=0)
    if target <= now:
        target += dt.timedelta(days=1)
    return (target - now).total_seconds()


def refresh_loop() -> None:
    while True:
        wait = seconds_until_next_update()
        next_run = dt.datetime.now() + dt.timedelta(seconds=wait)
        print(
            f"Next data update at {next_run:%Y-%m-%d %H:%M} "
            f"(in {int(wait)}s), daily at {UPDATE_HOUR:02d}:{UPDATE_MINUTE:02d} Asia/Jakarta"
        )
        time.sleep(wait)
        run_fetch()


def serve() -> None:
    os.chdir(BASE_DIR)
    handler = http.server.SimpleHTTPRequestHandler
    with socketserver.TCPServer(("", PORT), handler) as httpd:
        print(f"Serving Faintry Stock at http://0.0.0.0:{PORT}/ui/")
        httpd.serve_forever()


def main() -> None:
    print("Starting Faintry Stock app...")
    run_fetch()
    worker = threading.Thread(target=refresh_loop, daemon=True)
    worker.start()
    serve()


if __name__ == "__main__":
    main()
