//! Comment views for tickets and patch proposals.

use chrono::{DateTime, FixedOffset};
use maud::{Markup, PreEscaped, Render, html};

use super::components::{AuthorName, Complaint, DeleteForm, TextArea};
use crate::comments::CommentAuthor;

/// A comment as displayed in the UI.
pub struct CommentView<'a> {
    /// The base URL we can find this comment at. MUST contain the "/comments" part.
    pub base_url: &'a str,
    /// The comment's UUID for edit/delete forms.
    pub uuid: String,
    /// The author's information (local or remote).
    pub author: CommentAuthor,
    /// Raw/Markdown comment content
    pub content: String,
    /// The comment content rendered as HTML.
    pub content_html: String,
    /// When the comment was created.
    pub created_at: DateTime<FixedOffset>,
    /// When the comment was last edited.
    pub updated_at: Option<DateTime<FixedOffset>>,
    /// Whether the current viewer may change (edit/delete) this comment.
    pub may_change: bool,
}

impl Render for CommentView<'_> {
    fn render(&self) -> Markup {
        // let edit_action = format!("{}/{}", base_action, comment.uuid);
        // let delete_action = format!("{}/{}/delete", base_action, comment.uuid);

        html! {
            article class="comment" id=(format!("comment-{}", self.uuid)) {
                header class="comment-header" {
                    (AuthorName(&self.author))
                    " "
                    span class="comment-created" {
                        (self.created_at.format("%Y-%m-%d %H:%M UTC").to_string())
                    }
                    @if let Some(updated_at) = &self.updated_at {
                        span class="comment-updated" {
                            em {
                                " (last updated at "
                                (updated_at.format("%Y-%m-%d %H:%M UTC").to_string())
                                ")"
                            }
                        }
                    }
                }
                div class="comment-content" {
                    (PreEscaped(&self.content_html))
                }
                @if self.may_change {
                    details class="comment-actions" {
                        summary { "Actions" }
                        form method="POST" action=(format!("{}/{}", self.base_url, self.uuid)) class="inline-form" {
                            (TextArea {
                                label: Some("Edit comment"),
                                name: "content",
                                rows: 4,
                                value: Some(&self.content),
                                required: true,
                            })
                            button type="submit" { "Save" }
                        }
                        (DeleteForm {
                            action: format!("{}/{}/delete", self.base_url, self.uuid),
                            form_class: Some("inline-form"),
                            button_class: Some("danger"),
                            confirm: Some("Delete this comment?"),
                        })
                    }
                }
            }
        }
    }
}

pub struct CommentListView<'a> {
    pub comments: &'a [CommentView<'a>],
    pub may_comment: bool,
    pub base_comments_url: &'a str,
    pub comment_error: Option<&'a str>,
    pub comment_draft: Option<&'a str>,
}

impl Render for CommentListView<'_> {
    fn render(&self) -> Markup {
        html! {
            section class="comments" {
                h3 { "Comments" }

                @if self.comments.is_empty() {
                    p class="no-comments" { "No comments yet." }
                } @else {
                    @for c in self.comments {
                        (CommentView {
                            base_url: self.base_comments_url,
                            // TODO: find a solution that doesn't clone here
                            content_html: c.content_html.clone(),
                            author: c.author.clone(),
                            uuid: c.uuid.clone(),
                            content: c.content.clone(),
                            ..*c
                        })
                    }
                }

                @if self.may_comment {
                    (Complaint(self.comment_error))
                    form method="POST" action=(self.base_comments_url) class="comment-form" {
                        (TextArea {
                            label: Some("Add a comment (Markdown supported)"),
                            name: "content",
                            rows: 4,
                            value: self.comment_draft,
                            required: true,
                        })
                        button type="submit" { "Comment" }
                    }
                }
            }
        }
    }
}
