'use client';

import React, { useEffect, useMemo, useRef, useState } from 'react';
import { twMerge } from 'tailwind-merge';

import Button, {
  ButtonShape,
  ButtonSize,
  ButtonVariant,
} from '@/components/button/Button';
import DiscoverSongCard from '@/components/carousel/carouselCards/DiscoverSongCard';
import {
  TimeLeft,
  formatTimeLeftCompact,
  getTimeLeft,
  redirectToRemixFromClipId,
} from '@/components/contest/util';
import Link from '@/components/link/Link';
import { useBreakpointMd } from '@/hooks/useBreakpoint';
import { ContestSchema } from '@/hooks/useContestClip';
import { PlayIcon, RemixIcon } from '@/icons/generated';
import { ContextType } from '@/logging/contextTypes';
import logWebUserEvent from '@/logging/logWebUserEvent';
import { Clip, ClipEntity } from '@/state/clipStore';

type ContestHeroProps = {
  contest: ContestSchema;
  contestClip: Clip | null;
  heroBackgroundImage?: string;
  heroBackgroundVideo?: string;
  videoPosterImage?: string;
  remixCount?: number;
  start?: string;
  end?: string;
  title?: string;
  description?: string;
  showRemixCount?: boolean;
  remixLabel?: string;
  gradientClassName?: string;
  titleClassName?: string;
  contestLabel?: string;
  primaryCTA?: React.ReactNode;
  secondaryCTA?: React.ReactNode;
};

