'use client';

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

// ============================================================================
// INFO FLYOUT (duplicated for self-contained 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(380, window.innerWidth - 40);
      const flyoutHeight = 450;
      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) return null;

  return createPortal(
    <Stack
      ref={flyoutRef}
      position="fixed"
      zIndex={50}
      w="380px"
      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
  );
}

function InfoButton({ onClick, buttonRef }: { onClick: () => void; buttonRef: React.Ref<HTMLButtonElement> }) {
  return (
    <Stack
      as="button"
      ref={buttonRef}
      type="button"
      onClick={onClick}
      display="flex"
      h="5"
      w="5"
      alignItems="center"
      justifyContent="center"
      rounded="full"
      transition
      color="text-gray-500"
      hoverTextColor="text-primary-blue"
      hoverBg="bg-primary-blue/10"
    >
      <Icon icon={HelpCircle} size={3.5} />
    </Stack>
  );
}

// Drop Rules Mockup
function DropRulesMockup() {
  const results = [
    { round: 'R1', pts: 25, dropped: false },
    { round: 'R2', pts: 18, dropped: false },
    { round: 'R3', pts: 4, dropped: true },
    { round: 'R4', pts: 15, dropped: false },
    { round: 'R5', pts: 12, dropped: false },
    { round: 'R6', pts: 0, dropped: true },
  ];

  const total = results.filter(r => !r.dropped).reduce((sum, r) => sum + r.pts, 0);
  const wouldBe = results.reduce((sum, r) => sum + r.pts, 0);

  return (
    <Stack bg="bg-deep-graphite" rounded="lg" p={4}>
      <Stack display="flex" alignItems="center" gap={2} mb={3} pb={2} borderBottom borderColor="border-charcoal-outline/50" opacity={0.5}>
        <Text size="xs" weight="semibold" color="text-white">Best 4 of 6 Results</Text>
      </Stack>
      <Stack display="flex" gap={1} mb={3}>
        {results.map((r, i) => (
          <Stack
            key={i}
            flexGrow={1}
            p={2}
            rounded="lg"
            textAlign="center"
            border
            transition
            bg={r.dropped ? 'bg-charcoal-outline/20' : 'bg-performance-green/10'}
            borderColor={r.dropped ? 'border-charcoal-outline/50' : 'border-performance-green/30'}
            opacity={r.dropped ? 0.5 : 1}
            // eslint-disable-next-line gridpilot-rules/component-classification
            className={r.dropped ? 'border-dashed' : ''}
          >
            <Text 
              // eslint-disable-next-line gridpilot-rules/component-classification
              style={{ fontSize: '9px' }} 
              color="text-gray-500" 
              block
            >
              {r.round}
            </Text>
            <Text font="mono" weight="semibold" size="xs" color={r.dropped ? 'text-gray-500' : 'text-white'} 
              // eslint-disable-next-line gridpilot-rules/component-classification
              className={r.dropped ? 'line-through' : ''} 
              block
            >
              {r.pts}
            </Text>
          </Stack>
        ))}
      </Stack>
      <Stack display="flex" justifyContent="between" alignItems="center">
        <Text size="xs" color="text-gray-500">Total counted:</Text>
        <Text font="mono" weight="semibold" color="text-performance-green" size="xs">{total} pts</Text>
      </Stack>
      <Stack display="flex" justifyContent="between" alignItems="center" mt={1}>
        <Text 
          // eslint-disable-next-line gridpilot-rules/component-classification
          style={{ fontSize: '10px' }} 
          color="text-gray-500"
        >
          Without drops:
        </Text>
        <Text font="mono" 
          // eslint-disable-next-line gridpilot-rules/component-classification
          style={{ fontSize: '10px' }} 
          color="text-gray-500"
        >
          {wouldBe} pts
        </Text>
      </Stack>
    </Stack>
  );
}

interface LeagueDropSectionProps {
  form: LeagueConfigFormModel;
  onChange?: (form: LeagueConfigFormModel) => void;
  readOnly?: boolean;
}

