Skip to content
use actix_web::Result as AwResult;
use actix_web::{HttpRequest, HttpResponse, get, web};

use super::render_layout;
use super::session_auth::get_username_from_request;
use crate::auth::NotesContext;

#[get("/")]
pub async fn index(
    req: HttpRequest,
    auth_state: web::Data<NotesContext>,
) -> AwResult<HttpResponse> {
    let username = get_username_from_request(&req, &auth_state).await;

    let username = match username {
        Some(name) => name,
        None => {
            return Ok(HttpResponse::Found()
                .insert_header(("Location", "/auth/login"))
                .finish());
        }
    };

    let content = maud::html! {
        div class="mw8 center w-100 mt3" {
            div class="tc mb5" {
                h1 class="f1 fw6 brand mv3" { "Welcome, " (username) "!" }
                p class="f4 black-60 mt0" { "What would you like to do today?" }
            }

            div class="flex flex-column flex-row-m flex-row-l justify-center gap-4 justify-around-ns" {
                // Save Card
                div class="w-100 w-45-m w-45-l bg-white pa4 shadow-4 ba b--black-10 note-card flex flex-column justify-between mb4 mb0-ns" {
                    div {
                        div class="flex items-center mb3" {
                            div class="bg-blue white pa3 flex items-center justify-center mr3" style="width: 48px; height: 48px;" {
                                // Simple pen SVG
                                svg class="w2 h2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" {
                                    path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z" {}
                                }
                            }
                            h2 class="f3 fw6 ma0 brand" { "Save Note" }
                        }
                        p class="f5 black-60 lh-copy" {
                            "Jot down your thoughts, ideas, or reminders instantly. Add tags and categories to organize them. The title of the note is automatically derived from the start of your text!"
                        }
                    }
                    a href="/save" class="db tc btn-brand no-underline f5 fw6 mt3 pv3" {
                        "Go to Save Note"
                    }
                }

                // View Card
                div class="w-100 w-45-m w-45-l bg-white pa4 shadow-4 ba b--black-10 note-card flex flex-column justify-between" {
                    div {
                        div class="flex items-center mb3" {
                            div class="bg-green white pa3 flex items-center justify-center mr3" style="width: 48px; height: 48px;" {
                                // Simple search SVG
                                svg class="w2 h2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" {
                                    path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" {}
                                }
                            }
                            h2 class="f3 fw6 ma0 brand" { "Search & View" }
                        }
                        p class="f5 black-60 lh-copy" {
                            "Browse through your notes library. Easily search by keywords, filter by categories and tags, and edit or delete your notes as needed."
                        }
                    }
                    a href="/view" class="db tc btn-brand no-underline f5 fw6 mt3 pv3" {
                        "Go to Search & View"
                    }
                }
            }
        }
    };

    Ok(HttpResponse::Ok()
        .content_type("text/html; charset=utf-8")
        .body(render_layout(&content, Some(&username)).into_string()))
}

#[get("/save")]
pub async fn save_page(
    req: HttpRequest,
    auth_state: web::Data<NotesContext>,
) -> AwResult<HttpResponse> {
    let username = get_username_from_request(&req, &auth_state).await;

    let username = match username {
        Some(name) => name,
        None => {
            return Ok(HttpResponse::Found()
                .insert_header(("Location", "/auth/login"))
                .finish());
        }
    };

    let content = maud::html! {
        div class="mw7 center w-100 bg-white pa4 shadow-4 ba b--black-10 mt3" {
            div class="flex items-center justify-between mb4 pb2 bb b--black-10" {
                h1 class="f3 fw6 brand ma0" { "Create New Note" }
                a href="/" class="link gray hover-black f6 underline" { "Back to Dashboard" }
            }

            form
                hx-post="/save"
                hx-target="#save-result"
                hx-swap="innerHTML"
                hx-on--after-request="if(event.detail.successful) this.reset()"
                class="flex flex-column"
            {
                div class="mb3" {
                    label class="db f6 fw6 black-70 mb2" for="content" { "Note Content" }
                    textarea
                        name="content"
                        id="content"
                        required
                        rows="12"
                        class="db w-100 pa3 ba b--black-20 f5 code"
                        style="resize: vertical;"
                        placeholder="Start typing your note here... The first line will automatically become the title!" {}
                }

                div class="flex flex-column flex-row-ns gap-3 mb4" {
                    div class="w-100 w-50-ns mb3 mb0-ns mr2-ns" {
                        label class="db f6 fw6 black-70 mb2" for="category" { "Category (Optional)" }
                        input
                            type="text"
                            name="category"
                            id="category"
                            class="db w-100 pa2 ba b--black-20 f5"
                            placeholder="e.g. Work, Personal, Snippets";
                    }

                    div class="w-100 w-50-ns ml2-ns" {
                        label class="db f6 fw6 black-70 mb2" for="tags" { "Tags (Optional, comma-separated)" }
                        input
                            type="text"
                            name="tags"
                            id="tags"
                            class="db w-100 pa2 ba b--black-20 f5"
                            placeholder="e.g. rust, htmx, ideas";
                    }
                }

                button
                    type="submit"
                    class="btn-brand f5 fw6 cursor-pointer self-start ph4 pv3"
                {
                    "Save Note"
                }
            }

            div id="save-result" class="mt3" {}
        }
    };

    Ok(HttpResponse::Ok()
        .content_type("text/html; charset=utf-8")
        .body(render_layout(&content, Some(&username)).into_string()))
}

