use actix_files::{Files, NamedFile};
use actix_identity::Identity;
use actix_identity::{CookieIdentityPolicy, IdentityService};
use actix_web::{
    cookie::Cookie, get, http, middleware, post, web, web::Data, web::Form, App, HttpRequest,
    HttpResponse, HttpServer, Responder,
    http::{header::ContentType, StatusCode}, error::ResponseError
};
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use tera::{Context, Tera};

use serde_json::{json, Value};
use derive_more::{Display, Error};

// #[derive(Debug, Display)]
// pub struct MyError {
//     tmpl: Tera,
//     message_erreur: String,
// }
// impl MyError {
//     pub fn new(_tmpl: Tera, message: &String) -> Self {
//         MyError {
//             tmpl: _tmpl,
//             message_erreur: message.to_string(),
//         }
//     }
// }
// impl ResponseError for MyError {

//     fn error_response(&self) -> HttpResponse {
//         let context = Context::new();
//         context.insert("message_erreur", &self.message_erreur);
//         let result_tmpl = self.tmpl.render("catch/500.html.twig", &context);
//         let body = "internal error".to_string();
//         if !result_tmpl.is_err() {
//             body = result_tmpl.unwrap();
//         }
//         HttpResponse::build(StatusCode::INTERNAL_SERVER_ERROR)
//             .insert_header(ContentType::html())
//             .body(body)
//     }

//     // fn status_code(&self) -> StatusCode {
//     //     match *self {
//     //         MyError::InternalError => StatusCode::INTERNAL_SERVER_ERROR,
//     //         MyError::BadClientData => StatusCode::BAD_REQUEST,
//     //         MyError::Timeout => StatusCode::GATEWAY_TIMEOUT,
//     //     }
//     // }
// }

pub fn json(obj: Value) -> HttpResponse {
    HttpResponse::Ok().insert_header(ContentType::json()).body(obj.to_string())
}

pub fn text(s: String) -> HttpResponse {
    HttpResponse::Ok().body(s)
}

pub fn template(tmpl: Data<Tera>, name: &'static str, context: &Context) -> HttpResponse {
    HttpResponse::Ok().body(tmpl.render(name, context).unwrap())
}

pub fn redirect(uri: &str) -> HttpResponse {
    HttpResponse::Found()
        .append_header((http::header::LOCATION, uri))
        .finish()
}

pub fn just_404(tmpl: Data<Tera>) -> HttpResponse {
    let context = Context::new();
    HttpResponse::NotFound().body(tmpl.render("catch/404.html.twig", &context).unwrap())
    // HttpResponse::NotFound().finish()
}

pub fn file(req: HttpRequest, path: PathBuf) -> HttpResponse {
    NamedFile::open(path).unwrap().into_response(&req)
}
