import { css, keyframes } from '@emotion/react';
import { useState } from 'react';
import { adaptive } from '../styles/adaptive';
import elementsData from '../data/elements.json';
import { useGameStore } from '../store/useGameStore';
import { trackGameEvent } from '../platform/analytics';
import { showRewardedAd } from '../platform/ads';
import type { OfflineReward } from '../store/useGameStore';

function formatDuration(seconds: number): string {
  if (seconds >= 3600) {
    const h = Math.floor(seconds / 3600);
    const m = Math.floor((seconds % 3600) / 60);
    return `${h}시간 ${m}분`;
  }
  if (seconds >= 60) {
    return `${Math.floor(seconds / 60)}분`;
  }
  return `${seconds}초`;
}

const starTwinkle = keyframes`
  from { opacity: 0.3; transform: scale(0.8); }
  to   { opacity: 1.0; transform: scale(1.2); }
`;

const shimmer = keyframes`
  0%   { transform: translateX(-150%) rotate(25deg); }
  100% { transform: translateX(150%) rotate(25deg); }
`;

const overlayStyle = css`
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.6);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 2000;
  padding: 20px;
`;

const modalStyle = css`
  background: ${adaptive.background};
  border-radius: 24px;
  padding: 28px 24px 24px;
  width: 100%;
  max-width: 340px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.22);
  background-image: radial-gradient(
    circle at 50% 0%,
    rgba(124, 77, 255, 0.07) 0%,
    transparent 60%
  );
`;

const headerStyle = css`
  text-align: center;
  margin-bottom: 20px;
  position: relative;
`;

const closeButtonStyle = css`
  position: absolute;
  top: 0;
  right: 0;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: ${adaptive.greyBackground};
  border: none;
  border-radius: 50%;
  font-size: 16px;
  color: ${adaptive.grey500};
  cursor: pointer;
  line-height: 1;
  &:active { transform: scale(0.92); }
`;

const moonIconStyle = css`
  font-size: 48px;
  line-height: 1;
  display: block;
  margin-bottom: 10px;
  position: relative;

  &::before {
    content: '✦';
    position: absolute;
    font-size: 13px;
    color: #FFD700;
    top: 2px;
    left: 22%;
    animation: ${starTwinkle} 2s ease-in-out infinite alternate;
  }
  &::after {
    content: '✦';
    position: absolute;
    font-size: 10px;
    color: #FFD700;
    top: 8px;
    right: 18%;
    animation: ${starTwinkle} 2s ease-in-out infinite alternate;
    animation-delay: 0.7s;
  }
`;

const titleStyle = css`
  font-size: 18px;
  font-weight: 800;
  color: ${adaptive.grey900};
  margin: 0 0 6px;
  text-align: center;
`;

const subtitleStyle = css`
  font-size: 13px;
  color: ${adaptive.grey500};
  text-align: center;
  margin: 0;
  line-height: 1.5;
`;

const rewardListStyle = css`
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 20px;
  max-height: 240px;
  overflow-y: auto;
`;

const rewardItemStyle = css`
  display: flex;
  align-items: center;
  gap: 10px;
  background: ${adaptive.greyBackground};
  border-radius: 12px;
  padding: 10px 14px;
`;

const rewardEmojiStyle = css`
  font-size: 22px;
`;

const rewardNameStyle = css`
  flex: 1;
  font-size: 14px;
  font-weight: 600;
  color: ${adaptive.grey900};
`;

const rewardCountStyle = css`
  font-size: 14px;
  font-weight: 700;
  color: ${adaptive.blue500};
`;

const goldRowStyle = css`
  display: flex;
  align-items: center;
  gap: 10px;
  background: linear-gradient(135deg, #fff8e1, #fff3cd);
  border-radius: 12px;
  padding: 10px 14px;
  margin-bottom: 20px;
`;

const claimButtonStyle = css`
  width: 100%;
  padding: 15px;
  background: linear-gradient(135deg, #3182f6, #7c4dff);
  color: white;
  border: none;
  border-radius: 16px;
  font-size: 16px;
  font-weight: 700;
  cursor: pointer;
  position: relative;
  overflow: hidden;

  &::after {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 60%;
    height: 100%;
    background: linear-gradient(
      90deg,
      transparent,
      rgba(255, 255, 255, 0.2),
      transparent
    );
    animation: ${shimmer} 2.8s ease-in-out infinite;
    pointer-events: none;
  }

  &:active {
    transform: scale(0.97);
  }

  &:disabled {
    cursor: wait;
    opacity: 0.72;
  }
`;

