'use client';

import { useEffect, useRef, useState, useTransition } from 'react';
import { useRouter } from 'next/navigation';
import {
  ChampionSuggestion,
  getChampionSuggestions,
  getRiotAccountSuggestions,
  lookupAnalysis,
  refreshAnalysis,
  RiotAccountSuggestion,
} from '@/lib/api';
import { buildSummonerDetailPath } from '@/lib/routes';
import { translateApiErrorMessage } from '@/lib/ui-text';

type Variant = 'hero' | 'compact';
type AutocompleteItem =
  | {
      id: string;
      kind: 'champion';
      sortScore: number;
      suggestion: ChampionSuggestion;
    }
  | {
      id: string;
      kind: 'summoner';
      sortScore: number;
      suggestion: RiotAccountSuggestion;
    };

export function RiotSearchForm({ variant = 'hero' }: { variant?: Variant }) {
  const router = useRouter();
  const [gameName, setGameName] = useState('');
  const [tagLine, setTagLine] = useState('KR1');
  const [suggestions, setSuggestions] = useState<RiotAccountSuggestion[]>([]);
  const [championSuggestions, setChampionSuggestions] = useState<ChampionSuggestion[]>([]);
  const [isSuggesting, setIsSuggesting] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [isPending, startTransition] = useTransition();
  const requestSeqRef = useRef(0);

  useEffect(() => {
    const parsed = parseSuggestionQuery(gameName, tagLine);
    if (!parsed.query) {
      setSuggestions([]);
      setChampionSuggestions([]);
      setIsSuggesting(false);
      return;
    }

    const timer = window.setTimeout(async () => {
      const requestSeq = requestSeqRef.current + 1;
      requestSeqRef.current = requestSeq;
      setIsSuggesting(true);
      try {
        const [accountData, championData] = await Promise.all([
          getRiotAccountSuggestions({
            query: parsed.query,
            tagLine: parsed.tagLineHint,
          }),
          getChampionSuggestions(parsed.query),
        ]);
        if (requestSeq !== requestSeqRef.current) return;
        setSuggestions(accountData);
        setChampionSuggestions(championData);
      } catch {
        if (requestSeq !== requestSeqRef.current) return;
        setSuggestions([]);
        setChampionSuggestions([]);
      } finally {
        if (requestSeq === requestSeqRef.current) {
          setIsSuggesting(false);
        }
      }
    }, 250);

    return () => window.clearTimeout(timer);
  }, [gameName, tagLine]);

  const runSearch = (
    input: { gameName: string; tagLine: string },
    champions: ChampionSuggestion[] = [],
    accounts: RiotAccountSuggestion[] = [],
  ) => {
    setError(null);
    startTransition(async () => {
      try {
        const champion = resolveChampionMatch(input.gameName, champions);
        if (champion) {
          router.push(`/champions/${encodeURIComponent(champion.key)}`);
          return;
        }

        const parsed = parseRiotId(input.gameName, input.tagLine);
        const matchedAccount = resolveAccountMatch(parsed, accounts);
        const resolvedGameName = matchedAccount?.gameName ?? parsed.gameName;
        const resolvedTagLine = matchedAccount?.tagLine ?? parsed.tagLine;
        const stablePath = buildSummonerDetailPath(resolvedGameName, resolvedTagLine);
        const lookup = await lookupAnalysis({
          gameName: resolvedGameName,
          tagLine: resolvedTagLine,
          region: 'KR',
          syncIfMissing: false,
        });
        const refresh = await refreshAnalysis({
          snapshotId: lookup.latestSnapshotId ?? undefined,
          gameName: resolvedGameName,
          tagLine: resolvedTagLine,
          region: 'KR',
        });
        if (lookup.latestSnapshotId || refresh.requestId) {
          router.push(stablePath);
          return;
        }

        router.push(stablePath);
      } catch (err) {
        setError(
          translateApiErrorMessage(err instanceof Error ? err.message : 'Request failed.'),
        );
      }
    });
  };

  const submit = (event: React.FormEvent) => {
    event.preventDefault();
    runSearch({ gameName, tagLine }, championSuggestions, suggestions);
  };

  const chooseSuggestion = (suggestion: RiotAccountSuggestion) => {
    setGameName(suggestion.gameName);
    setTagLine(suggestion.tagLine);
    setSuggestions([]);
    setChampionSuggestions([]);
    runSearch({
      gameName: suggestion.gameName,
      tagLine: suggestion.tagLine,
    });
  };

  const chooseChampionSuggestion = (suggestion: ChampionSuggestion) => {
    setGameName(suggestion.name);
    setChampionSuggestions([]);
    setSuggestions([]);
    router.push(`/champions/${encodeURIComponent(suggestion.key)}`);
  };

  const compact = variant === 'compact';
  const wrapperClass = compact ? 'mx-0 max-w-none' : 'mx-auto max-w-[760px]';
  const containerClass = compact
    ? 'rounded-[18px] border border-[#d7e3ff]/50 bg-[#f6f9ff] shadow-[0_18px_42px_rgba(14,24,51,0.22)]'
    : 'rounded-[18px] border border-white/12 bg-white shadow-[0_20px_55px_rgba(0,0,0,0.28)]';
  const fieldHeight = compact ? 'h-[54px]' : 'h-[64px]';
  const buttonWidth = compact ? 'w-[96px]' : 'w-[88px]';
  const regionWidth = compact ? 'min-w-[82px]' : 'min-w-[96px]';
  const tagWidth = compact ? 'w-[98px]' : 'w-[110px]';
  const preview = parseRiotId(gameName, tagLine);
  const autocompleteItems = buildAutocompleteItems(gameName, suggestions, championSuggestions);

  return (
    <form onSubmit={submit} className="w-full">
      <div className={`relative ${wrapperClass}`}>
        <div className={`flex overflow-hidden ${containerClass}`}>
          <div
            className={`flex ${fieldHeight} ${regionWidth} items-center justify-center gap-2 rounded-l-[18px] bg-[#e3ecff] px-3 text-[14px] font-semibold text-[#3054c8]`}
          >
            KR
            <span className="text-[#98a2b5]">▾</span>
          </div>
          <input
            value={gameName}
            onChange={(event) => setGameName(event.target.value)}
            placeholder="소환사명, 챔피언명 또는 소환사명#태그"
            className={`min-w-0 flex-1 bg-transparent px-4 text-[15px] font-medium text-[#1d2433] outline-none placeholder:text-[#8f9cb6] ${fieldHeight}`}
            required
          />
          <input
            value={tagLine}
            onChange={(event) => setTagLine(event.target.value)}
            aria-label="Riot 태그"
            placeholder="KR1"
            className={`${fieldHeight} ${tagWidth} border-l border-[#dbe4f5] bg-transparent px-2 text-center text-[15px] font-semibold text-[#1d2433] outline-none placeholder:text-[#8f9cb6]`}
            required
          />
          <button
            disabled={isPending}
            className={`${fieldHeight} ${buttonWidth} border-l border-[#dbe4f5] bg-[#2f63ff] text-[15px] font-black text-white transition hover:bg-[#2558ef] disabled:opacity-60`}
            aria-label="검색"
          >
            {isPending ? '검색중' : '검색'}
          </button>
        </div>

        {(autocompleteItems.length > 0 || isSuggesting) && (
          <div className="absolute left-0 right-0 top-[calc(100%+8px)] z-20 overflow-hidden rounded-[14px] border border-[#d9deea] bg-[#232838] text-left shadow-[0_26px_50px_rgba(0,0,0,0.35)]">
            {isSuggesting ? (
              <div className="px-4 py-3 text-sm text-[#b7bfd3]">추천 목록을 불러오는 중입니다.</div>
            ) : (
              autocompleteItems.map((item, index) => (
                <button
                  key={item.id}
                  type="button"
                  onClick={() =>
                    item.kind === 'champion'
                      ? chooseChampionSuggestion(item.suggestion)
                      : chooseSuggestion(item.suggestion)
                  }
                  className={`flex w-full items-center gap-3 px-4 py-3 text-sm transition hover:bg-white/5 ${
                    index < autocompleteItems.length - 1 ? 'border-b border-white/8' : ''
                  }`}
                >
                  {item.kind === 'champion' ? (
                    item.suggestion.imageUrl ? (
                      <img
                        src={item.suggestion.imageUrl}
                        alt={item.suggestion.name}
                        className="h-8 w-8 rounded-[8px]"
                      />
                    ) : (
                      <span className="flex h-8 w-8 items-center justify-center rounded-[8px] bg-white/10 text-[11px] font-black text-white">
                        챔
                      </span>
                    )
                  ) : (
                    <span className="flex h-8 w-8 items-center justify-center rounded-full bg-[#3a4362] text-[11px] font-black text-[#d8ad53]">
                      소
                    </span>
                  )}
                  <div className="min-w-0 flex-1 text-left">
                    {item.kind === 'champion' ? (
                      <>
                        <div className="truncate font-semibold text-white">{item.suggestion.name}</div>
                        <div className="truncate text-xs text-[#9da6b8]">
                          {item.suggestion.title || '챔피언'}
                        </div>
                      </>
                    ) : (
                      <>
                        <div className="truncate font-semibold text-white">
                          {item.suggestion.gameName}
                          <span className="ml-1 text-[#d8ad53]">#{item.suggestion.tagLine}</span>
                        </div>
                        <div className="truncate text-xs text-[#9da6b8]">최근 동기화된 소환사</div>
                      </>
                    )}
                  </div>
                  <span
                    className={`rounded-full px-2 py-1 text-[10px] font-black ${
                      item.kind === 'champion'
                        ? 'bg-[#33405f] text-[#9dc1ff]'
                        : 'bg-[#423728] text-[#f0c977]'
                    }`}
                  >
                    {item.kind === 'champion' ? '챔피언' : '소환사'}
                  </span>
                </button>
              ))
            )}
          </div>
        )}
      </div>

      {!compact ? (
        <p className="mt-3 text-center text-[12px] font-medium text-[#d5dbec]">
          {gameName.includes('#')
            ? `${preview.gameName}#${preview.tagLine}의 최신 전적을 동기화한 뒤 결과 페이지를 엽니다.`
            : '해시태그 없이 소환사명이나 챔피언명을 입력해도 추천이 뜹니다. 일치하는 항목을 우선 정렬한 뒤 최신 경기 동기화를 시작합니다.'}
        </p>
      ) : null}
      {error ? <p className="mt-2 text-sm font-medium text-[#ff6f8b]">{error}</p> : null}
    </form>
  );
}

