mod models;
mod auth;
mod books;
mod cart;
mod profile;
mod error;

use actix_web::{web, App, HttpServer};
use actix_cors::Cors;
use actix_files::Files;
use dotenv::dotenv;
use env_logger::Builder;
use sqlx::postgres::PgPoolOptions;
use std::env;
use log;

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    Builder::from_env(env_logger::Env::default().default_filter_or("debug")).init();
    dotenv().ok();

    let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set in .env");
    let pool = PgPoolOptions::new()
        .max_connections(5)
        .connect(&database_url)
        .await
        .expect("Failed to create pool");

    HttpServer::new(move || {
        let cors = Cors::default()
            .allow_any_origin()
            .allowed_methods(vec!["GET", "POST", "DELETE"])
            .allowed_headers(vec![
                actix_web::http::header::CONTENT_TYPE,
                actix_web::http::header::AUTHORIZATION,
                actix_web::http::header::ACCEPT,
            ])
            .supports_credentials();

        App::new()
            .app_data(web::Data::new(pool.clone()))
            .wrap(cors)
            .wrap(actix_web::middleware::Logger::default())
            .service(books::get_books)
            .service(books::get_book)
            .service(auth::register)
            .service(auth::login)
            .service(auth::logout)
            .service(auth::check_auth)
            .service(cart::get_cart)
            .service(cart::add_to_cart)
            .service(cart::remove_from_cart)
            .service(cart::checkout)
            .service(cart::update_cart_quantity)
            .service(profile::get_order_history)
            .service(
                Files::new("/images", "./static/images")
                    .show_files_listing(),
            )
            .service(Files::new("/", "./static").index_file("index.html"))
    })
    .bind("0.0.0.0:7999")?
    .run()
    .await
}

