import Link from "next/link";
import { cookies, headers } from "next/headers";
import { notFound } from "next/navigation";
import type { Metadata } from "next";
import Header from "@/components/header";
import DetailRawPanel from "@/components/detail-raw-panel";

type SourceType = "twitter" | "pixiv";

type PostDetailResponse = {
    _id: string;
    type: SourceType;
    url?: string;
    author?: string;
    tags?: string[];
    tweet?: {
        text?: string;
        title?: string;
    };
    mediaUrl?: string;
    mediaIndex?: number;
};

type Me = {
    role: "admin" | "writer" | "reader";
};

function getSourceLabel(type: SourceType) {
    return type === "twitter" ? "X" : type === "pixiv" ? "Pixiv" : "-";
}

function createDetailDescription(post: PostDetailResponse) {
    const author = post.author?.trim() || "unknown";
    const source = getSourceLabel(post.type);
    const tags = (post.tags ?? []).filter((tag) => tag.trim().length > 0).slice(0, 5);
    const tagText = tags.length > 0 ? ` | Tags: ${tags.join(", ")}` : "";
    return `${author} | ${source} post${tagText}`;
}

function createDetailTitle(post: PostDetailResponse) {
    const author = post.author?.trim() || "unknown";
    const source = getSourceLabel(post.type);
    const rawText = post.tweet?.text || post.tweet?.title;
    const contentText = rawText?.trim() || post._id;
    return `${author} - ${contentText} | ${source}`;
}

function toAbsoluteUrl(value: string, baseUrl: string) {
    try {
        return new URL(value, baseUrl).toString();
    } catch {
        return value;
    }
}



async function getApiBaseUrl() {
    const configuredBaseUrl = process.env.API_BASE_URL;
    if (configuredBaseUrl) {
        return configuredBaseUrl;
    }

    const requestHeaders = await headers();
    const protocol = requestHeaders.get("x-forwarded-proto") ?? "http";
    const host = requestHeaders.get("x-forwarded-host") ?? requestHeaders.get("host");

    if (!host) {
        throw new Error("Unable to determine request host for server-side fetches.");
    }

    return `${protocol}://${host}`;
}

async function fetchPostDetail(apiBaseUrl: string, id: string) {
    const response = await fetch(`${apiBaseUrl}/api/post/detail/${id}`, {
        cache: "no-store",
    });

    if (response.status === 404 || response.status >= 500) {
        return null;
    }

    if (!response.ok) {
        throw new Error(`상세 정보를 불러오지 못했습니다: ${response.status}`);
    }

    return response.json() as Promise<PostDetailResponse>;
}

async function fetchViewerRole(apiBaseUrl: string) {
    const cookieHeader = (await cookies()).toString();
    if (!cookieHeader) {
        return "guest" as const;
    }

    try {
        const response = await fetch(`${apiBaseUrl}/api/auth/me`, {
            cache: "no-store",
            headers: {
                cookie: cookieHeader,
            },
        });

        if (!response.ok) {
            return "guest" as const;
        }

        const me = (await response.json()) as Me;
        return me.role;
    } catch {
        return "guest" as const;
    }
}

export async function generateMetadata({ params }: { params: Promise<{ id: string }> }): Promise<Metadata> {
    const { id } = await params;
    const fallbackTitle = `Detail ${id} | Akiyama Mizuki`;

    try {
        const apiBaseUrl = await getApiBaseUrl();
        const post = await fetchPostDetail(apiBaseUrl, id);
        const detailUrl = `${apiBaseUrl}/detail/${id}`;

        if (!post) {
            return {
                title: fallbackTitle,
                description: "Post detail",
                alternates: {
                    canonical: detailUrl,
                },
                robots: {
                    index: false,
                    follow: false,
                },
            };
        }

        const source = getSourceLabel(post.type);
        const author = post.author?.trim() || "unknown";
        const title = createDetailTitle(post);
        const description = createDetailDescription(post);
        const ogImageUrl = post.mediaUrl ? toAbsoluteUrl(post.mediaUrl, apiBaseUrl) : undefined;
        const ogImages = ogImageUrl
            ? [
                {
                    url: ogImageUrl,
                    alt: `${author} ${source}`,
                },
            ]
            : undefined;

        return {
            title,
            description,
            alternates: {
                canonical: detailUrl,
            },
            openGraph: {
                type: "article",
                title,
                description,
                url: detailUrl,
                siteName: "Akiyama Mizuki",
                images: ogImages,
            },
            twitter: {
                card: post.mediaUrl ? "summary_large_image" : "summary",
                title,
                description,
                images: ogImageUrl ? [ogImageUrl] : undefined,
            },
        };
    } catch {
        return {
            title: fallbackTitle,
            description: "Post detail",
        };
    }
}

