"use client";

import { useEffect, useMemo, useState } from "react";
import { Helmet } from "@/lib/helmet";
import { useNavigate, useParams } from "@/lib/router";
import { api } from "@/lib/api";
import type * as Types from "@/lib/types";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import GalleryLightbox, { type GalleryLightboxItem } from "@/components/GalleryLightbox";
import ProgressiveImage from "@/components/ProgressiveImage";
import { useToast } from "@/hooks/use-toast";
import Markdown from "@/components/Markdown";
import CouponDialogFa from "@/components/CouponDialogFa";
import {
  formatJalali,
  formatNumberPersian,
  formatToman,
  getEventCardImageUrl,
  getEventHeroImageUrl,
  getEventSeoImageUrl,
  getGalleryImageBlurUrl,
  getGalleryImageFullUrl,
  getGalleryImagePreviewUrl,
  resolveErrorMessage,
  toPersianDigits,
} from "@/lib/utils";
import { useAuth } from "@/contexts/AuthContext";
import { siteUrl } from "@/lib/site";

const typeLabel: Record<string, string> = {
  online: "آنلاین",
  on_site: "حضوری",
  hybrid: "آنلاین و حضوری",
};

type EventDetailProps = {
  initialEvent?: Types.EventDetailSchema | null;
};

function buildPaymentSnapshot(
  event: Types.EventDetailSchema,
  eventThumb: string | null,
  payload: {
    baseAmount: number;
    discountAmount: number;
    amount: number;
  },
) {
  return JSON.stringify({
    event_id: event.id,
    slug: event.slug,
    title: event.title,
    thumb: eventThumb,
    base_amount: payload.baseAmount,
    discount_amount: payload.discountAmount,
    amount: payload.amount,
    started_at: new Date().toISOString(),
    success_markdown: event.registration_success_markdown,
  });
}

