mod create_db;
use create_db::init;

use actix_web::{App, HttpServer, get, Responder, HttpResponse, http::header::ContentType};
use actix_files::Files;
use serde_json::json;
use sqlite::{Connection, State}; 
use serde::{Serialize, Deserialize};

#[derive(serde::Serialize)]
struct Article {
    id: i64,
    title: String,
    auteur: Option<String>,
    edited_at: Option<String>,
    published_at: Option<String>,
    content: String,
}

#[get("/api/hello")]
async fn hello() -> impl Responder {
    HttpResponse::Ok().body("Hello world!")
}

#[get("/api/articles")]
async fn get_articles() -> impl Responder {
    let conn = Connection::open("./data/data.db").unwrap();
    let mut stmt = conn.prepare("SELECT * FROM articles").unwrap();
    let mut articles = Vec::new();

    while let State::Row = stmt.next().unwrap() {
        let id = stmt.read::<i64, _>(0).unwrap();
        let title = stmt.read::<String, _>(1).unwrap();
        let content = stmt.read::<String, _>(3).unwrap();
        articles.push(Article {
            id,
            title,
            auteur: None,
            edited_at: None,
            published_at: None,
            content
        });
    }

    HttpResponse::Ok().json(articles)
}

#[get("/api")]
async fn api() -> impl Responder {
    let value = json!({
        "code": 200,
        "success": true,
        "payload": {
            "features": [
                "serde",
                "json"
            ],
            "homepage": null
        }
    });
    HttpResponse::Ok()
        .content_type(ContentType::json())
        .body(value.to_string())
}

#[actix_web::main]
async fn main() -> Result<(), std::io::Error> {
    let _ = init();

    HttpServer::new(|| {
        App::new()
            .service(hello)
            .service(get_articles)
            .service(api)
            .service(Files::new("/", "public").index_file("index.html"))
    })
    .bind(("0.0.0.0", 2486))?
    .run()
    .await
}