export default async function DetailPage({ params }: { params: Promise<{ id: string }> }) {
    const { id } = await params;
    const apiBaseUrl = await getApiBaseUrl();
    const postPromise = fetchPostDetail(apiBaseUrl, id);
    const viewerRolePromise = fetchViewerRole(apiBaseUrl);

    let post: PostDetailResponse | null;
    try {
        post = await postPromise;
    } catch (loadError) {
        return (
        <div className="min-h-screen bg-main-gradient text-foreground transition-colors duration-500">
                <Header />
                <main className="mx-auto w-full max-w-6xl px-4 py-8 sm:px-6 lg:px-8">
                    <section className="border-b border-border/70 pb-6">
                        <div className="flex flex-wrap items-start justify-between gap-3">
                            <div>
                                <h1 className="text-xl tracking-wide">Detail</h1>
                            </div>
                            <div className="border-l border-border/80 pl-3 text-xs text-foreground/70">
                                <p>ID: <span className="font-medium text-foreground/90">{id}</span></p>
                            </div>
                        </div>
                        <p className="mt-4 text-sm text-red-600">
                            {loadError instanceof Error ? loadError.message : "상세 정보를 불러오지 못했습니다."}
                        </p>
                        <div className="mt-6">
                            <Link href="/" className="border border-border px-4 py-2 text-sm text-foreground/70 transition hover:bg-black/5">
                                돌아가기
                            </Link>
                        </div>
                    </section>
                </main>
            </div>
        );
    }

    if (!post) {
        notFound();
    }

    const viewerRole = await viewerRolePromise;
    const canManagePost = viewerRole === "admin" || viewerRole === "writer";
    const sourceLabel = post.type === "twitter" ? "𝕏" : post.type === "pixiv" ? "Pixiv" : "-";
    const tags = post.tags ?? [];

    return (
        <div className="min-h-screen bg-main-gradient text-foreground transition-colors duration-500">
            <Header />

            <main className="mx-auto w-full max-w-6xl px-4 py-8 sm:px-6 lg:px-8">
                <section className="border-b border-border/70 pb-6">
                    <div className="flex flex-wrap items-start justify-between gap-3">
                        <div>
                            <h1 className="text-xl tracking-wide">Detail</h1>
                        </div>
                        <div className="border-l border-border/80 pl-3 text-xs text-foreground/70">
                            <p>Source: <span className="font-medium text-foreground/90">{sourceLabel}</span></p>
                                <p className="mt-0.5">ID: <span className="font-medium text-foreground/90">{id}</span></p>
                        </div>
                    </div>

                    <div className="mt-6 grid gap-6 lg:grid-cols-[minmax(0,1.15fr)_minmax(320px,0.85fr)]">
                        <div className="space-y-3">
                            {post.mediaUrl ? (
                                <img
                                    src={post.mediaUrl}
                                    alt={post.author ?? post._id}
                                    loading="eager"
                                    decoding="async"
                                    className="w-full border border-border bg-card object-contain image-scale"
                                />
                            ) : (
                                <div className="aspect-4/5 w-full border border-border bg-muted/30" />
                            )}
                        </div>

                        <aside className="space-y-4">
                            <div className="border border-border bg-background/80 p-4">
                                <p className="text-xs uppercase tracking-[0.3em] text-foreground/40">Metadata</p>
                                <dl className="mt-3 space-y-3 text-sm">
                                    <div>
                                        <dt className="text-foreground/45">Author</dt>
                                        <dd className="mt-0.5 text-foreground/90">{post.author?.trim() || "unknown"}</dd>
                                    </div>
                                    <div>
                                        <dt className="text-foreground/45">Type</dt>
                                        <dd className="mt-0.5 text-foreground/90">{post.type}</dd>
                                    </div>
                                    <div>
                                        <dt className="text-foreground/45">Media Index</dt>
                                        <dd className="mt-0.5 text-foreground/90">{typeof post.mediaIndex === "number" ? post.mediaIndex + 1 : "-"}</dd>
                                    </div>
                                </dl>
                            </div>

                            <div className="border border-border bg-background/80 p-4">
                                <p className="text-xs uppercase tracking-[0.3em] text-foreground/40">Tags</p>
                                <div className="mt-3 flex flex-wrap gap-2">
                                    {tags.length > 0 ? tags.map((tag) => (
                                        <span key={tag} className="border border-border/80 px-2 py-1 text-xs text-foreground/75">
                                            {tag}
                                        </span>
                                    )) : (
                                        <span className="text-sm text-foreground/55">태그 없음</span>
                                    )}
                                </div>
                            </div>

                            <div className="flex flex-col gap-2">
                                {post.url ? (
                                    <a
                                        href={post.url}
                                        target="_blank"
                                        rel="noopener noreferrer"
                                        className="border border-border px-4 py-2 text-sm text-foreground/80 transition hover:bg-accent"
                                    >
                                        원본 보기
                                    </a>
                                ) : null}
                                <div className="flex flex-row gap-2">
                                    <Link
                                        href="/"
                                        className="border border-border px-4 py-2 text-sm text-foreground/70 transition hover:bg-accent w-full"
                                    >
                                        돌아가기
                                    </Link>
                                    {canManagePost ? (
                                        <Link
                                            href={`/edit/${post._id}`}
                                            className="border border-border bg-foreground px-4 py-2 text-sm text-background transition hover:opacity-90 w-full"
                                        >
                                            편집
                                        </Link>
                                    ) : null}
                                </div>
                                <DetailRawPanel data={post} />
                            </div>
                        </aside>
                    </div>
                </section>
            </main>
        </div>
    );
}