function resolveChampionMatch(query: string, champions: ChampionSuggestion[]) {
  const normalized = query.trim().toLowerCase();
  if (!normalized) return null;
  return (
    champions.find(
      (champion) =>
        champion.name.trim().toLowerCase() === normalized ||
        champion.key.trim().toLowerCase() === normalized,
    ) ?? null
  );
}

function parseRiotId(gameNameInput: string, tagLineInput: string) {
  const trimmedGameName = gameNameInput.trim();
  const trimmedTagLine = tagLineInput.trim();

  if (!trimmedGameName.includes('#')) {
    return {
      gameName: trimmedGameName,
      tagLine: trimmedTagLine,
    };
  }

  const [gameName, ...tagParts] = trimmedGameName.split('#');
  const tagLine = tagParts.join('#').trim();

  return {
    gameName: gameName.trim(),
    tagLine: tagLine || trimmedTagLine,
  };
}

function parseSuggestionQuery(gameNameInput: string, tagLineInput: string) {
  const trimmedInput = gameNameInput.trim();
  if (!trimmedInput) {
    return {
      query: '',
      tagLineHint: '',
    };
  }

  if (!trimmedInput.includes('#')) {
    return {
      query: trimmedInput,
      tagLineHint: tagLineInput.trim(),
    };
  }

  const [namePart, ...tagParts] = trimmedInput.split('#');
  return {
    query: namePart.trim(),
    tagLineHint: tagParts.join('#').trim(),
  };
}