export default function EventDetail({ initialEvent = null }: EventDetailProps) {
  const { slug } = useParams<{ slug: string }>();
  const { isAuthenticated } = useAuth();
  const navigate = useNavigate();
  const { toast } = useToast();

  const [event, setEvent] = useState<Types.EventDetailSchema | null>(initialEvent);
  const [eventThumb, setEventThumb] = useState<string | null>(
    initialEvent ? getEventCardImageUrl(initialEvent) : null,
  );
  const [lightboxIndex, setLightboxIndex] = useState<number | null>(null);
  const [loading, setLoading] = useState(!initialEvent);
  const [open, setOpen] = useState(false);
  const [submitting, setSubmitting] = useState(false);
  const [alreadyRegistered, setAlreadyRegistered] = useState(false);
  const [nowTs, setNowTs] = useState(() => Date.now());

  const basePrice = Number(event?.price ?? 0);
  const isFree = useMemo(() => basePrice <= 0, [basePrice]);
  const siteName = "انجمن علمی کامپیوتر شرق گیلان";
  const defaultDescription =
    "جزئیات کامل رویدادهای انجمن علمی کامپیوتر شرق گیلان شامل زمان، مکان و شرایط ثبت‌نام.";

  const toAbsoluteUrl = (value?: string | null) => {
    if (!value) return undefined;
    if (value.startsWith("http")) return value;
    const normalizedSite = siteUrl.endsWith("/") ? siteUrl.slice(0, -1) : siteUrl;
    const normalizedPath = value.startsWith("/") ? value.slice(1) : value;
    return `${normalizedSite}/${normalizedPath}`;
  };

  const sanitizeDescription = (value?: string | null) => {
    if (!value) return defaultDescription;
    const stripped = value.replace(/<[^>]*>/g, " ").replace(/\s+/g, " ").trim();
    if (!stripped) return defaultDescription;
    if (stripped.length <= 160) return stripped;
    return `${stripped.slice(0, 157)}...`;
  };

  const canonicalUrl = event ? `${siteUrl}/events/${event.slug}` : `${siteUrl}/events`;
  const primaryImage = event
    ? toAbsoluteUrl(getEventSeoImageUrl(event)) ?? `${siteUrl}/favicon.ico`
    : `${siteUrl}/favicon.ico`;
  const pageTitle = event ? `${event.title} | ${siteName}` : `جزئیات رویداد | ${siteName}`;
  const pageDescription = sanitizeDescription(event?.description);
  const pageRobots = event?.status === "draft" ? "noindex, nofollow" : "index, follow";

  useEffect(() => {
    let cancelled = false;

    async function checkRegistration() {
      if (!isAuthenticated || !event?.id) {
        return;
      }

      try {
        const res = await api.getRegistrationStatus(event.id);
        if (!cancelled) {
          setAlreadyRegistered(res.is_registered);
        }
      } catch {
        // Ignore registration status failures on the detail page.
      }
    }

    checkRegistration();
    return () => {
      cancelled = true;
    };
  }, [event?.id, isAuthenticated]);

  const goSuccess = (registrationId?: string) => {
    if (!event) return;
    const query = registrationId ? `?registration_id=${registrationId}` : "";
    setAlreadyRegistered(true);
    toast({ title: "ثبت‌نام با موفقیت انجام شد!", variant: "success" });
    navigate(`/events/${event.slug}/success${query}`);
  };

  const handleMainCTA = async () => {
    if (!event) return;

    if (!isAuthenticated) {
      toast({
        title: "ابتدا وارد شوید",
        description: "برای ثبت‌نام در رویداد باید وارد حساب کاربری خود شوید.",
        variant: "destructive",
      });
      navigate("/auth");
      return;
    }

    if (!isFree) {
      setOpen(true);
      return;
    }

    try {
      setSubmitting(true);
      const res = await api.registerForEvent(event.id);
      goSuccess(res.ticket_id);
    } catch (error: unknown) {
      const msg = resolveErrorMessage(error, "");
      if (msg.includes("already registered")) {
        setAlreadyRegistered(true);
        toast({ title: "شما قبلاً ثبت‌نام کرده‌اید", variant: "destructive" });
        return;
      }
      toast({
        title: "خطا در ثبت‌نام",
        description: msg || "لطفاً دوباره تلاش کنید.",
        variant: "destructive",
      });
    } finally {
      setSubmitting(false);
    }
  };

  const handleContinueFromModal = async (coupon?: string, finalAmount?: number) => {
    if (!event) return;

    if (!isAuthenticated) {
      toast({
        title: "ابتدا وارد شوید",
        description: "برای ثبت‌نام در رویداد باید وارد حساب کاربری خود شوید.",
        variant: "destructive",
      });
      navigate("/auth");
      return;
    }

    try {
      setSubmitting(true);
      const reg = await api.registerForEvent(event.id, coupon);

      if (finalAmount === 0) {
        window.sessionStorage.setItem(
          "payment:last",
          buildPaymentSnapshot(event, eventThumb, {
            baseAmount: Number(event.price ?? 0),
            discountAmount: Number(event.price ?? 0),
            amount: 0,
          }),
        );
        await api.ChangeRegistrationStatus(reg.id, "confirmed");
        goSuccess(reg.ticket_id);
        return;
      }

      const result = await api.createPayment({
        event_id: event.id,
        description: `پرداخت رویداد: ${event.title}`,
        discount_code: (coupon ?? "").trim() || null,
      });

      if (!result?.start_pay_url || Number(result.amount) === 0) {
        window.sessionStorage.setItem(
          "payment:last",
          buildPaymentSnapshot(event, eventThumb, {
            baseAmount: result.base_amount,
            discountAmount: result.discount_amount ?? result.base_amount,
            amount: 0,
          }),
        );
        goSuccess(reg.ticket_id);
        return;
      }

      window.sessionStorage.setItem(
        "payment:last",
        buildPaymentSnapshot(event, eventThumb, {
          baseAmount: result.base_amount,
          discountAmount: result.discount_amount,
          amount: result.amount,
        }),
      );
      window.location.href = result.start_pay_url;
    } catch (error: unknown) {
      const msg = resolveErrorMessage(error, "");
      if (msg.includes("already registered")) {
        setAlreadyRegistered(true);
        toast({ title: "شما قبلاً ثبت‌نام کرده‌اید", variant: "destructive" });
        return;
      }
      toast({
        title: "خطا در پردازش پرداخت",
        description: msg || "لطفاً دوباره تلاش کنید.",
        variant: "destructive",
      });
    } finally {
      setSubmitting(false);
      setOpen(false);
    }
  };

  useEffect(() => {
    let cancelled = false;

    async function loadEvent() {
      try {
        if (!slug) return;

        if (initialEvent && initialEvent.slug === slug) {
          setEvent(initialEvent);
          setEventThumb(getEventCardImageUrl(initialEvent));
          return;
        }

        const data = await api.getEventBySlug(slug);
        if (cancelled) return;
        setEvent(data);
        setEventThumb(getEventCardImageUrl(data));
      } catch (error: unknown) {
        if (cancelled) return;
        toast({
          title: "خطا در بارگذاری رویداد",
          description: resolveErrorMessage(error, "لطفاً دوباره تلاش کنید."),
          variant: "destructive",
        });
      } finally {
        if (!cancelled) {
          setLoading(false);
        }
      }
    }

    loadEvent();
    return () => {
      cancelled = true;
    };
  }, [initialEvent, slug, toast]);

  useEffect(() => {
    const timer = window.setInterval(() => setNowTs(Date.now()), 1000);
    return () => window.clearInterval(timer);
  }, []);

  const rsTs = useMemo<number | null>(
    () => (event?.registration_start_date ? new Date(event.registration_start_date).getTime() : null),
    [event?.registration_start_date],
  );

  const deadlineTs = useMemo<number | null>(
    () => (event?.registration_end_date ? new Date(event.registration_end_date).getTime() : null),
    [event?.registration_end_date],
  );

  const remainingMs = useMemo<number | null>(
    () => (deadlineTs != null ? Math.max(0, deadlineTs - nowTs) : null),
    [deadlineTs, nowTs],
  );

  const formatCountdownTwoDigit = (value: number) =>
    toPersianDigits(value.toString().padStart(2, "0"));
  const formatCountdownNumber = (value: number) => formatNumberPersian(value);

  const formatRemainingWords = (ms: number) => {
    const total = Math.max(0, Math.floor(ms / 1000));
    const days = Math.floor(total / 86400);
    const hours = Math.floor((total % 86400) / 3600);
    const minutes = Math.floor((total % 3600) / 60);
    const seconds = total % 60;

    if (days === 0) {
      return `${formatCountdownTwoDigit(hours)} ساعت و ${formatCountdownTwoDigit(minutes)} دقیقه و ${formatCountdownTwoDigit(seconds)} ثانیه`;
    }

    return `${formatCountdownNumber(days)} روز و ${formatCountdownTwoDigit(hours)} ساعت و ${formatCountdownTwoDigit(minutes)} دقیقه و ${formatCountdownTwoDigit(seconds)} ثانیه`;
  };

  const meta = useMemo(() => {
    if (!event) return null;
    const registrationOpen =
      (rsTs == null || nowTs >= rsTs) && (deadlineTs == null || nowTs <= deadlineTs);
    const unlimited = event.capacity == null;
    const remaining = unlimited
      ? Number.POSITIVE_INFINITY
      : Math.max(0, (event.capacity || 0) - (event.registration_count || 0));
    const full = !unlimited && remaining <= 0;
    return { registrationOpen, remaining, full };
  }, [deadlineTs, event, nowTs, rsTs]);

  const galleryItems = useMemo<GalleryLightboxItem[]>(
    () =>
      (event?.gallery_images ?? []).map((image) => ({
        id: image.id,
        alt: image.title || event?.title || "تصویر رویداد",
        title: image.title,
        previewSrc: getGalleryImagePreviewUrl(image),
        blurSrc: getGalleryImageBlurUrl(image),
        fullSrc: getGalleryImageFullUrl(image),
      })),
    [event],
  );

  const eventStructuredData = useMemo(() => {
    if (!event) return null;

    const attendanceModeMap: Record<string, string> = {
      online: "https://schema.org/OnlineEventAttendanceMode",
      on_site: "https://schema.org/OfflineEventAttendanceMode",
      hybrid: "https://schema.org/MixedEventAttendanceMode",
    };

    const statusMap: Record<string, string> = {
      published: "https://schema.org/EventScheduled",
      completed: "https://schema.org/EventCompleted",
      cancelled: "https://schema.org/EventCancelled",
      draft: "https://schema.org/EventPostponed",
    };

    const data: Record<string, unknown> = {
      "@context": "https://schema.org",
      "@type": "Event",
      name: event.title,
      description: pageDescription,
      startDate: event.start_time,
      url: canonicalUrl,
      eventAttendanceMode: attendanceModeMap[event.event_type] ?? attendanceModeMap.hybrid,
      eventStatus: statusMap[event.status] ?? statusMap.published,
      organizer: {
        "@type": "Organization",
        name: siteName,
        url: siteUrl,
      },
    };

    if (event.end_time) {
      data.endDate = event.end_time;
    }

    if (primaryImage) {
      data.image = [primaryImage];
    }

    if (event.event_type === "online") {
      data.location = {
        "@type": "VirtualLocation",
        url: event.online_link || canonicalUrl,
      };
    } else {
      const location: Record<string, unknown> = {
        "@type": "Place",
        name: event.location || event.address || siteName,
      };
      if (event.address) {
        location.address = event.address;
      }
      if (event.location) {
        location.description = event.location;
      }
      data.location = location;
    }

    const offers: Record<string, unknown> = {
      "@type": "Offer",
      url: canonicalUrl,
      priceCurrency: "IRR",
      price: String(event.price ?? 0),
      availability: meta?.full ? "https://schema.org/SoldOut" : "https://schema.org/InStock",
    };

    if (event.registration_start_date) {
      offers.validFrom = event.registration_start_date;
    }
    if (event.registration_end_date) {
      offers.validThrough = event.registration_end_date;
    }

    data.offers = offers;
    return data;
  }, [canonicalUrl, event, meta?.full, pageDescription, primaryImage, siteName]);

  const helmet = (
    <Helmet>
      <title>{pageTitle}</title>
      <meta name="description" content={pageDescription} />
      <meta name="robots" content={pageRobots} />
      <link rel="canonical" href={canonicalUrl} />
      <meta property="og:title" content={pageTitle} />
      <meta property="og:description" content={pageDescription} />
      <meta property="og:type" content="event" />
      <meta property="og:url" content={canonicalUrl} />
      <meta property="og:site_name" content={siteName} />
      <meta property="og:image" content={primaryImage} />
      <meta property="og:locale" content="fa_IR" />
      {event?.start_time && <meta property="event:start_time" content={event.start_time} />}
      {event?.end_time && <meta property="event:end_time" content={event.end_time} />}
      {event?.updated_at && <meta property="og:updated_time" content={event.updated_at} />}
      <meta name="twitter:card" content="summary_large_image" />
      <meta name="twitter:title" content={pageTitle} />
      <meta name="twitter:description" content={pageDescription} />
      <meta name="twitter:image" content={primaryImage} />
      {eventStructuredData && (
        <script type="application/ld+json">{JSON.stringify(eventStructuredData)}</script>
      )}
    </Helmet>
  );

  const withHelmet = (node: JSX.Element) => (
    <>
      {helmet}
      {node}
    </>
  );

  if (loading) {
    return withHelmet(
      <div className="min-h-[60vh] flex items-center justify-center text-muted-foreground">
        در حال بارگذاری رویداد...
      </div>,
    );
  }

  if (!event) {
    return withHelmet(
      <div className="min-h-[60vh] flex items-center justify-center">
        رویداد مورد نظر یافت نشد.
      </div>,
    );
  }

  const beforeStart = rsTs != null && nowTs < rsTs;
  const ended = deadlineTs !== null && remainingMs === 0;
  const showCountdown = !beforeStart && deadlineTs !== null && (remainingMs ?? 0) > 0;

  return withHelmet(
    <div className="container mx-auto px-4 py-8" dir="rtl">
      {beforeStart && (
        <div className="mb-6">
          <div className="rounded-xl border p-4 text-center bg-sky-50 text-sky-900 border-sky-200 dark:bg-sky-900/30 dark:text-sky-100 dark:border-sky-800">
            ثبت‌نام از <strong className="font-semibold">{formatJalali(event.registration_start_date!)}</strong> آغاز می‌شود.
          </div>
        </div>
      )}

      {showCountdown && remainingMs != null && (
        <div className="mb-6">
          <div className="rounded-xl border p-4 text-center bg-emerald-50 text-emerald-900 border-emerald-200 dark:bg-emerald-900/30 dark:text-emerald-100 dark:border-emerald-800">
            <div className="flex flex-col items-center gap-1 sm:flex-row sm:justify-center">
              <span>زمان باقی‌مانده تا پایان ثبت‌نام:</span>
              <strong className="font-extrabold tracking-wider sm:ms-1">
                {formatRemainingWords(remainingMs)}
              </strong>
            </div>
          </div>
        </div>
      )}

      {ended && (
        <div className="mb-6">
          <div className="rounded-xl border p-4 text-center bg-rose-50 text-rose-900 border-rose-200 dark:bg-rose-900/30 dark:text-rose-100 dark:border-rose-800">
            مهلت ثبت‌نام به پایان رسیده است.
          </div>
        </div>
      )}

      <div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
        <div className="lg:col-span-2">
          <Card className="overflow-hidden">
            <div className="w-full aspect-video overflow-hidden rounded-lg">
              <ProgressiveImage
                src={getEventHeroImageUrl(event)}
                blurSrc={event.absolute_featured_image_thumbnail_url}
                alt={event.title}
                wrapperClassName="h-full w-full"
                className="h-full w-full object-cover"
              />
            </div>

            <CardHeader>
              <div className="flex items-start justify-between gap-3">
                <div>
                  <CardTitle className="text-2xl">{event.title}</CardTitle>
                  <CardDescription className="mt-1">
                    {formatJalali(event.start_time)}
                    {event.end_time ? ` تا ${formatJalali(event.end_time)}` : null}
                  </CardDescription>
                </div>
                <div className="flex flex-col items-end gap-2">
                  <Badge variant="default">{typeLabel[event.event_type] || event.event_type}</Badge>
                </div>
              </div>
            </CardHeader>
            <CardContent>
              <Markdown content={event.description} justify size="base" />
            </CardContent>
          </Card>

          {galleryItems.length ? (
            <div className="mt-6">
              <h3 className="text-lg font-semibold mb-3">گالری تصاویر</h3>
              <div className="grid grid-cols-2 sm:grid-cols-3 gap-3">
                {galleryItems.map((image, index) => (
                  <button
                    key={image.id}
                    type="button"
                    className="overflow-hidden rounded-md text-right transition-transform hover:scale-[1.01] focus:outline-none focus:ring-2 focus:ring-primary/40"
                    onClick={() => setLightboxIndex(index)}
                  >
                    <ProgressiveImage
                      src={image.previewSrc}
                      blurSrc={image.blurSrc}
                      alt={image.alt}
                      wrapperClassName="h-36 w-full"
                      className="h-36 w-full object-cover"
                    />
                  </button>
                ))}
              </div>
            </div>
          ) : null}
        </div>

        <div className="lg:col-span-1">
          <div className="lg:sticky lg:top-24">
            <Card>
              <CardHeader>
                <CardTitle className="text-base">اطلاعات ثبت‌نام</CardTitle>
                <CardDescription>جزئیات دسترسی به رویداد</CardDescription>
              </CardHeader>
              <CardContent className="space-y-3 text-sm">
                {event.address && <div>آدرس: {event.address}</div>}
                <div>
                  ظرفیت کل: {event.capacity == null ? "نامحدود" : formatNumberPersian(event.capacity)}
                </div>
                {meta && event.capacity != null && (
                  <div>
                    ظرفیت باقی‌مانده:{" "}
                    {meta.remaining === Number.POSITIVE_INFINITY
                      ? "نامحدود"
                      : formatNumberPersian(meta.remaining)}
                  </div>
                )}
                <div>هزینه حضور: {event.price ? formatToman(event.price) : "رایگان"}</div>

                <Button
                  onClick={handleMainCTA}
                  className="w-full mt-2"
                  disabled={
                    submitting ||
                    alreadyRegistered ||
                    event.status !== "published" ||
                    meta?.full === true ||
                    !meta?.registrationOpen
                  }
                >
                  {event.status !== "published"
                    ? "ثبت‌نام این رویداد فعال نیست"
                    : alreadyRegistered
                    ? "شما قبلاً ثبت‌نام کرده‌اید"
                    : !meta?.registrationOpen
                    ? "ثبت‌نام هنوز آغاز نشده است"
                    : meta?.full
                    ? "ظرفیت ثبت‌نام تکمیل شده است"
                    : submitting
                    ? "در حال ثبت‌نام..."
                    : event.price === 0
                    ? "ثبت‌نام (رایگان)"
                    : "ثبت‌نام و ادامه پرداخت"}
                </Button>

                {!isFree && (
                  <CouponDialogFa
                    open={open}
                    onOpenChange={setOpen}
                    basePrice={basePrice}
                    onVerifyCouponRaw={(code) => api.checkDiscountCode(event.id, code)}
                    onContinue={handleContinueFromModal}
                  />
                )}
              </CardContent>
            </Card>
          </div>
        </div>
      </div>

      <GalleryLightbox
        items={galleryItems}
        open={lightboxIndex !== null}
        initialIndex={lightboxIndex ?? 0}
        onOpenChange={(isOpen) => {
          if (!isOpen) {
            setLightboxIndex(null);
          }
        }}
      />
    </div>
  );
}