#[get("/view")]
pub async fn view_page(
    req: HttpRequest,
    auth_state: web::Data<NotesContext>,
) -> AwResult<HttpResponse> {
    let username = get_username_from_request(&req, &auth_state).await;

    let username = match username {
        Some(name) => name,
        None => {
            return Ok(HttpResponse::Found()
                .insert_header(("Location", "/auth/login"))
                .finish());
        }
    };

    let db = auth_state.db();
    let categories = db.get_all_categories().await.unwrap_or_default();
    let tags = db.get_all_tags().await.unwrap_or_default();

    let content = maud::html! {
        div class="mw9 center w-100 mt2 flex flex-column flex-row-ns" style="min-height: 75vh;" {
            // Left column: Search and list of notes
            div class="w-100 w-40-ns pr3-ns br-ns b--black-10 flex flex-column mb4 mb0-ns" {
                (render_search_card(&categories, &tags))

                // Search results container
                div
                    id="search-results"
                    hx-get="/view/search"
                    hx-include="#search-form"
                    hx-trigger="load, refresh-list from:body"
                    class="flex-auto overflow-y-auto"
                    style="max-height: 60vh;"
                {
                    p class="gray tc mt4" { "Loading notes..." }
                }
            }

            // Right column: Selected note details / Edit form
            div id="note-details" class="w-100 w-60-ns pl3-ns" {
                div class="bg-white pa4 shadow-4 ba b--black-10 tc gray f5 flex flex-column justify-center items-center" style="min-height: 300px;" {
                    // Simple note icon
                    svg class="w3 h3 mb3 black-30" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" {
                        path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" {}
                    }
                    "Select a note from the left to view and edit its details."
                }
            }
        }
    };

    Ok(HttpResponse::Ok()
        .content_type("text/html; charset=utf-8")
        .body(render_layout(&content, Some(&username)).into_string()))
}

pub fn render_search_card(categories: &[String], tags: &[String]) -> maud::Markup {
    maud::html! {
        div class="bg-white pa3 shadow-4 ba b--black-10 mb3" id="search-card" {
            div class="flex items-center justify-between mb3" {
                h2 class="f4 fw6 brand ma0" { "Search & Filter" }
                button
                    hx-get="/view/search-card"
                    hx-target="#search-card"
                    hx-swap="outerHTML"
                    class="f6 link gray hover-brand bg-transparent bn pointer underline"
                {
                    "Reload"
                }
            }

            form
                id="search-form"
                hx-get="/view/search"
                hx-target="#search-results"
                hx-trigger="submit, change, input changed delay:500ms from:#search-input"
                onsubmit="return false;"
                class="flex flex-column"
            {
                div class="mb3" {
                    label class="db f6 fw6 black-70 mb1" for="search-input" { "Keyword Search" }
                    input
                        type="search"
                        name="q"
                        id="search-input"
                        class="db w-100 pa2 ba b--black-20 f5"
                        placeholder="Search title or content...";
                }

                div class="flex gap-2" {
                    div class="w-50 mr1" {
                        label class="db f6 fw6 black-70 mb1" for="category-select" { "Category" }
                        select
                            name="category"
                            id="category-select"
                            class="db w-100 pa2 ba b--black-20 f6 bg-white"
                        {
                            option value="" { "All Categories" }
                            @for cat in categories {
                                option value=(cat) { (cat) }
                            }
                        }
                    }
                    div class="w-50 ml1" {
                        label class="db f6 fw6 black-70 mb1" for="tag-select" { "Tag" }
                        select
                            name="tag"
                            id="tag-select"
                            class="db w-100 pa2 ba b--black-20 f6 bg-white"
                        {
                            option value="" { "All Tags" }
                            @for tag in tags {
                                option value=(tag) { (tag) }
                            }
                        }
                    }
                }
            }
        }
    }
}

#[get("/view/search-card")]
pub async fn search_card_handler(
    req: HttpRequest,
    auth_state: web::Data<NotesContext>,
) -> AwResult<HttpResponse> {
    let username = get_username_from_request(&req, &auth_state).await;

    let _username = match username {
        Some(name) => name,
        None => {
            return Ok(HttpResponse::Unauthorized().body("Unauthorized"));
        }
    };

    let db = auth_state.db();
    let categories = db.get_all_categories().await.unwrap_or_default();
    let tags = db.get_all_tags().await.unwrap_or_default();

    let markup = render_search_card(&categories, &tags);

    Ok(HttpResponse::Ok()
        .content_type("text/html; charset=utf-8")
        .body(markup.into_string()))
}