import React, { useEffect, useRef, useState } from 'react';
import { createRoot } from 'react-dom/client';
import './styles.css';

function Icon({ name, size = 24, ...props }) {
  const paths = {
    pin: <><path d="M20 10c0 6-8 12-8 12S4 16 4 10a8 8 0 1 1 16 0Z" /><circle cx="12" cy="10" r="2.5" /></>,
    food: <><path d="M5 3v6m3-6v6M2 3v6a3 3 0 0 0 6 0M5 12v9M16 3c-3 2-4 5-4 9h5M17 3v18" /></>,
    drink: <><path d="m3 4 9 10 9-10H3Zm9 10v7m-5 0h10M7 8h10" /></>,
    coffee: <><path d="M3 8h13v7a5 5 0 0 1-5 5H8a5 5 0 0 1-5-5V8Zm13 1h2a3 3 0 1 1 0 6h-2M6 3v2m4-3v3m4-2v2M2 22h16" /></>,
    search: <><circle cx="10.5" cy="10.5" r="6.5" /><path d="m16 16 5 5" /></>,
    arrow: <><path d="M4 12h16m-6-6 6 6-6 6" /></>,
    check: <path d="m5 12 4 4L19 6" />,
    sparkle: <><path d="m12 3 2.5 6.5L21 12l-6.5 2.5L12 21l-2.5-6.5L3 12l6.5-2.5L12 3Z" /></>,
  };
  return <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true" {...props}>{paths[name]}</svg>;
}

const categories = [
  { name: '맛집', icon: 'food', description: '맛있는 한 끼' },
  { name: '술집', icon: 'drink', description: '가볍게 한 잔' },
  { name: '카페', icon: 'coffee', description: '느긋한 수다' },
];

function NeighborhoodArt() {
  return <div className="neighborhood-art" aria-hidden="true">
    <div className="map-paper">
      <div className="map-block block-one" /><div className="map-block block-two" />
      <div className="map-block block-three" /><div className="map-block block-four" />
      <svg className="map-route" viewBox="0 0 390 260"><path d="M70 179h85q22 0 22-22v-40q0-22 22-22h95" fill="none" stroke="#7b9679" strokeWidth="3" strokeDasharray="5 9" strokeLinecap="round" /></svg>
      <div className="map-tree tree-one">✳</div><div className="map-tree tree-two">✳</div>
      <div className="place-bubble bubble-food"><Icon name="food" size={26} /></div>
      <div className="place-bubble bubble-coffee"><Icon name="coffee" size={27} /></div>
      <div className="place-bubble bubble-drink"><Icon name="drink" size={25} /></div>
      <div className="meeting-pin"><Icon name="pin" size={55} /></div>
    </div>
    <div className="map-note"><span className="note-dot" />우리 여기서 만날까?</div>
    <span className="art-sparkle sparkle-one">✧</span><span className="art-sparkle sparkle-two">✦</span>
  </div>;
}