type DropStrategy = 'none' | 'bestNResults' | 'dropWorstN';

// Drop rule info content
const DROP_RULE_INFO: Record<DropStrategy, { title: string; description: string; details: string[]; example: string }> = {
  none: {
    title: 'All Results Count',
    description: 'Every race result affects the championship standings with no exceptions.',
    details: [
      'All race results count toward final standings',
      'No safety net for bad races or DNFs',
      'Rewards consistency across entire season',
      'Best for shorter seasons (4-6 races)',
    ],
    example: '8 races × your points = your total',
  },
  bestNResults: {
    title: 'Best N Results',
    description: 'Only your top N race results count toward the championship.',
    details: [
      'Choose how many of your best races count',
      'Extra races become "bonus" opportunities',
      'Protects against occasional bad days',
      'Encourages trying even when behind',
    ],
    example: 'Best 6 of 8 races count',
  },
  dropWorstN: {
    title: 'Drop Worst N Results',
    description: 'Your N worst race results are excluded from championship calculations.',
    details: [
      'Automatically removes your worst performances',
      'Great for handling DNFs or incidents',
      'All other races count normally',
      'Common in real-world championships',
    ],
    example: 'Drop 2 worst → 6 of 8 count',
  },
};

const DROP_OPTIONS: Array<{
  value: DropStrategy;
  label: string;
  emoji: string;
  description: string;
  defaultN?: number;
}> = [
  {
    value: 'none',
    label: 'All count',
    emoji: '✓',
    description: 'Every race counts',
  },
  {
    value: 'bestNResults',
    label: 'Best N',
    emoji: '🏆',
    description: 'Only best results',
    defaultN: 6,
  },
  {
    value: 'dropWorstN',
    label: 'Drop worst',
    emoji: '🗑️',
    description: 'Exclude worst races',
    defaultN: 2,
  },
];

