use actix_web::{post, web, HttpResponse, Responder};
use bcrypt::{hash, verify, DEFAULT_COST};
use serde::{Deserialize, Serialize};

#[derive(Deserialize)]
pub struct RegistrationData {
    pub email: String,
    pub haslo: String,
    pub imie: String,
    #[serde(rename = "confirmPassword")]
    pub confirm_password: String,
}

#[post("/rejestracja")]
pub async fn rejestracja(
    form: web::Json<RegistrationData>,
    pool: web::Data<sqlx::PgPool>,
) -> impl Responder {
    // Walidacja hasła
    if form.haslo.len() < 8 {
        return HttpResponse::BadRequest().body("Hasło musi mieć minimum 8 znaków");
    }

    // Sprawdzenie, czy hasła się zgadzają
    if form.haslo != form.confirm_password {
        return HttpResponse::BadRequest().body("Hasła nie są identyczne");
    }

    // Hashowanie hasła
    let hashed_password = match hash(&form.haslo, DEFAULT_COST) {
        Ok(h) => h,
        Err(_) => return HttpResponse::InternalServerError().finish(),
    };

    // Zapisz do bazy danych
    match sqlx::query!(
        r#"
        INSERT INTO uzytkownicy (email, haslo, imie)
        VALUES ($1, $2, $3)
        "#,
        form.email,
        hashed_password,
        form.imie
    )
    .execute(pool.get_ref())
    .await
    {
        Ok(_) => HttpResponse::Created().body("Konto utworzone pomyślnie"),
        Err(e) => {
            if e.to_string().contains("duplicate key value") {
                HttpResponse::Conflict().body("Email jest już zarejestrowany")
            } else {
                HttpResponse::InternalServerError().finish()
            }
        }
    }
}

#[derive(Deserialize)]
pub struct LoginData {
    pub email: String,
    pub haslo: String,
}

#[derive(Serialize)]
pub struct LoginResponse {
    pub token: String,
    pub imie: String,
}

#[post("/login")]
pub async fn login(
    form: web::Json<LoginData>,
    pool: web::Data<sqlx::PgPool>,
) -> impl Responder {
    let user = match sqlx::query!(
        "SELECT id, haslo, imie FROM uzytkownicy WHERE email = $1",
        form.email
    )
    .fetch_optional(pool.get_ref())
    .await
    {
        Ok(Some(u)) => u,
        Ok(None) => return HttpResponse::Unauthorized().body("Nieprawidłowe dane"),
        Err(_) => return HttpResponse::InternalServerError().finish(),
    };

    match verify(&form.haslo, &user.haslo) {
        Ok(true) => {
            // W praktyce użyj JWT lub innego mechanizmu autentykacji
            let dummy_token = format!("user-{}-token", user.id);
            HttpResponse::Ok().json(LoginResponse {
                token: dummy_token,
                imie: user.imie,
            })
        },
        _ => HttpResponse::Unauthorized().body("Nieprawidłowe hasło"),
    }
}

