import { Form, redirect, useNavigation } from "react-router";
import type { Route } from "./+types/home";
import { createPost, listPosts } from "~/lib/db.server";
import { renderMarkdown } from "~/lib/md.server";

export async function loader() {
  const posts = listPosts();
  return { posts: posts.map((p) => ({ ...p, html: renderMarkdown(p.content) })) };
}

export async function action({ request }: Route.ActionArgs) {
  const form = await request.formData();
  const content = String(form.get("content") ?? "").trim();

  if (!content) {
    return { error: "内容を入力してください", content };
  }
  if (content.length > 10000) {
    return { error: "投稿が長すぎます（最大10,000文字）", content };
  }

  createPost({ id: crypto.randomUUID(), content });
  return redirect("/");
}

export default function Home({ loaderData, actionData }: Route.ComponentProps) {
  const { posts } = loaderData;
  const navigation = useNavigation();
  const isSubmitting = navigation.state === "submitting";

  return (
    <div className="wrap">
      <header className="site-header">
        <h1>log</h1>
      </header>

      <div className="compose">
        <Form method="post">
          <textarea
            name="content"
            placeholder="Markdown で投稿..."
            rows={4}
            defaultValue={actionData?.content ?? ""}
            autoFocus
          />
          {actionData?.error && (
            <p className="error-msg">{actionData.error}</p>
          )}
          <div className="compose-row">
            <span className="hint">markdown</span>
            <button type="submit" disabled={isSubmitting}>
              {isSubmitting ? "投稿中…" : "投稿"}
            </button>
          </div>
        </Form>
      </div>

      <div className="feed">
        {posts.length === 0 && (
          <p className="empty">まだ投稿がありません</p>
        )}
        {posts.map((post) => (
          <article key={post.id} className="post">
            <time className="post-meta" dateTime={post.created_at + "Z"}>
              {formatDate(post.created_at)}
            </time>
            <div
              className="prose"
              dangerouslySetInnerHTML={{ __html: post.html }}
            />
          </article>
        ))}
      </div>
    </div>
  );
}

function formatDate(isoUtc: string): string {
  return new Date(isoUtc + "Z").toLocaleString("ja-JP", {
    year: "numeric",
    month: "2-digit",
    day: "2-digit",
    hour: "2-digit",
    minute: "2-digit",
    timeZone: "Asia/Tokyo",
  });
}
