use actix_web::HttpResponse;
use maud::{Markup, Render, html};

use super::{
    Page,
    components::{Complaint, DeleteForm, TextArea},
};

/// A key as the list of them shows it.
pub struct SshKeySummary {
    /// The row's id, which is what deletion addresses.
    pub id: i64,
    pub name: String,
    pub algorithm: String,
    pub fingerprint: String,
    /// When the key was last used to connect, already formatted.
    pub last_used: Option<String>,
}

/// What the add-key form shows when it is (re)rendered.
#[derive(Default)]
pub struct SshKeyForm {
    pub key: Option<String>,
    pub error: Option<String>,
}

pub(super) struct SshKeysBody<'a> {
    owner: &'a str,
    keys: &'a [SshKeySummary],
    form: &'a SshKeyForm,
}

impl Render for SshKeysBody<'_> {
    fn render(&self) -> Markup {
        html! {
            h2 { "SSH keys" }
            p {
                "A key here is what lets you fetch from and push to your "
                "repositories. Passwords are not accepted over SSH."
            }
            @if self.keys.is_empty() {
                p { "No keys yet." }
            } @else {
                ul class="ssh-keys" {
                    @for key in self.keys {
                        li {
                            strong { (key.name) }
                            " "
                            span class="algorithm" { (key.algorithm) }
                            code { (key.fingerprint) }
                            @if let Some(last_used) = &key.last_used {
                                span class="last-used" { "last used " (last_used) }
                            } @else {
                                span class="last-used" { "never used" }
                            }
                            (DeleteForm {
                                action: format!("/~{}/ssh-keys/{}/delete", self.owner, key.id),
                                form_class: None,
                                button_class: None,
                                confirm: None,
                            })
                        }
                    }
                }
            }
            h3 { "Add a key" }
            (Complaint(self.form.error.as_deref()))
            form method="post" action=(format!("/~{}/ssh-keys", self.owner)) {
                (TextArea {
                    label: Some("Public key"),
                    name: "key",
                    rows: 4,
                    value: self.form.key.as_deref(),
                    required: true,
                })
                button type="submit" { "Add" }
            }
        }
    }
}

/// The page listing `owner`'s SSH keys, and the form for adding one.
pub fn ssh_keys(
    viewer: Option<&str>,
    owner: &str,
    keys: &[SshKeySummary],
    form: &SshKeyForm,
) -> HttpResponse {
    Page {
        title: format!("Frogue - {owner}'s SSH keys"),
        viewer: viewer.map(str::to_string),
        extra_head: None,
        body: SshKeysBody { owner, keys, form },
    }
    .into_response()
}
