'use client';

import type { LeagueConfigFormModel } from '@/lib/types/LeagueConfigFormModel';
import { Heading } from '@/ui/Heading';
import { Icon } from '@/ui/Icon';
import { Stack } from '@/ui/Stack';
import { Text } from '@/ui/Text';
import { Check, HelpCircle, Trophy, Users, X } from 'lucide-react';
import type * as React from 'react';
import { useEffect, useRef, useState } from 'react';
import { createPortal } from 'react-dom';

// Minimum drivers for ranked leagues
const MIN_RANKED_DRIVERS = 10;

// ============================================================================
// INFO FLYOUT COMPONENT
// ============================================================================

interface InfoFlyoutProps {
  isOpen: boolean;
  onClose: () => void;
  title: string;
  children: React.ReactNode;
  anchorRef: React.RefObject<HTMLElement>;
}

function InfoFlyout({ isOpen, onClose, title, children, anchorRef }: InfoFlyoutProps) {
  const [position, setPosition] = useState({ top: 0, left: 0 });
  const [mounted, setMounted] = useState(false);
  const flyoutRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    setMounted(true);
  }, []);

  useEffect(() => {
    if (isOpen && anchorRef.current && mounted) {
      const rect = anchorRef.current.getBoundingClientRect();
      const flyoutWidth = Math.min(340, window.innerWidth - 40);
      const flyoutHeight = 350;
      const padding = 16;
      
      let left = rect.right + 12;
      let top = rect.top;
      
      if (left + flyoutWidth > window.innerWidth - padding) {
        left = rect.left - flyoutWidth - 12;
      }
      if (left < padding) {
        left = Math.max(padding, (window.innerWidth - flyoutWidth) / 2);
      }
      
      top = rect.top - flyoutHeight / 3;
      if (top + flyoutHeight > window.innerHeight - padding) {
        top = window.innerHeight - flyoutHeight - padding;
      }
      if (top < padding) top = padding;
      
      left = Math.max(padding, Math.min(left, window.innerWidth - flyoutWidth - padding));
      
      setPosition({ top, left });
    }
  }, [isOpen, anchorRef, mounted]);

  useEffect(() => {
    const handleEscape = (e: KeyboardEvent) => {
      if (e.key === 'Escape') onClose();
    };
    const handleClickOutside = (e: MouseEvent) => {
      if (flyoutRef.current && !flyoutRef.current.contains(e.target as Node)) {
        onClose();
      }
    };
    
    if (isOpen) {
      document.addEventListener('keydown', handleEscape);
      document.addEventListener('mousedown', handleClickOutside);
    }
    return () => {
      document.removeEventListener('keydown', handleEscape);
      document.removeEventListener('mousedown', handleClickOutside);
    };
  }, [isOpen, onClose]);

  if (!isOpen || !mounted) return null;

  return createPortal(
    <Stack
      ref={flyoutRef}
      position="fixed"
      zIndex={50}
      w="340px"
      bg="bg-iron-gray"
      border
      borderColor="border-charcoal-outline"
      rounded="xl"
      shadow="2xl"
      // eslint-disable-next-line gridpilot-rules/component-classification
      style={{ top: position.top, left: position.left, maxHeight: '80vh', overflowY: 'auto' }}
    >
      <Stack 
        display="flex" 
        alignItems="center" 
        justifyContent="between" 
        p={4} 
        borderBottom 
        borderColor="border-charcoal-outline/50" 
        position="sticky" 
        top="0" 
        bg="bg-iron-gray" 
        zIndex={10}
      >
        <Stack direction="row" align="center" gap={2}>
          <Icon icon={HelpCircle} size={4} color="text-primary-blue" />
          <Text size="sm" weight="semibold" color="text-white">{title}</Text>
        </Stack>
        <Stack
          as="button"
          type="button"
          onClick={onClose}
          display="flex"
          h="6"
          w="6"
          alignItems="center"
          justifyContent="center"
          rounded="md"
          transition
          hoverBg="bg-charcoal-outline"
        >
          <Icon icon={X} size={4} color="text-gray-400" />
        </Stack>
      </Stack>
      <Stack p={4}>
        {children}
      </Stack>
    </Stack>,
    document.body
  );
}

interface LeagueVisibilitySectionProps {
  form: LeagueConfigFormModel;
  onChange?: (form: LeagueConfigFormModel) => void;
  errors?: {
    visibility?: string;
  };
  readOnly?: boolean;
}

