"use client";

import { useEffect, useState } from "react";

import {
  Anchor,
  CreditCard,
  History,
  Package,
  Pencil,
  Ship,
  ToggleLeft,
  User,
  UserCog,
} from "lucide-react";

import { Badge } from "@/components/ui/badge";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { ScrollArea } from "@/components/ui/scroll-area";
import { getBookingActivities } from "@/lib/cruise-store";
import { cn, formatCurrency } from "@/lib/utils";
import type { BookingActivity, BookingActivityActor, BookingActivityType } from "@/types/cruise";

const actorConfig: Record<BookingActivityActor, { icon: typeof User; className: string }> = {
  admin: { icon: UserCog, className: "bg-violet-500/15 text-violet-700 dark:text-violet-300" },
  guest: { icon: User, className: "bg-sky-500/15 text-sky-700 dark:text-sky-300" },
  system: { icon: CreditCard, className: "bg-amber-500/15 text-amber-800 dark:text-amber-300" },
};

const typeConfig: Record<
  BookingActivityType,
  { icon: typeof Pencil; label: string; iconClass: string }
> = {
  booking_created: { icon: Ship, label: "Created", iconClass: "bg-emerald-500/15 text-emerald-700" },
  status_changed: { icon: ToggleLeft, label: "Status", iconClass: "bg-blue-500/15 text-blue-700" },
  cabin_changed: { icon: Anchor, label: "Cabin", iconClass: "bg-indigo-500/15 text-indigo-700" },
  addons_changed: { icon: Package, label: "Add-ons", iconClass: "bg-orange-500/15 text-orange-700" },
  payment_received: { icon: CreditCard, label: "Payment", iconClass: "bg-emerald-500/15 text-emerald-700" },
  payment_partial: { icon: CreditCard, label: "Partial pay", iconClass: "bg-amber-500/15 text-amber-800" },
  auto_pay_changed: { icon: ToggleLeft, label: "Auto-pay", iconClass: "bg-slate-500/15 text-slate-700" },
  cruise_line_updated: { icon: Ship, label: "Cruise line", iconClass: "bg-cyan-500/15 text-cyan-800" },
  admin_edit: { icon: Pencil, label: "Updated", iconClass: "bg-violet-500/15 text-violet-700" },
};

function formatWhen(iso: string) {
  const date = new Date(iso);
  const now = new Date();
  const sameDay =
    date.getFullYear() === now.getFullYear() &&
    date.getMonth() === now.getMonth() &&
    date.getDate() === now.getDate();

  if (sameDay) {
    return `Today, ${date.toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit" })}`;
  }

  return date.toLocaleString("en-US", {
    month: "short",
    day: "numeric",
    year: date.getFullYear() !== now.getFullYear() ? "numeric" : undefined,
    hour: "numeric",
    minute: "2-digit",
  });
}

function ActivityItem({ item, isLast }: { item: BookingActivity; isLast: boolean }) {
  const actor = actorConfig[item.actor];
  const ActorIcon = actor.icon;
  const meta = typeConfig[item.type];
  const TypeIcon = meta.icon;

  return (
    <li className="relative flex gap-3 pb-5 last:pb-0">
      {!isLast && <span aria-hidden className="absolute top-9 bottom-0 left-[15px] w-px bg-border" />}
      <div
        className={cn(
          "relative z-10 flex size-8 shrink-0 items-center justify-center rounded-full ring-2 ring-background",
          meta.iconClass,
        )}
      >
        <TypeIcon className="size-3.5" />
      </div>
      <div className="min-w-0 flex-1 rounded-lg border bg-card px-3 py-2.5 shadow-sm">
        <div className="flex flex-wrap items-center gap-x-2 gap-y-1">
          <Badge variant="secondary" className="h-5 px-1.5 text-[10px] font-medium">
            {meta.label}
          </Badge>
          <span className={cn("inline-flex items-center gap-1 rounded-full px-1.5 py-0.5 text-[10px]", actor.className)}>
            <ActorIcon className="size-3" />
            {item.actorName}
          </span>
          <span className="text-muted-foreground text-xs">{formatWhen(item.createdAt)}</span>
        </div>
        <p className="mt-1.5 text-sm leading-relaxed">{item.message}</p>
        {item.amount != null && item.amount > 0 && (
          <p className="mt-1 font-semibold text-sm tabular-nums">{formatCurrency(item.amount)}</p>
        )}
      </div>
    </li>
  );
}

interface BookingActivityTimelineProps {
  bookingId: string;
  refreshKey?: number;
}

export function BookingActivityTimeline({ bookingId, refreshKey = 0 }: BookingActivityTimelineProps) {
  const [activities, setActivities] = useState<BookingActivity[]>([]);

  useEffect(() => {
    setActivities(getBookingActivities(bookingId));
  }, [bookingId, refreshKey]);

  return (
    <Card className="flex flex-col lg:sticky lg:top-4 lg:max-h-[calc(100vh-6rem)]">
      <CardHeader className="shrink-0 pb-3">
        <CardTitle className="flex items-center gap-2 text-base">
          <History className="size-4 text-muted-foreground" />
          Activity log
        </CardTitle>
        <CardDescription>
          {activities.length} {activities.length === 1 ? "entry" : "entries"} — newest first
        </CardDescription>
      </CardHeader>
      <CardContent className="min-h-0 flex-1 pt-0">
        {activities.length === 0 ? (
          <div className="rounded-lg border border-dashed p-6 text-center">
            <History className="mx-auto mb-2 size-8 text-muted-foreground/50" />
            <p className="text-muted-foreground text-sm">No activity recorded yet.</p>
            <p className="mt-1 text-muted-foreground text-xs">Edits and payments will appear here.</p>
          </div>
        ) : (
          <ScrollArea className="h-[min(520px,calc(100vh-14rem))] pr-3">
            <ol className="relative pl-0.5">
              {activities.map((item, index) => (
                <ActivityItem key={item.id} item={item} isLast={index === activities.length - 1} />
              ))}
            </ol>
          </ScrollArea>
        )}
      </CardContent>
    </Card>
  );
}