const ContestHero: React.FC<ContestHeroProps> = ({
  contest,
  contestClip,
  heroBackgroundImage,
  heroBackgroundVideo,
  videoPosterImage,
  start,
  end,
  title,
  description,
  showRemixCount = false,
  remixLabel,
  gradientClassName,
  titleClassName,
  contestLabel = 'Remix Contest',
  primaryCTA,
  secondaryCTA,
}) => {
  const isTablet = useBreakpointMd();
  const isMobile = !isTablet;
  const videoRef = useRef<HTMLVideoElement | null>(null);

  const startMs = useMemo(
    () => (start ? Date.parse(start) : undefined),
    [start]
  );
  const endMs = useMemo(() => (end ? Date.parse(end) : undefined), [end]);

  const submissionsActive = useMemo(() => {
    if (startMs == null || endMs == null) return false;
    const now = Date.now();
    return now >= startMs && now <= endMs;
  }, [startMs, endMs]);

  const isBeforeSubmissions = useMemo(() => {
    if (startMs == null) return false;
    return Date.now() < startMs;
  }, [startMs]);

  const [timeLeft, setTimeLeft] = useState<TimeLeft | null>(() => {
    const target = isBeforeSubmissions
      ? startMs
      : submissionsActive
        ? endMs
        : undefined;
    if (target == null) return null;
    return getTimeLeft(target - Date.now());
  });

  useEffect(() => {
    const target = isBeforeSubmissions ? startMs : endMs;
    if ((!isBeforeSubmissions && !submissionsActive) || target == null) return;
    setTimeLeft(getTimeLeft(target - Date.now()));
    const id = setInterval(() => {
      setTimeLeft(getTimeLeft(target - Date.now()));
    }, 1000);
    return () => clearInterval(id);
  }, [isBeforeSubmissions, submissionsActive, startMs, endMs]);

  // Ensure autoplay on iOS and first-load SSR cases by attempting play
  useEffect(() => {
    const el = videoRef.current;
    if (!el || !heroBackgroundVideo) return;

    // Satisfy iOS inline autoplay requirements
    el.muted = true;
    el.defaultMuted = true;
    el.playsInline = true;
    el.setAttribute('muted', '');
    el.setAttribute('playsinline', '');
    el.setAttribute('webkit-playsinline', 'true');

    const attempt = () => {
      if (!el) return;
      const isPlaying =
        el.currentTime > 0 && !el.paused && !el.ended && el.readyState > 2;
      if (isPlaying) return;
      const p = el.play();
      if (p && typeof (p as Promise<void>).then === 'function') {
        (p as Promise<void>).catch(() => {
          // Ignore failures; some environments may still block autoplay
        });
      }
    };

    if (el.readyState >= 2) {
      attempt();
    }

    const onCanPlay = () => attempt();
    const onLoadedData = () => attempt();
    const onLoadedMetadata = () => attempt();

    el.addEventListener('canplay', onCanPlay);
    el.addEventListener('loadeddata', onLoadedData);
    el.addEventListener('loadedmetadata', onLoadedMetadata);

    // In some SSR hydration scenarios, forcing a load cycle helps kick off autoplay
    try {
      el.load();
    } catch {}

    return () => {
      el.removeEventListener('canplay', onCanPlay);
      el.removeEventListener('loadeddata', onLoadedData);
      el.removeEventListener('loadedmetadata', onLoadedMetadata);
    };
  }, [heroBackgroundVideo]);

  return (
    <div
      className='relative h-screen pt-[300px] md:pt-0'
      style={
        heroBackgroundVideo
          ? {}
          : {
              backgroundImage: heroBackgroundImage
                ? `url(${heroBackgroundImage})`
                : undefined,
              backgroundSize: 'cover',
              backgroundPosition: 'center',
            }
      }
    >
      <div
        className={twMerge(
          'pointer-events-none absolute inset-x-0 bottom-0 z-[1] h-1/2 bg-gradient-to-t from-background-primary to-transparent md:h-[250px]',
          gradientClassName
        )}
      />

      {heroBackgroundVideo && (
        <video
          ref={videoRef}
          key={heroBackgroundVideo}
          className='pointer-events-none absolute inset-0 h-full w-full object-cover'
          autoPlay
          muted
          loop
          playsInline
          preload='auto'
          disablePictureInPicture
          poster={videoPosterImage}
        >
          <source src={heroBackgroundVideo} />
        </video>
      )}
      <div className='relative z-[1] mx-auto flex h-full w-full max-w-[2560px] items-end justify-center px-[20px] pb-[100px] md:pb-12'>
        <div className='flex w-full flex-col-reverse items-center justify-center text-center md:flex-row md:items-end md:justify-between md:text-left'>
          <div>
            <div>
              <div
                className='mb-[24px] inline-block rounded-full px-[12px] py-[8px] text-[12px] leading-[16px] font-medium uppercase'
                style={{
                  backgroundColor: 'var(--Accent-Yellow, #F5D907)',
                  color: '#000000',
                }}
              >
                {contestLabel}
              </div>
            </div>
            <div
              className={twMerge(
                'max-w-[650px] text-[30px] leading-[30px] font-medium tracking-[-0.6px] whitespace-pre-line text-white not-italic md:text-[60px] md:leading-[60px] md:tracking-[-0.42px]',
                titleClassName
              )}
            >
              {title}
            </div>
            <div className='mt-2 max-w-[400px] text-[14px] leading-[20px] font-normal text-[rgba(255,255,255,0.5)] not-italic'>
              {description}
            </div>
            <div className='mt-[24px] flex flex-row justify-center gap-[12px] md:justify-start'>
              {primaryCTA ? (
                primaryCTA
              ) : contestClip?.id ? (
                <Button
                  variant={ButtonVariant.Aura}
                  size={ButtonSize.Large}
                  icon={RemixIcon}
                  shape={ButtonShape.Pill}
                  style={{ padding: '10px 15px' }}
                  onClick={() => {
                    logWebUserEvent({
                      actionName: 'ContestLandingRemixCtaClicked',
                      context: {
                        contestId: contest.id,
                        contestSlug: contest.slug ?? undefined,
                        source: 'hero',
                        clipId: contestClip?.id,
                      },
                    });
                    // Use imperative redirect to aid iOS deep-linking
                    redirectToRemixFromClipId(contestClip?.id);
                  }}
                >
                  Remix
                </Button>
              ) : null}
              {secondaryCTA ? secondaryCTA : <></>}
              {showRemixCount && (
                <Link
                  href={`/playlist/${contest.submissions_playlist_id}`}
                  target='_blank'
                  rel='noopener noreferrer'
                >
                  <Button
                    variant={ButtonVariant.Secondary}
                    size={ButtonSize.Large}
                    icon={PlayIcon}
                    shape={ButtonShape.Pill}
                    style={{ padding: '10px 20px', paddingLeft: '17px' }}
                    onClick={() => {
                      if (contest.id) {
                        logWebUserEvent({
                          actionName: 'ContestLandingRemixPlaylistClicked',
                          context: {
                            contestId: contest.id,
                            contestSlug: contest.slug ?? undefined,
                            source: 'hero',
                            clipId: contestClip?.id,
                          },
                        });
                      }
                    }}
                  >
                    {remixLabel}
                  </Button>
                </Link>
              )}

              {(isBeforeSubmissions || submissionsActive) &&
                timeLeft &&
                !isMobile && (
                  <Button
                    variant={ButtonVariant.Secondary}
                    size={ButtonSize.Large}
                    shape={ButtonShape.Pill}
                    style={{ padding: '10px 12px' }}
                  >
                    {formatTimeLeftCompact(timeLeft)}
                  </Button>
                )}
            </div>
          </div>

          <div className='mb-[24px] md:mb-0'>
            {contestClip && (
              <DiscoverSongCard
                clip={{
                  ...(contestClip as unknown as ClipEntity),
                  imageUrl: contestClip?.image_url,
                }}
                index={0}
                className='h-[132px] w-[132px] md:h-[207px] md:w-[207px]'
                contextType={ContextType.Contest}
                contextId={contest.id}
                contestCard={true}
              />
            )}
          </div>
        </div>
      </div>
    </div>
  );
};

export default ContestHero;