export function LeagueDropSection({
  form,
  onChange,
  readOnly,
}: LeagueDropSectionProps) {
  const disabled = readOnly || !onChange;
  const dropPolicy = form.dropPolicy || { strategy: 'none' as const };
  const [showDropFlyout, setShowDropFlyout] = useState(false);
  const [activeDropRuleFlyout, setActiveDropRuleFlyout] = useState<DropStrategy | null>(null);
  const dropInfoRef = useRef<HTMLButtonElement>(null!);
  const dropRuleRefs = useRef<Record<DropStrategy, HTMLButtonElement | null>>({
    none: null,
    bestNResults: null,
    dropWorstN: null,
  });

  const handleStrategyChange = (strategy: DropStrategy) => {
    if (disabled || !onChange) return;
    
    const option = DROP_OPTIONS.find((o) => o.value === strategy);
    const next: LeagueConfigFormModel = {
      ...form,
      dropPolicy:
        strategy === 'none'
          ? {
              strategy,
            }
          : {
              strategy,
              n: dropPolicy.n ?? option?.defaultN ?? 1,
            },
    };
    onChange(next);
  };

  const handleNChange = (delta: number) => {
    if (disabled || !onChange || dropPolicy.strategy === 'none') return;
    const current = dropPolicy.n ?? 1;
    const newValue = Math.max(1, current + delta);
    onChange({
      ...form,
      dropPolicy: {
        ...dropPolicy,
        n: newValue,
      },
    });
  };

  const needsN = dropPolicy.strategy !== 'none';

  return (
    <Stack gap={4}>
      {/* Section header */}
      <Stack display="flex" alignItems="center" gap={3}>
        <Stack display="flex" h="10" w="10" alignItems="center" justifyContent="center" rounded="xl" bg="bg-primary-blue/10">
          <Icon icon={TrendingDown} size={5} color="text-primary-blue" />
        </Stack>
        <Stack flexGrow={1}>
          <Stack display="flex" alignItems="center" gap={2}>
            <Heading level={3}>Drop Rules</Heading>
            <InfoButton buttonRef={dropInfoRef} onClick={() => setShowDropFlyout(true)} />
          </Stack>
          <Text size="xs" color="text-gray-500">Protect from bad races</Text>
        </Stack>
      </Stack>

      {/* Drop Rules Flyout */}
      <InfoFlyout
        isOpen={showDropFlyout}
        onClose={() => setShowDropFlyout(false)}
        title="Drop Rules Explained"
        anchorRef={dropInfoRef}
      >
        <Stack gap={4}>
          <Text size="xs" color="text-gray-400" block>
            Drop rules allow drivers to exclude their worst results from championship calculations.
            This protects against mechanical failures, bad luck, or occasional poor performances.
          </Text>
          
          <Stack>
            <Text size="xs" weight="bold" color="text-gray-500" transform="uppercase" 
              // eslint-disable-next-line gridpilot-rules/component-classification
              className="tracking-wide" 
              block 
              mb={2} 
              // eslint-disable-next-line gridpilot-rules/component-classification
              style={{ fontSize: '10px' }}
            >
              Visual Example
            </Text>
            <DropRulesMockup />
          </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 
              // eslint-disable-next-line gridpilot-rules/component-classification
              style={{ fontSize: '10px' }}
            >
              Drop Strategies
            </Text>
            <Stack gap={2}>
              <Stack display="flex" alignItems="start" gap={2} p={2} rounded="lg" bg="bg-deep-graphite" border borderColor="border-charcoal-outline/30">
                <Text size="base">✓</Text>
                <Stack>
                  <Text size="xs" weight="medium" color="text-white" block 
                    // eslint-disable-next-line gridpilot-rules/component-classification
                    style={{ fontSize: '10px' }}
                  >
                    All Count
                  </Text>
                  <Text size="xs" color="text-gray-500" block 
                    // eslint-disable-next-line gridpilot-rules/component-classification
                    style={{ fontSize: '9px' }}
                  >
                    Every race affects standings. Best for short seasons.
                  </Text>
                </Stack>
              </Stack>
              <Stack display="flex" alignItems="start" gap={2} p={2} rounded="lg" bg="bg-deep-graphite" border borderColor="border-charcoal-outline/30">
                <Text size="base">🏆</Text>
                <Stack>
                  <Text size="xs" weight="medium" color="text-white" block 
                    // eslint-disable-next-line gridpilot-rules/component-classification
                    style={{ fontSize: '10px' }}
                  >
                    Best N Results
                  </Text>
                  <Text size="xs" color="text-gray-500" block 
                    // eslint-disable-next-line gridpilot-rules/component-classification
                    style={{ fontSize: '9px' }}
                  >
                    Only your top N races count. Extra races are optional.
                  </Text>
                </Stack>
              </Stack>
              <Stack display="flex" alignItems="start" gap={2} p={2} rounded="lg" bg="bg-deep-graphite" border borderColor="border-charcoal-outline/30">
                <Text size="base">🗑️</Text>
                <Stack>
                  <Text size="xs" weight="medium" color="text-white" block 
                    // eslint-disable-next-line gridpilot-rules/component-classification
                    style={{ fontSize: '10px' }}
                  >
                    Drop Worst N
                  </Text>
                  <Text size="xs" color="text-gray-500" block 
                    // eslint-disable-next-line gridpilot-rules/component-classification
                    style={{ fontSize: '9px' }}
                  >
                    Exclude your N worst results. Forgives bad days.
                  </Text>
                </Stack>
              </Stack>
            </Stack>
          </Stack>

          <Stack rounded="lg" bg="bg-primary-blue/5" border borderColor="border-primary-blue/20" p={3}>
            <Stack display="flex" alignItems="start" gap={2}>
              <Icon icon={Zap} size={3.5} color="text-primary-blue" flexShrink={0} mt={0.5} />
              <Stack>
                <Text size="xs" color="text-gray-400" 
                  // eslint-disable-next-line gridpilot-rules/component-classification
                  style={{ fontSize: '11px' }}
                >
                  <Text weight="medium" color="text-primary-blue">Pro tip:</Text> For an 8-round season,
                  &quot;Best 6&quot; or &quot;Drop 2&quot; are popular choices.
                </Text>
              </Stack>
            </Stack>
          </Stack>
        </Stack>
      </InfoFlyout>

      {/* Strategy buttons + N stepper inline */}
      <Stack display="flex" flexWrap="wrap" alignItems="center" gap={2}>
        {DROP_OPTIONS.map((option) => {
          const isSelected = dropPolicy.strategy === option.value;
          const ruleInfo = DROP_RULE_INFO[option.value];
          return (
            <Stack key={option.value} display="flex" alignItems="center" position="relative">
              <Stack
                as="button"
                type="button"
                disabled={disabled}
                onClick={() => handleStrategyChange(option.value)}
                display="flex"
                alignItems="center"
                gap={2}
                px={3}
                py={2}
                rounded="lg"
                border
                borderWidth="2px"
                transition
                borderColor={isSelected ? 'border-primary-blue' : 'border-charcoal-outline/40'}
                bg={isSelected ? 'bg-primary-blue/10' : 'bg-iron-gray/20'}
                hoverBorderColor={!isSelected && !disabled ? 'border-charcoal-outline' : undefined}
                hoverBg={!isSelected && !disabled ? 'bg-iron-gray/30' : undefined}
                cursor={disabled ? 'default' : 'pointer'}
                opacity={disabled ? 0.6 : 1}
                // eslint-disable-next-line gridpilot-rules/component-classification
                style={{ borderRightWidth: 0, borderTopRightRadius: 0, borderBottomRightRadius: 0 }}
              >
                {/* Radio indicator */}
                <Stack 
                  display="flex" 
                  h="4" 
                  w="4" 
                  alignItems="center" 
                  justifyContent="center" 
                  rounded="full" 
                  border 
                  borderColor={isSelected ? 'border-primary-blue' : 'border-gray-500'}
                  bg={isSelected ? 'bg-primary-blue' : ''}
                  flexShrink={0}
                  transition
                >
                  {isSelected && <Icon icon={Check} size={2.5} color="text-white" />}
                </Stack>
                
                <Text size="sm">{option.emoji}</Text>
                <Text size="sm" weight="medium" color={isSelected ? 'text-white' : 'text-gray-400'}>
                  {option.label}
                </Text>
              </Stack>

              {/* Info button - separate from main button */}
              <Stack
                as="button"
                ref={(el: HTMLButtonElement | null) => { dropRuleRefs.current[option.value] = el; }}
                type="button"
                onClick={(e: React.MouseEvent) => {
                  e.stopPropagation();
                  setActiveDropRuleFlyout(activeDropRuleFlyout === option.value ? null : option.value);
                }}
                display="flex"
                alignItems="center"
                justifyContent="center"
                px={2}
                py={2}
                rounded="lg"
                border
                borderWidth="2px"
                transition
                borderColor={isSelected ? 'border-primary-blue' : 'border-charcoal-outline/40'}
                bg={isSelected ? 'bg-primary-blue/10' : 'bg-iron-gray/20'}
                hoverBorderColor={!isSelected && !disabled ? 'border-charcoal-outline' : undefined}
                hoverBg={!isSelected && !disabled ? 'bg-iron-gray/30' : undefined}
                cursor={disabled ? 'default' : 'pointer'}
                opacity={disabled ? 0.6 : 1}
                // eslint-disable-next-line gridpilot-rules/component-classification
                style={{ borderLeftWidth: 0, borderTopLeftRadius: 0, borderBottomLeftRadius: 0, height: '100%' }}
              >
                <Icon icon={HelpCircle} size={3.5} color="text-gray-500" 
                  // eslint-disable-next-line gridpilot-rules/component-classification
                  className="hover:text-primary-blue transition-colors" 
                />
              </Stack>

              {/* Drop Rule Info Flyout */}
              <InfoFlyout
                isOpen={activeDropRuleFlyout === option.value}
                onClose={() => setActiveDropRuleFlyout(null)}
                title={ruleInfo.title}
                anchorRef={{ current: (dropRuleRefs.current[option.value] as HTMLElement | null) ?? dropInfoRef.current }}
              >
                <Stack gap={4}>
                  <Text size="xs" color="text-gray-400" block>{ruleInfo.description}</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 
                      mb={2}
                      // eslint-disable-next-line gridpilot-rules/component-classification
                      style={{ fontSize: '10px' }}
                    >
                      How It Works
                    </Text>
                    <Stack gap={1.5}>
                      {ruleInfo.details.map((detail, idx) => (
                        <Stack key={idx} display="flex" alignItems="start" gap={2}>
                          <Icon icon={Check} size={3} color="text-performance-green" flexShrink={0} mt={0.5} />
                          <Text size="xs" color="text-gray-400">{detail}</Text>
                        </Stack>
                      ))}
                    </Stack>
                  </Stack>

                  <Stack rounded="lg" bg="bg-deep-graphite" border borderColor="border-charcoal-outline/30" p={3}>
                    <Stack display="flex" alignItems="center" gap={2}>
                      <Text size="base">{option.emoji}</Text>
                      <Stack>
                        <Text size="xs" color="text-gray-400" block 
                          // eslint-disable-next-line gridpilot-rules/component-classification
                          style={{ fontSize: '10px' }}
                        >
                          Example
                        </Text>
                        <Text size="xs" weight="medium" color="text-white" block>{ruleInfo.example}</Text>
                      </Stack>
                    </Stack>
                  </Stack>
                </Stack>
              </InfoFlyout>
            </Stack>
          );
        })}

        {/* N Stepper - only show when needed */}
        {needsN && (
          <Stack display="flex" alignItems="center" gap={1} ml={2}>
            <Text size="xs" color="text-gray-500" mr={1}>N =</Text>
            <Stack
              as="button"
              type="button"
              disabled={disabled || (dropPolicy.n ?? 1) <= 1}
              onClick={() => handleNChange(-1)}
              display="flex"
              h="7"
              w="7"
              alignItems="center"
              justifyContent="center"
              rounded="md"
              bg="bg-iron-gray"
              border
              borderColor="border-charcoal-outline"
              color="text-gray-400"
              transition
              hoverTextColor={!disabled ? 'text-white' : undefined}
              hoverBorderColor={!disabled ? 'border-primary-blue' : undefined}
              opacity={disabled || (dropPolicy.n ?? 1) <= 1 ? 0.4 : 1}
            >
              −
            </Stack>
            <Stack display="flex" h="7" w="10" alignItems="center" justifyContent="center" rounded="md" bg="bg-iron-gray/50" border borderColor="border-charcoal-outline/50">
              <Text size="sm" weight="semibold" color="text-white">{dropPolicy.n ?? 1}</Text>
            </Stack>
            <Stack
              as="button"
              type="button"
              disabled={disabled}
              onClick={() => handleNChange(1)}
              display="flex"
              h="7"
              w="7"
              alignItems="center"
              justifyContent="center"
              rounded="md"
              bg="bg-iron-gray"
              border
              borderColor="border-charcoal-outline"
              color="text-gray-400"
              transition
              hoverTextColor={!disabled ? 'text-white' : undefined}
              hoverBorderColor={!disabled ? 'border-primary-blue' : undefined}
              opacity={disabled ? 0.4 : 1}
            >
              +
            </Stack>
          </Stack>
        )}
      </Stack>

      {/* Explanation text */}
      <Text size="xs" color="text-gray-500" block>
        {dropPolicy.strategy === 'none' && 'Every race result affects the championship standings.'}
        {dropPolicy.strategy === 'bestNResults' && `Only your best ${dropPolicy.n ?? 1} results will count.`}
        {dropPolicy.strategy === 'dropWorstN' && `Your worst ${dropPolicy.n ?? 1} results will be excluded.`}
      </Text>
    </Stack>
  );
}