function resolveAccountMatch(
  parsed: { gameName: string; tagLine: string },
  accounts: RiotAccountSuggestion[],
) {
  const normalizedGameName = normalizeAutocompleteValue(parsed.gameName);
  const normalizedTagLine = normalizeAutocompleteValue(parsed.tagLine);

  return (
    accounts.find(
      (account) =>
        normalizeAutocompleteValue(account.gameName) === normalizedGameName &&
        normalizeAutocompleteValue(account.tagLine) === normalizedTagLine,
    ) ??
    accounts.find(
      (account) => normalizeAutocompleteValue(account.gameName) === normalizedGameName,
    ) ??
    null
  );
}

function buildAutocompleteItems(
  query: string,
  accounts: RiotAccountSuggestion[],
  champions: ChampionSuggestion[],
) {
  const normalizedQuery = normalizeAutocompleteValue(query.split('#')[0] ?? query);

  const items: AutocompleteItem[] = [
    ...accounts.map((suggestion) => ({
      id: `summoner:${suggestion.puuid}`,
      kind: 'summoner' as const,
      sortScore: scoreSummonerSuggestion(normalizedQuery, suggestion),
      suggestion,
    })),
    ...champions.map((suggestion) => ({
      id: `champion:${suggestion.key}`,
      kind: 'champion' as const,
      sortScore: scoreChampionSuggestion(normalizedQuery, suggestion),
      suggestion,
    })),
  ];

  return items
    .filter((item) => item.sortScore > 0)
    .sort((left, right) => {
      if (right.sortScore !== left.sortScore) return right.sortScore - left.sortScore;
      if (left.kind !== right.kind) return left.kind === 'summoner' ? -1 : 1;
      return left.id.localeCompare(right.id, 'ko');
    })
    .slice(0, 8);
}