const doubleButtonStyle = css`
  width: 100%;
  padding: 13px;
  background: #101828;
  color: white;
  border: none;
  border-radius: 14px;
  font-size: 14px;
  font-weight: 800;
  cursor: pointer;
  margin-bottom: 10px;

  &:active {
    transform: scale(0.97);
  }

  &:disabled {
    cursor: wait;
    opacity: 0.72;
  }
`;

export function OfflineRewardModal() {
  const pendingOfflineReward = useGameStore((s) => s.pendingOfflineReward);
  const claimOfflineReward = useGameStore((s) => s.claimOfflineReward);
  const set = useGameStore.setState;
  const [isClaiming, setIsClaiming] = useState(false);

  if (!pendingOfflineReward) return null;

  const trackClaim = (reward: OfflineReward, multiplier: number) => {
    try {
      trackGameEvent('offline_reward_claimed', {
        offline_sec: reward.offlineSec,
        gold_reward: reward.gold * multiplier,
        multiplier,
        element_types_count: Object.values(reward.elements).filter((c) => c > 0).length,
      });
    } catch (error) {
      console.warn('Failed to track offline reward claim', error);
    }
  };

  const claimReward = (reward: OfflineReward, multiplier = 1) => {
    claimOfflineReward(multiplier);
    trackClaim(reward, multiplier);
  };

  const handleClaim = (multiplier = 1) => {
    if (isClaiming) return;
    setIsClaiming(true);
    claimReward(pendingOfflineReward, multiplier);
  };

  const handleDoubleClaim = async () => {
    if (isClaiming) return;
    setIsClaiming(true);

    try {
      const result = await showRewardedAd();
      if (result.rewarded) {
        claimReward(pendingOfflineReward, 2);
        return;
      }
    } catch (error) {
      console.warn('Failed to show rewarded ad', error);
    }

    setIsClaiming(false);
  };

  const elementRewards = Object.entries(pendingOfflineReward.elements)
    .filter(([, count]) => count > 0)
    .map(([id, count]) => {
      const el = elementsData.find((e) => e.id === id);
      return { id, count, emoji: el?.emoji ?? '?', name: el?.name ?? id };
    });

  const hasRewards = elementRewards.length > 0 || pendingOfflineReward.gold > 0;

  return (
    <div css={overlayStyle}>
      <div css={modalStyle}>
        <div css={headerStyle}>
          <button css={closeButtonStyle} onClick={() => set({ pendingOfflineReward: null })} aria-label="닫기">✕</button>
          <span css={moonIconStyle}>🌙</span>
          <h2 css={titleStyle}>오프라인 보상</h2>
          <p css={subtitleStyle}>
            {formatDuration(pendingOfflineReward.offlineSec)} 동안<br />
            원소가 자동 수집되었습니다!
          </p>
        </div>

        {hasRewards ? (
          <>
            <div css={rewardListStyle}>
              {elementRewards.map(({ id, count, emoji, name }) => (
                <div key={id} css={rewardItemStyle}>
                  <span css={rewardEmojiStyle}>{emoji}</span>
                  <span css={rewardNameStyle}>{name}</span>
                  <span css={rewardCountStyle}>+{count}</span>
                </div>
              ))}
            </div>
            {pendingOfflineReward.gold > 0 && (
              <div css={goldRowStyle}>
                <span css={rewardEmojiStyle}>💰</span>
                <span css={rewardNameStyle}>골드</span>
                <span css={rewardCountStyle}>+{pendingOfflineReward.gold}</span>
              </div>
            )}
          </>
        ) : (
          <p css={subtitleStyle}>아직 수집된 원소가 없습니다.</p>
        )}

        {hasRewards && (
          <button css={doubleButtonStyle} onClick={handleDoubleClaim} disabled={isClaiming}>
            {isClaiming ? '처리 중...' : '광고 보고 2배 수령'}
          </button>
        )}
        <button css={claimButtonStyle} onClick={() => handleClaim()} disabled={isClaiming}>
          {isClaiming ? '처리 중...' : '수령하기'}
        </button>
      </div>
    </div>
  );
}
