"use client";

import { useEffect, useMemo, useState } from "react";

import { ExternalLink, Loader2 } from "lucide-react";

import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Markdown } from "@/components/atoms/Markdown";
import {
  getForgejoIssue,
  type ForgejoIssue,
  type ForgejoIssueDetail,
} from "@/lib/api-forgejo";

type ForgejoIssueDetailDialogProps = {
  issue: ForgejoIssue | null;
  repositoryName: string;
  open: boolean;
  onOpenChange: (open: boolean) => void;
};

const formatDateTime = (value: string | null | undefined): string => {
  if (!value) return "—";
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return value;
  return date.toLocaleString(undefined, {
    dateStyle: "medium",
    timeStyle: "short",
  });
};

const objectList = (value: unknown): Record<string, unknown>[] => {
  if (!Array.isArray(value)) return [];
  return value.filter(
    (item): item is Record<string, unknown> =>
      typeof item === "object" && item !== null,
  );
};

const asString = (value: unknown): string | null =>
  typeof value === "string" && value.trim() ? value : null;

export function ForgejoIssueDetailDialog({
  issue,
  repositoryName,
  open,
  onOpenChange,
}: ForgejoIssueDetailDialogProps) {
  const [detail, setDetail] = useState<ForgejoIssueDetail | null>(null);
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    if (!open || !issue) return;
    let cancelled = false;
    (async () => {
      setIsLoading(true);
      setError(null);
      try {
        const result = await getForgejoIssue(issue.id);
        if (!cancelled) {
          setDetail(result);
        }
      } catch (err) {
        if (!cancelled) {
          setError(
            err instanceof Error
              ? err.message
              : "Could not load issue details from Pipeline.",
          );
        }
      } finally {
        if (!cancelled) {
          setIsLoading(false);
        }
      }
    })();
    return () => {
      cancelled = true;
    };
  }, [issue, open]);

  const comments = useMemo(
    () => objectList(detail?.forgejo_comments_payload),
    [detail?.forgejo_comments_payload],
  );
  const timeline = useMemo(
    () => objectList(detail?.forgejo_timeline_payload),
    [detail?.forgejo_timeline_payload],
  );
  const reactions = useMemo(
    () => objectList(detail?.forgejo_reactions_payload),
    [detail?.forgejo_reactions_payload],
  );

  if (!issue) return null;

  const active = detail ?? issue;
  const body = detail?.body ?? issue.body ?? issue.body_preview ?? "";
  const stateVariant = active.state === "open" ? "success" : "default";

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-4xl">
        <DialogHeader>
          <div className="flex flex-wrap items-start justify-between gap-3">
            <div className="space-y-2">
              <DialogTitle className="break-words text-base sm:text-lg">
                {active.title}
              </DialogTitle>
              <DialogDescription className="flex flex-wrap items-center gap-2 text-xs sm:text-sm">
                <span className="font-medium text-strong">
                  {repositoryName}
                </span>
                <span className="font-mono">
                  #{active.forgejo_issue_number}
                </span>
                <Badge variant={stateVariant}>{active.state}</Badge>
                <span>Opened {formatDateTime(active.forgejo_created_at)}</span>
                <span>Updated {formatDateTime(active.forgejo_updated_at)}</span>
              </DialogDescription>
            </div>
            <a
              href={active.html_url}
              target="_blank"
              rel="noopener noreferrer"
              className="inline-flex h-9 items-center gap-2 rounded-xl border border-[color:var(--border)] px-3 text-xs font-semibold text-muted transition hover:border-[color:var(--accent)] hover:text-[color:var(--accent)]"
            >
              Open in Forgejo
              <ExternalLink className="h-3.5 w-3.5" />
            </a>
          </div>
        </DialogHeader>

        {isLoading ? (
          <div className="flex items-center gap-2 rounded-xl border border-[color:var(--border)] bg-[color:var(--surface-muted)] p-4 text-sm text-muted">
            <Loader2 className="h-4 w-4 animate-spin text-[color:var(--accent)]" />
            Loading issue details…
          </div>
        ) : null}

        {error ? (
          <div className="rounded-xl border border-[color:rgba(248,113,113,0.35)] bg-[color:rgba(248,113,113,0.08)] p-3 text-sm text-[color:var(--danger)]">
            {error}
          </div>
        ) : null}

        <Tabs defaultValue="overview">
          <TabsList>
            <TabsTrigger value="overview">Overview</TabsTrigger>
            <TabsTrigger value="comments">
              Comments ({comments.length})
            </TabsTrigger>
            <TabsTrigger value="timeline">
              Timeline ({timeline.length})
            </TabsTrigger>
            <TabsTrigger value="reactions">
              Reactions ({reactions.length})
            </TabsTrigger>
          </TabsList>

          <TabsContent value="overview">
            <div className="rounded-xl border border-[color:var(--border)] bg-[color:var(--surface-muted)] p-4">
              {body ? (
                <Markdown content={body} variant="comment" />
              ) : (
                <p className="text-sm text-muted">No issue body provided.</p>
              )}
            </div>
          </TabsContent>

          <TabsContent value="comments">
            <div className="space-y-3">
              {comments.length === 0 ? (
                <div className="rounded-xl border border-[color:var(--border)] bg-[color:var(--surface-muted)] p-4 text-sm text-muted">
                  No comments on this issue.
                </div>
              ) : (
                comments.map((comment, idx) => {
                  const login =
                    asString(
                      comment.user &&
                        (comment.user as Record<string, unknown>).login,
                    ) ?? "Unknown";
                  const bodyText = asString(comment.body) ?? "";
                  return (
                    <article
                      key={String(comment.id ?? idx)}
                      className="rounded-xl border border-[color:var(--border)] bg-[color:var(--surface-muted)] p-4"
                    >
                      <div className="mb-2 flex flex-wrap items-center gap-2 text-xs text-muted">
                        <span className="font-medium text-strong">{login}</span>
                        <span>
                          {formatDateTime(asString(comment.created_at))}
                        </span>
                      </div>
                      {bodyText ? (
                        <Markdown content={bodyText} variant="comment" />
                      ) : (
                        <p className="text-sm text-muted">No comment text.</p>
                      )}
                    </article>
                  );
                })
              )}
            </div>
          </TabsContent>

          <TabsContent value="timeline">
            <div className="space-y-2">
              {timeline.length === 0 ? (
                <div className="rounded-xl border border-[color:var(--border)] bg-[color:var(--surface-muted)] p-4 text-sm text-muted">
                  No timeline events found.
                </div>
              ) : (
                timeline.map((event, idx) => {
                  const label =
                    asString(event.type) ??
                    asString(event.action) ??
                    asString(event.event) ??
                    "event";
                  const actor =
                    asString(
                      event.user &&
                        (event.user as Record<string, unknown>).login,
                    ) ?? "system";
                  return (
                    <div
                      key={String(event.id ?? idx)}
                      className="rounded-lg border border-[color:var(--border)] bg-[color:var(--surface-muted)] px-3 py-2 text-sm"
                    >
                      <span className="font-medium text-strong">{label}</span>{" "}
                      <span className="text-muted">by {actor}</span>
                      <span className="ml-2 text-xs text-muted">
                        {formatDateTime(asString(event.created_at))}
                      </span>
                    </div>
                  );
                })
              )}
            </div>
          </TabsContent>

          <TabsContent value="reactions">
            <div className="space-y-2">
              {reactions.length === 0 ? (
                <div className="rounded-xl border border-[color:var(--border)] bg-[color:var(--surface-muted)] p-4 text-sm text-muted">
                  No reactions on this issue.
                </div>
              ) : (
                reactions.map((reaction, idx) => {
                  const content = asString(reaction.content) ?? "reaction";
                  const login =
                    asString(
                      reaction.user &&
                        (reaction.user as Record<string, unknown>).login,
                    ) ?? "Unknown";
                  return (
                    <div
                      key={String(reaction.id ?? idx)}
                      className="flex items-center justify-between rounded-lg border border-[color:var(--border)] bg-[color:var(--surface-muted)] px-3 py-2 text-sm"
                    >
                      <span className="font-medium text-strong">{content}</span>
                      <span className="text-xs text-muted">{login}</span>
                    </div>
                  );
                })
              )}
            </div>
          </TabsContent>
        </Tabs>

        <div className="flex justify-end">
          <Button variant="outline" onClick={() => onOpenChange(false)}>
            Close
          </Button>
        </div>
      </DialogContent>
    </Dialog>
  );
}