function scoreSummonerSuggestion(query: string, suggestion: RiotAccountSuggestion) {
  const normalizedGameName = normalizeAutocompleteValue(suggestion.gameName);
  const normalizedDisplay = `${normalizedGameName}#${normalizeAutocompleteValue(suggestion.tagLine)}`;
  if (!query) return 0;

  let score = 0;
  if (normalizedDisplay === query) score += 260;
  if (normalizedGameName === query) score += 220;
  else if (normalizedGameName.startsWith(query)) score += 175;
  else if (normalizedGameName.includes(query)) score += 125;
  else if (query.includes(normalizedGameName)) score += 70;

  score -= Math.max(0, normalizedGameName.length - query.length);
  return score;
}

function scoreChampionSuggestion(query: string, suggestion: ChampionSuggestion) {
  const normalizedName = normalizeAutocompleteValue(suggestion.name);
  const normalizedKey = normalizeAutocompleteValue(suggestion.key);
  const normalizedTitle = normalizeAutocompleteValue(suggestion.title ?? '');
  if (!query) return 0;

  let score = 0;
  if (normalizedName === query) score += 230;
  else if (normalizedName.startsWith(query)) score += 180;
  else if (normalizedName.includes(query)) score += 130;

  if (normalizedKey === query) score += 205;
  else if (normalizedKey.startsWith(query)) score += 160;
  else if (normalizedKey.includes(query)) score += 120;

  if (normalizedTitle === query) score += 60;
  else if (normalizedTitle.startsWith(query)) score += 45;
  else if (normalizedTitle.includes(query)) score += 20;

  score -= Math.max(0, normalizedName.length - query.length);
  return score;
}

function normalizeAutocompleteValue(value: string) {
  return value.trim().normalize('NFC').toLowerCase();
}