export function LeagueVisibilitySection({
  form,
  onChange,
  errors,
  readOnly,
}: LeagueVisibilitySectionProps) {
  const basics = form.basics;
  const disabled = readOnly || !onChange;

  // Flyout state
  const [showRankedFlyout, setShowRankedFlyout] = useState(false);
  const [showUnrankedFlyout, setShowUnrankedFlyout] = useState(false);
  const rankedInfoRef = useRef<HTMLButtonElement>(null!);
  const unrankedInfoRef = useRef<HTMLButtonElement>(null!);

  // Normalize visibility to new terminology
  const isRanked = basics.visibility === 'public';

  // Auto-update minDrivers when switching to ranked
  const handleVisibilityChange = (visibility: 'public' | 'private' | 'unlisted') => {
    if (!onChange) return;
    
    // If switching to public and current maxDrivers is below minimum, update it
    if (visibility === 'public' && (form.structure?.maxDrivers ?? 0) < MIN_RANKED_DRIVERS) {
      onChange({
        ...form,
        basics: { ...form.basics, visibility },
        structure: { ...form.structure, maxDrivers: MIN_RANKED_DRIVERS },
      });
    } else {
      onChange({
        ...form,
        basics: { ...form.basics, visibility },
      });
    }
  };

  return (
    <Stack gap={8}>
      {/* Emotional header for the step */}
      <Stack textAlign="center" pb={2}>
        <Heading level={3} mb={2}>
          Choose your league&apos;s destiny
        </Heading>
        <Text size="sm" color="text-gray-400" maxWidth="lg" mx="auto" block>
          Will you compete for glory on the global leaderboards, or race with friends in a private series?
        </Text>
      </Stack>

      {/* League Type Selection */}
      <Stack display="grid" responsiveGridCols={{ base: 1, md: 2 }} gap={6}>
        {/* Ranked (Public) Option */}
        <Stack position="relative">
          <Stack
            as="button"
            type="button"
            disabled={disabled}
            onClick={() => handleVisibilityChange('public')}
            display="flex"
            flexDirection="col"
            gap={4}
            p={6}
            textAlign="left"
            rounded="xl"
            border
            borderColor={isRanked ? 'border-primary-blue' : 'border-charcoal-outline'}
            bg={isRanked ? 'bg-primary-blue/15' : 'bg-iron-gray/30'}
            w="full"
            position="relative"
            transition
            shadow={isRanked ? '0_0_30px_rgba(25,140,255,0.25)' : undefined}
            hoverBorderColor={!isRanked && !disabled ? 'border-gray-500' : undefined}
            hoverBg={!isRanked && !disabled ? 'bg-iron-gray/50' : undefined}
            opacity={disabled ? 0.6 : 1}
            cursor={disabled ? 'not-allowed' : 'pointer'}
            group
          >
            {/* Header */}
            <Stack display="flex" alignItems="start" justifyContent="between">
              <Stack direction="row" align="center" gap={3}>
                <Stack 
                  display="flex" 
                  h="14" 
                  w="14" 
                  alignItems="center" 
                  justifyContent="center" 
                  rounded="xl" 
                  bg={isRanked ? 'bg-primary-blue/30' : 'bg-charcoal-outline/50'}
                >
                  <Icon icon={Trophy} size={7} color={isRanked ? 'text-primary-blue' : 'text-gray-400'} />
                </Stack>
                <Stack>
                  <Text weight="bold" size="xl" color={isRanked ? 'text-white' : 'text-gray-300'} block>
                    Ranked
                  </Text>
                  <Text size="sm" color={isRanked ? 'text-primary-blue' : 'text-gray-500'} block>
                    Compete for glory
                  </Text>
                </Stack>
              </Stack>
              {/* Radio indicator */}
              <Stack 
                display="flex" 
                h="7" 
                w="7" 
                alignItems="center" 
                justifyContent="center" 
                rounded="full" 
                border 
                borderColor={isRanked ? 'border-primary-blue' : 'border-gray-500'}
                bg={isRanked ? 'bg-primary-blue' : ''}
                flexShrink={0}
                transition
              >
                {isRanked && <Icon icon={Check} size={4} color="text-white" />}
              </Stack>
            </Stack>

            {/* Emotional tagline */}
            <Text size="sm" color={isRanked ? 'text-gray-300' : 'text-gray-500'} block>
              Your results matter. Build your reputation in the global standings and climb the ranks.
            </Text>

            {/* Features */}
            <Stack gap={2.5} py={2}>
              <Stack direction="row" align="center" gap={2}>
                <Icon icon={Check} size={4} color="text-performance-green" />
                <Text size="sm" color="text-gray-400">Discoverable by all drivers</Text>
              </Stack>
              <Stack direction="row" align="center" gap={2}>
                <Icon icon={Check} size={4} color="text-performance-green" />
                <Text size="sm" color="text-gray-400">Affects driver ratings & rankings</Text>
              </Stack>
              <Stack direction="row" align="center" gap={2}>
                <Icon icon={Check} size={4} color="text-performance-green" />
                <Text size="sm" color="text-gray-400">Featured on leaderboards</Text>
              </Stack>
            </Stack>

            {/* Requirement badge */}
            <Stack display="flex" alignItems="center" gap={2} mt="auto" px={3} py={2} rounded="lg" bg="bg-warning-amber/10" border borderColor="border-warning-amber/20" w="fit">
              <Icon icon={Users} size={4} color="text-warning-amber" />
              <Text size="xs" color="text-warning-amber" weight="medium">
                Requires {MIN_RANKED_DRIVERS}+ drivers for competitive integrity
              </Text>
            </Stack>
          </Stack>

          {/* Info button */}
          <Stack
            as="button"
            ref={rankedInfoRef}
            type="button"
            onClick={() => setShowRankedFlyout(true)}
            position="absolute"
            top="3"
            right="3"
            display="flex"
            h="7"
            w="7"
            alignItems="center"
            justifyContent="center"
            rounded="full"
            transition
            color="text-gray-500"
            hoverTextColor="text-primary-blue"
            hoverBg="bg-primary-blue/10"
          >
            <Icon icon={HelpCircle} size={4} />
          </Stack>
        </Stack>

        {/* Ranked Info Flyout */}
        <InfoFlyout
          isOpen={showRankedFlyout}
          onClose={() => setShowRankedFlyout(false)}
          title="Ranked Leagues"
          anchorRef={rankedInfoRef}
        >
          <Stack gap={4}>
            <Text size="xs" color="text-gray-400" block>
              Ranked leagues are competitive series where results matter. Your performance
              affects your driver rating and contributes to global leaderboards.
            </Text>
            
            <Stack gap={2}>
              <Text size="xs" weight="bold" color="text-gray-500" transform="uppercase" 
                // eslint-disable-next-line gridpilot-rules/component-classification
                className="tracking-wide" 
                block
              >
                Requirements
              </Text>
              <Stack gap={1.5}>
                <Stack display="flex" alignItems="start" gap={2}>
                  <Icon icon={Users} size={3.5} color="text-warning-amber" flexShrink={0} mt={0.5} />
                  <Text size="xs" color="text-gray-400">
                    <Text weight="bold" color="text-white">Minimum {MIN_RANKED_DRIVERS} drivers</Text> for competitive integrity
                  </Text>
                </Stack>
                <Stack display="flex" alignItems="start" gap={2}>
                  <Icon icon={Check} size={3.5} color="text-performance-green" flexShrink={0} mt={0.5} />
                  <Text size="xs" color="text-gray-400">Anyone can discover and join your league</Text>
                </Stack>
              </Stack>
            </Stack>

            <Stack gap={2}>
              <Text size="xs" weight="bold" color="text-gray-500" transform="uppercase" 
                // eslint-disable-next-line gridpilot-rules/component-classification
                className="tracking-wide" 
                block
              >
                Benefits
              </Text>
              <Stack gap={1.5}>
                <Stack display="flex" alignItems="start" gap={2}>
                  <Icon icon={Trophy} size={3.5} color="text-primary-blue" flexShrink={0} mt={0.5} />
                  <Text size="xs" color="text-gray-400">Results affect driver ratings and rankings</Text>
                </Stack>
                <Stack display="flex" alignItems="start" gap={2}>
                  <Icon icon={Check} size={3.5} color="text-performance-green" flexShrink={0} mt={0.5} />
                  <Text size="xs" color="text-gray-400">Featured in league discovery</Text>
                </Stack>
              </Stack>
            </Stack>
          </Stack>
        </InfoFlyout>

        {/* Unranked (Private) Option */}
        <Stack position="relative">
          <Stack
            as="button"
            type="button"
            disabled={disabled}
            onClick={() => handleVisibilityChange('private')}
            display="flex"
            flexDirection="col"
            gap={4}
            p={6}
            textAlign="left"
            rounded="xl"
            border
            borderColor={!isRanked ? 'border-neon-aqua' : 'border-charcoal-outline'}
            bg={!isRanked ? 'bg-neon-aqua/15' : 'bg-iron-gray/30'}
            w="full"
            position="relative"
            transition
            shadow={!isRanked ? '0_0_30px_rgba(67,201,230,0.2)' : undefined}
            hoverBorderColor={isRanked && !disabled ? 'border-gray-500' : undefined}
            hoverBg={isRanked && !disabled ? 'bg-iron-gray/50' : undefined}
            opacity={disabled ? 0.6 : 1}
            cursor={disabled ? 'not-allowed' : 'pointer'}
            group
          >
            {/* Header */}
            <Stack display="flex" alignItems="start" justifyContent="between">
              <Stack direction="row" align="center" gap={3}>
                <Stack 
                  display="flex" 
                  h="14" 
                  w="14" 
                  alignItems="center" 
                  justifyContent="center" 
                  rounded="xl" 
                  bg={!isRanked ? 'bg-neon-aqua/30' : 'bg-charcoal-outline/50'}
                >
                  <Icon icon={Users} size={7} color={!isRanked ? 'text-neon-aqua' : 'text-gray-400'} />
                </Stack>
                <Stack>
                  <Text weight="bold" size="xl" color={!isRanked ? 'text-white' : 'text-gray-300'} block>
                    Unranked
                  </Text>
                  <Text size="sm" color={!isRanked ? 'text-neon-aqua' : 'text-gray-500'} block>
                    Race with friends
                  </Text>
                </Stack>
              </Stack>
              {/* Radio indicator */}
              <Stack 
                display="flex" 
                h="7" 
                w="7" 
                alignItems="center" 
                justifyContent="center" 
                rounded="full" 
                border 
                borderColor={!isRanked ? 'border-neon-aqua' : 'border-gray-500'}
                bg={!isRanked ? 'bg-neon-aqua' : ''}
                flexShrink={0}
                transition
              >
                {!isRanked && <Icon icon={Check} size={4} color="text-deep-graphite" />}
              </Stack>
            </Stack>

            {/* Emotional tagline */}
            <Text size="sm" color={!isRanked ? 'text-gray-300' : 'text-gray-500'} block>
              Pure racing fun. No pressure, no rankings — just you and your crew hitting the track.
            </Text>

            {/* Features */}
            <Stack gap={2.5} py={2}>
              <Stack direction="row" align="center" gap={2}>
                <Icon icon={Check} size={4} color={!isRanked ? 'text-neon-aqua' : 'text-gray-400'} />
                <Text size="sm" color="text-gray-400">Private, invite-only access</Text>
              </Stack>
              <Stack direction="row" align="center" gap={2}>
                <Icon icon={Check} size={4} color={!isRanked ? 'text-neon-aqua' : 'text-gray-400'} />
                <Text size="sm" color="text-gray-400">Zero impact on your rating</Text>
              </Stack>
              <Stack direction="row" align="center" gap={2}>
                <Icon icon={Check} size={4} color={!isRanked ? 'text-neon-aqua' : 'text-gray-400'} />
                <Text size="sm" color="text-gray-400">Perfect for practice & fun</Text>
              </Stack>
            </Stack>

            {/* Flexibility badge */}
            <Stack display="flex" alignItems="center" gap={2} mt="auto" px={3} py={2} rounded="lg" bg="bg-neon-aqua/10" border borderColor="border-neon-aqua/20" w="fit">
              <Icon icon={Users} size={4} color={!isRanked ? 'text-neon-aqua' : 'text-gray-400'} />
              <Text size="xs" color={!isRanked ? 'text-neon-aqua' : 'text-gray-400'} weight="medium">
                Any size — even 2 friends
              </Text>
            </Stack>
          </Stack>

          {/* Info button */}
          <Stack
            as="button"
            ref={unrankedInfoRef}
            type="button"
            onClick={() => setShowUnrankedFlyout(true)}
            position="absolute"
            top="3"
            right="3"
            display="flex"
            h="7"
            w="7"
            alignItems="center"
            justifyContent="center"
            rounded="full"
            transition
            color="text-gray-500"
            hoverTextColor="text-neon-aqua"
            hoverBg="bg-neon-aqua/10"
          >
            <Icon icon={HelpCircle} size={4} />
          </Stack>
        </Stack>

        {/* Unranked Info Flyout */}
        <InfoFlyout
          isOpen={showUnrankedFlyout}
          onClose={() => setShowUnrankedFlyout(false)}
          title="Unranked Leagues"
          anchorRef={unrankedInfoRef}
        >
          <Stack gap={4}>
            <Text size="xs" color="text-gray-400" block>
              Unranked leagues are casual, private series for racing with friends.
              Results don&apos;t affect driver ratings, so you can practice and have fun
              without pressure.
            </Text>
            
            <Stack gap={2}>
              <Text size="xs" weight="bold" color="text-gray-500" transform="uppercase" 
                // eslint-disable-next-line gridpilot-rules/component-classification
                className="tracking-wide" 
                block
              >
                Perfect For
              </Text>
              <Stack gap={1.5}>
                <Stack display="flex" alignItems="start" gap={2}>
                  <Icon icon={Check} size={3.5} color="text-neon-aqua" flexShrink={0} mt={0.5} />
                  <Text size="xs" color="text-gray-400">Private racing with friends</Text>
                </Stack>
                <Stack display="flex" alignItems="start" gap={2}>
                  <Icon icon={Check} size={3.5} color="text-neon-aqua" flexShrink={0} mt={0.5} />
                  <Text size="xs" color="text-gray-400">Practice and training sessions</Text>
                </Stack>
                <Stack display="flex" alignItems="start" gap={2}>
                  <Icon icon={Check} size={3.5} color="text-neon-aqua" flexShrink={0} mt={0.5} />
                  <Text size="xs" color="text-gray-400">Small groups (2+ drivers)</Text>
                </Stack>
              </Stack>
            </Stack>

            <Stack gap={2}>
              <Text size="xs" weight="bold" color="text-gray-500" transform="uppercase" 
                // eslint-disable-next-line gridpilot-rules/component-classification
                className="tracking-wide" 
                block
              >
                Features
              </Text>
              <Stack gap={1.5}>
                <Stack display="flex" alignItems="start" gap={2}>
                  <Icon icon={Users} size={3.5} color="text-neon-aqua" flexShrink={0} mt={0.5} />
                  <Text size="xs" color="text-gray-400">Invite-only membership</Text>
                </Stack>
                <Stack display="flex" alignItems="start" gap={2}>
                  <Icon icon={Check} size={3.5} color="text-neon-aqua" flexShrink={0} mt={0.5} />
                  <Text size="xs" color="text-gray-400">Full stats and standings (internal only)</Text>
                </Stack>
              </Stack>
            </Stack>
          </Stack>
        </InfoFlyout>
      </Stack>

      {errors?.visibility && (
        <Stack display="flex" alignItems="center" gap={2} p={3} rounded="lg" bg="bg-warning-amber/10" border borderColor="border-warning-amber/20">
          <Icon icon={HelpCircle} size={4} color="text-warning-amber" flexShrink={0} />
          <Text size="xs" color="text-warning-amber">{errors.visibility}</Text>
        </Stack>
      )}

      {/* Contextual info based on selection */}
      <Stack 
        rounded="xl" 
        p={5} 
        border 
        transition 
        bg={isRanked ? 'bg-primary-blue/5' : 'bg-neon-aqua/5'}
        borderColor={isRanked ? 'border-primary-blue/20' : 'border-neon-aqua/20'}
      >
        <Stack display="flex" alignItems="start" gap={3}>
          {isRanked ? (
            <>
              <Icon icon={Trophy} size={5} color="text-primary-blue" flexShrink={0} mt={0.5} />
              <Stack>
                <Text size="sm" weight="medium" color="text-white" block mb={1}>Ready to compete</Text>
                <Text size="xs" color="text-gray-400" block>
                  Your league will be visible to all GridPilot drivers. Results will affect driver ratings
                  and contribute to the global leaderboards. Make sure you have at least {MIN_RANKED_DRIVERS} drivers
                  to ensure competitive integrity.
                </Text>
              </Stack>
            </>
          ) : (
            <>
              <Icon icon={Users} size={5} color="text-neon-aqua" flexShrink={0} mt={0.5} />
              <Stack>
                <Text size="sm" weight="medium" color="text-white" block mb={1}>Private racing awaits</Text>
                <Text size="xs" color="text-gray-400" block>
                  Your league will be invite-only. Perfect for racing with friends, practice sessions,
                  or any time you want to have fun without affecting your official ratings.
                </Text>
              </Stack>
            </>
          )}
        </Stack>
      </Stack>
    </Stack>
  );
}