function App() {
  const [region, setRegion] = useState('');
  const [category, setCategory] = useState('맛집');
  const [submitted, setSubmitted] = useState(null);
  const [error, setError] = useState('');
  const [status, setStatus] = useState('idle');
  const [places, setPlaces] = useState([]);
  const [searchError, setSearchError] = useState('');
  const [selectedRegion, setSelectedRegion] = useState('');
  const regionInput = useRef(null);
  const activeRequest = useRef(null);
  const requestId = useRef(0);

  useEffect(() => () => { requestId.current += 1; activeRequest.current?.abort(); }, []);

  function resetSearch() {
    requestId.current += 1;
    activeRequest.current?.abort();
    activeRequest.current = null;
    setStatus('idle');
    setPlaces([]);
    setSubmitted(null);
    setSelectedRegion('');
    setSearchError('');
  }

  async function handleSubmit(event) {
    event.preventDefault();
    if (activeRequest.current) return;
    const cleanRegion = region.trim();
    if (!cleanRegion) {
      setError('만날 지역이나 역 이름을 입력해 주세요.');
      regionInput.current.focus();
      return;
    }
    setError('');
    setSubmitted({ region: cleanRegion, category });
    setStatus('loading');
    setPlaces([]);
    setSelectedRegion('');
    setSearchError('');
    const id = ++requestId.current;
    const controller = new AbortController();
    activeRequest.current = controller;
    const timer = setTimeout(() => controller.abort(), 15000);
    try {
      const params = new URLSearchParams({ region: cleanRegion, category });
      const response = await fetch(`/api/search?${params}`, { signal: controller.signal });
      const data = await response.json();
      if (id !== requestId.current) return;
      if (!response.ok) throw new Error(data.message || '검색에 실패했어요. 잠시 후 다시 시도해 주세요.');
      if (!Array.isArray(data.places)) throw new Error('검색 결과를 읽지 못했어요. 다시 시도해 주세요.');
      setPlaces(data.places.slice(0, 10));
      setSelectedRegion(data.selectedRegion || '');
      setStatus(data.places.length ? 'success' : 'empty');
    } catch (failure) {
      if (id !== requestId.current) return;
      setStatus('error');
      setSearchError(controller.signal.aborted ? '검색 응답이 늦어지고 있어요. 다시 시도해 주세요.' : failure instanceof SyntaxError || failure instanceof TypeError ? '검색 서버에 연결하지 못했어요. 서버 실행 상태를 확인하고 다시 시도해 주세요.' : failure.message);
    } finally {
      clearTimeout(timer);
      if (id === requestId.current) activeRequest.current = null;
    }
  }

  return <div className="app-shell">
    <header className="site-header">
      <a className="brand" href="./" aria-label="어디갈래? 홈"><span className="brand-symbol"><Icon name="pin" size={23} /></span>어디갈래<span className="brand-question">?</span></a>
      <span className="header-note"><span />좋은 만남의 시작</span>
    </header>

    <main>
      <section className="hero" aria-labelledby="hero-title">
        <div className="hero-copy">
          <div className="eyebrow"><Icon name="sparkle" size={15} />친구와 함께, 동네의 발견</div>
          <h1 id="hero-title">만나는 동네는 정했어?<br />그럼, <span>어디갈래?</span></h1>
          <p>맛있는 한 끼부터 기분 좋은 커피 한 잔까지.<br />친구들과 함께할 장소, 이제 한곳에서 찾아봐요.</p>
        </div>
        <NeighborhoodArt />
      </section>

      <section className="search-panel" aria-labelledby="search-title">
        <div className="panel-heading"><h2 id="search-title">이번엔 어디서 만날까요?</h2><span>약속의 시작은 여기서</span></div>
        <form onSubmit={handleSubmit} noValidate>
          <div className="form-columns">
            <div className="region-field">
              <label htmlFor="region"><span className="step-number">01</span>만날 동네</label>
              <div className={`input-wrap ${error ? 'has-error' : ''}`}><Icon name="pin" size={22} /><input ref={regionInput} id="region" name="region" type="text" placeholder="예: 광주광역시 동명동" value={region} maxLength={80} autoComplete="off" required aria-invalid={Boolean(error)} aria-describedby={error ? 'region-error' : 'region-hint'} onChange={(event) => { resetSearch(); setRegion(event.target.value); if (error) setError(''); }} /></div>
              {error ? <p id="region-error" className="input-error" role="alert">{error}</p> : <p id="region-hint" className="input-hint">시·도까지 입력해 주세요. 예: 광주광역시 동명동, 서울 홍대입구역</p>}
            </div>
            <fieldset className="category-field">
              <legend><span className="step-number">02</span>어떤 시간을 보낼까요?</legend>
              <div className="category-options">
                {categories.map((item) => <label className={`category-option ${category === item.name ? 'is-selected' : ''}`} key={item.name}>
                  <input type="radio" name="category" value={item.name} checked={category === item.name} onChange={() => { resetSearch(); setCategory(item.name); }} />
                  <span className="category-top"><Icon name={item.icon} size={21} /><span>{item.name}</span>{category === item.name && <Icon name="check" size={14} className="category-check" />}</span>
                  <span className="category-description">{item.description}</span>
                </label>)}
              </div>
            </fieldset>
          </div>
          <button className="search-button" type="submit" disabled={status === 'loading'}><Icon name="search" size={20} />{status === 'loading' ? '장소 찾는 중…' : '장소 찾아보기'}<Icon name="arrow" size={20} className="button-arrow" /></button>
          <p className="preview-notice">카카오 장소 검색 · 맛집은 음식점으로 검색해요. 맛이나 평점 순위가 아니에요.</p>
        </form>
      </section>

      <section className="results-section" aria-labelledby="results-title">
        <div className="results-heading"><h2 id="results-title">장소 둘러보기</h2><span className="preparing-label"><span />카카오 장소 검색</span></div>
        {submitted && <div className="search-summary"><div className="submitted-tags"><span>{submitted.region}</span><span>{submitted.category}</span></div>{selectedRegion && <p>카카오가 인식한 지역: {selectedRegion}</p>}</div>}
        <div className={status === 'success' ? 'results-announcement' : 'results-content'} role="status" aria-live="polite" aria-atomic="true">
          {status !== 'success' && <div className={`result-icon ${status === 'loading' ? 'is-loading' : ''}`}><Icon name={submitted ? 'pin' : 'search'} size={25} /></div>}
          {status === 'idle' && <>
            <h3>좋은 장소에서, 더 좋은 시간을</h3>
            <p>만날 동네와 원하는 종류를 골라 주세요.<br />우리의 다음 약속을 여기서 시작해 봐요.</p>
          </>}
          {status === 'loading' && <><h3>만날 장소를 찾고 있어요</h3><p>잠시만 기다려 주세요.<br />검색 조건을 바꾸면 진행 중인 검색을 취소해요.</p></>}
          {status === 'empty' && <><h3>조건에 맞는 장소를 찾지 못했어요</h3><p>시·도를 포함한 지역 이름을 확인하거나 다른 종류로 검색해 보세요.</p></>}
          {status === 'error' && <><h3>검색을 완료하지 못했어요</h3><p className="search-error">{searchError}</p></>}
          {status === 'success' && <p><strong>{places.length}곳</strong>을 찾았어요. 카카오 검색 순서로 최대 10곳을 보여드려요.</p>}
        </div>
        {status === 'success' && <>
          <div className="place-grid">
            {places.map((place, index) => <article className="place-card" key={place.id || index}>
              <div className="place-card-heading"><span className="place-type-icon"><Icon name={categories.find(item => item.name === submitted.category).icon} size={22} /></span><h3>{place.name || '정보 없음'}</h3></div>
              <dl><div><dt>업종</dt><dd>{place.category || '정보 없음'}</dd></div><div><dt>주소</dt><dd>{place.address || '정보 없음'}</dd></div><div><dt>전화번호</dt><dd>{place.phone || '정보 없음'}</dd></div></dl>
              {place.url ? <a className="map-link" href={place.url} target="_blank" rel="noopener noreferrer" aria-label={`${place.name || '장소'} 카카오맵에서 보기 (새 탭)`}>카카오맵에서 보기<Icon name="arrow" size={16} /></a> : <p className="map-link-missing">카카오맵 링크: 정보 없음</p>}
            </article>)}
          </div>
          <p className="results-note">입력한 지역을 바탕으로 검색하며, 인근 지역이 포함될 수 있어요. 방문 전 주소와 상세 정보를 확인해 주세요.</p>
        </>}
      </section>
    </main>

    <footer><span className="footer-brand">어디갈래?</span><p>어디서 만나든, 함께라서 좋은 시간.</p><span className="footer-mark">우리의 다음 약속 <Icon name="sparkle" size={14} /></span></footer>
  </div>;
}

createRoot(document.getElementById('root')).render(<React.StrictMode><App /></React.StrictMode>);
