/* =========================================================
   SECTIONS · Part 2 — Gallery / Trust / Subsidy / FAQ / Notice / Contact / Footer
   ========================================================= */

function Gallery() {
  const G = window.GALLERY;
  const [tab, setTab] = useState("external");
  const [lb, setLb] = useState(null);

  const items = tab === "external" ? G.external : G.internal;

  const handleTabChange = (t) => { setTab(t); setLb(null); };
  const openLb = (idx) => setLb({ items, idx });

  useEffect(() => {
    const onKey = (e) => {
      if (e.key === "Escape") { setLb(null); return; }
      if (e.key === "ArrowLeft")  setLb(p => p ? { ...p, idx: (p.idx - 1 + p.items.length) % p.items.length } : null);
      if (e.key === "ArrowRight") setLb(p => p ? { ...p, idx: (p.idx + 1) % p.items.length } : null);
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, []);

  const cur = lb ? lb.items[lb.idx] : null;

  return (
    <section className="section gallery" id="gallery">
      <div className="container">
        <div className="section-head section-head--center">
          <Reveal as="span" className="eyebrow eyebrow--center">시공 사례</Reveal>
          <Reveal as="h2" className="h-title" delay={1}>완성된 현장을 확인하세요</Reveal>
          <Reveal as="p" className="lead" delay={2} style={{ textAlign: "center" }}>
            외부 전경부터 내부 설비까지 — 한 장 한 장이 현장에서 정직하게 쌓아온 기록입니다.
          </Reveal>
        </div>
        <Reveal style={{ display: "flex", justifyContent: "center" }}>
          <div className="tabs">
            <button className={`tab${tab === "external" ? " active" : ""}`} onClick={() => handleTabChange("external")}>
              <Icon name="pin" size={18} /> 외부 전경
            </button>
            <button className={`tab${tab === "internal" ? " active" : ""}`} onClick={() => handleTabChange("internal")}>
              <Icon name="snow" size={18} /> 내부 설비
            </button>
          </div>
        </Reveal>
        <div className="gallery__grid">
          {items.map((s, i) => (
            <Reveal key={s.img + tab} className="shot" delay={(i % 3) + 1} onClick={() => openLb(i)}>
              <img src={s.img} alt={s.title} loading="lazy" />
              <div className="shot__overlay">
                <h4>{s.title}</h4>
                <p>{s.desc}</p>
              </div>
              <span className="shot__zoom"><Icon name="zoom" size={19} /></span>
            </Reveal>
          ))}
        </div>
      </div>

      <div className={`lightbox${lb ? " open" : ""}`} onClick={() => setLb(null)}>
        {cur && (
          <React.Fragment>
            <img className="lightbox__img" src={cur.img} alt={cur.title}
              onClick={(e) => e.stopPropagation()} />
            <div className="lightbox__cap" onClick={(e) => e.stopPropagation()}>
              <h4>{cur.title}</h4>
              <p>{cur.desc}</p>
              <span className="count">{lb.idx + 1} / {lb.items.length}</span>
            </div>
          </React.Fragment>
        )}
        <button className="lb-btn lb-close" onClick={() => setLb(null)} aria-label="닫기">
          <Icon name="x" size={26} />
        </button>
        <button className="lb-btn lb-prev" aria-label="이전"
          onClick={(e) => { e.stopPropagation(); setLb(p => p ? { ...p, idx: (p.idx - 1 + p.items.length) % p.items.length } : null); }}>
          <Icon name="chevronLeft" size={26} />
        </button>
        <button className="lb-btn lb-next" aria-label="다음"
          onClick={(e) => { e.stopPropagation(); setLb(p => p ? { ...p, idx: (p.idx + 1) % p.items.length } : null); }}>
          <Icon name="chevronRight" size={26} />
        </button>
      </div>
    </section>
  );
}

function ConstructionProcessCase() {
  const P = window.CONSTRUCTION_PROCESS_CASE;
  const slides = P.images;
  const [active, setActive] = useState(0);
  const [paused, setPaused] = useState(false);
  const [lbOpen, setLbOpen] = useState(false);
  const stageDrag = useRef({ active: false, startX: 0 });
  const stepsRef = useRef(null);
  const stepsDrag = useRef({ active: false, startX: 0, scrollLeft: 0, moved: false, captured: false });
  const total = slides.length;

  const goTo = useCallback((idx) => {
    setActive((idx + total) % total);
  }, [total]);

  const step = useCallback((dir) => {
    setActive((current) => (current + dir + total) % total);
  }, [total]);

  useEffect(() => {
    if (paused || lbOpen) return;
    if (window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
    const timer = window.setInterval(() => {
      setActive((current) => (current + 1) % total);
    }, 3600);
    return () => window.clearInterval(timer);
  }, [paused, lbOpen, total]);

  useEffect(() => {
    if (!lbOpen) return;
    const onKey = (e) => {
      if (e.key === "Escape") setLbOpen(false);
      else if (e.key === "ArrowLeft") step(-1);
      else if (e.key === "ArrowRight") step(1);
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [lbOpen, step]);

  const onStagePointerDown = (e) => {
    if (e.pointerType === "mouse" && e.button !== 0) return;
    if (e.target.closest && e.target.closest("button")) return;
    stageDrag.current = { active: true, startX: e.clientX };
    e.currentTarget.setPointerCapture?.(e.pointerId);
  };

  const onStagePointerUp = (e) => {
    const drag = stageDrag.current;
    if (!drag.active) return;
    drag.active = false;
    const delta = e.clientX - drag.startX;
    e.currentTarget.releasePointerCapture?.(e.pointerId);
    if (Math.abs(delta) > 48) goTo(active + (delta < 0 ? 1 : -1));
    else if (Math.abs(delta) < 8) setLbOpen(true); // tap (not a drag) → open large view
  };

  const onStagePointerCancel = (e) => {
    stageDrag.current.active = false;
    e.currentTarget.releasePointerCapture?.(e.pointerId);
  };

  const onStepsPointerDown = (e) => {
    if (e.pointerType !== "mouse" || e.button !== 0) return;
    const el = stepsRef.current;
    if (!el) return;
    // Don't capture the pointer yet — capturing on a plain tap swallows the
    // thumbnail's click event. Capture lazily once an actual drag is detected.
    stepsDrag.current = { active: true, pointerId: e.pointerId, startX: e.clientX, scrollLeft: el.scrollLeft, moved: false, captured: false };
  };

  const onStepsPointerMove = (e) => {
    const drag = stepsDrag.current;
    const el = stepsRef.current;
    if (!drag.active || !el) return;
    if (drag.pointerId !== e.pointerId) return;
    const delta = e.clientX - drag.startX;
    if (!drag.moved && Math.abs(delta) > 4) {
      drag.moved = true;
      el.classList.add("dragging");
      try { e.currentTarget.setPointerCapture?.(e.pointerId); drag.captured = true; } catch (_) {}
    }
    if (drag.moved) {
      el.scrollLeft = drag.scrollLeft - delta;
      e.preventDefault();
    }
  };

  const stopStepsDrag = (e) => {
    const drag = stepsDrag.current;
    if (drag.pointerId !== undefined && drag.pointerId !== e.pointerId) return;
    drag.active = false;
    drag.pointerId = undefined;
    stepsRef.current?.classList.remove("dragging");
    if (drag.captured) {
      try { e.currentTarget.releasePointerCapture?.(e.pointerId); } catch (_) {}
      drag.captured = false;
    }
    window.setTimeout(() => { stepsDrag.current.moved = false; }, 0);
  };

  const onStepClick = (e, idx) => {
    if (stepsDrag.current.moved) {
      e.preventDefault();
      e.stopPropagation();
      return;
    }
    goTo(idx);
    setLbOpen(true); // clicking a thumbnail jumps to it and opens the large view
  };

  return (
    <section className="section construction-case" id="construction-case">
      <div className="container">
        <div className="construction-case__head">
          <div>
            <Reveal as="span" className="eyebrow">{P.eyebrow}</Reveal>
            <Reveal as="h2" className="h-title" delay={1}>{P.title}</Reveal>
          </div>
          <Reveal as="p" className="lead" delay={2}>{P.desc}</Reveal>
        </div>

        <Reveal
          className={`construction-carousel${paused ? " paused" : ""}`}
          onMouseEnter={() => setPaused(true)}
          onMouseLeave={() => setPaused(false)}
          onFocus={() => setPaused(true)}
          onBlur={() => setPaused(false)}
        >
          <div
            className="construction-carousel__stage"
            aria-live="polite"
            onPointerDown={onStagePointerDown}
            onPointerUp={onStagePointerUp}
            onPointerCancel={onStagePointerCancel}
          >
            {slides.map((item, i) => (
              <div
                key={item.img}
                className={`construction-slide${active === i ? " active" : ""}`}
                aria-hidden={active !== i}
              >
                <img src={item.img} alt={item.title} loading={i === 0 ? "eager" : "lazy"} draggable="false" />
                <div className="construction-slide__caption">
                  <h3>{item.title}</h3>
                  <p>{item.desc}</p>
                </div>
              </div>
            ))}

            <div className="construction-carousel__counter" aria-hidden="true">
              <em>{String(active + 1).padStart(2, "0")}</em>
              <span>/ {String(total).padStart(2, "0")}</span>
            </div>

            <button
              type="button"
              className="construction-carousel__zoom"
              onClick={() => setLbOpen(true)}
              aria-label="크게 보기"
            >
              <Icon name="zoom" size={16} /> 크게 보기
            </button>

            <button
              type="button"
              className="construction-carousel__arrow construction-carousel__arrow--prev"
              onClick={() => goTo(active - 1)}
              aria-label="이전 시공 과정"
            >
              <Icon name="chevronLeft" size={24} />
            </button>
            <button
              type="button"
              className="construction-carousel__arrow construction-carousel__arrow--next"
              onClick={() => goTo(active + 1)}
              aria-label="다음 시공 과정"
            >
              <Icon name="chevronRight" size={24} />
            </button>

            <div className="construction-carousel__progress" aria-hidden="true">
              <span key={active} />
            </div>
          </div>

          <div
            ref={stepsRef}
            className="construction-carousel__steps"
            role="tablist"
            aria-label="시공 과정 단계 선택"
            onPointerDown={onStepsPointerDown}
            onPointerMove={onStepsPointerMove}
            onPointerUp={stopStepsDrag}
            onPointerCancel={stopStepsDrag}
          >
            {slides.map((item, i) => (
              <button
                type="button"
                key={item.img}
                className={`construction-step${active === i ? " active" : ""}`}
                role="tab"
                aria-selected={active === i}
                aria-label={`${item.step} ${item.title}`}
                onClick={(e) => onStepClick(e, i)}
              >
                <img src={item.img} alt="" loading="lazy" draggable="false" />
                <b>{item.step}</b>
              </button>
            ))}
          </div>
        </Reveal>
      </div>

      <div
        className={`lightbox${lbOpen ? " open" : ""}`}
        onClick={() => setLbOpen(false)}
        role="dialog"
        aria-modal="true"
        aria-hidden={!lbOpen}
      >
        {lbOpen && (
          <React.Fragment>
            <img
              className="lightbox__img"
              src={slides[active].img}
              alt={slides[active].title}
              onClick={(e) => e.stopPropagation()}
            />
            <div className="lightbox__cap" onClick={(e) => e.stopPropagation()}>
              <h4>{slides[active].title}</h4>
              <p>{slides[active].desc}</p>
              <span className="count">{active + 1} / {total}</span>
            </div>
          </React.Fragment>
        )}
        <button className="lb-btn lb-close" onClick={() => setLbOpen(false)} aria-label="닫기">
          <Icon name="x" size={26} />
        </button>
        <button
          className="lb-btn lb-prev"
          aria-label="이전"
          onClick={(e) => { e.stopPropagation(); step(-1); }}
        >
          <Icon name="chevronLeft" size={26} />
        </button>
        <button
          className="lb-btn lb-next"
          aria-label="다음"
          onClick={(e) => { e.stopPropagation(); step(1); }}
        >
          <Icon name="chevronRight" size={26} />
        </button>
      </div>
    </section>
  );
}

function FeaturedProject() {
  const P = window.FEATURED_PROJECT;
  const images = P.images;
  const [main, ...details] = images;
  const [lb, setLb] = useState(null);
  const cur = lb === null ? null : images[lb];

  useEffect(() => {
    const onKey = (e) => {
      setLb((current) => {
        if (current === null) return null;
        if (e.key === "Escape") return null;
        if (e.key === "ArrowLeft") return (current - 1 + images.length) % images.length;
        if (e.key === "ArrowRight") return (current + 1) % images.length;
        return current;
      });
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [images.length]);

  return (
    <section className="section project-case" id="mukeunji-project">
      <div className="container">
        <div className="project-case__head">
          <div>
            <Reveal as="span" className="eyebrow">{P.eyebrow}</Reveal>
            <Reveal as="h2" className="h-title" delay={1}>{P.title}</Reveal>
          </div>
          <Reveal as="p" className="lead" delay={2}>{P.desc}</Reveal>
        </div>

        <div className="project-case__layout">
          <Reveal
            as="button"
            type="button"
            className="project-case__main"
            onClick={() => setLb(0)}
            aria-label={`${main.title} 크게 보기`}
          >
            <img src={main.img} alt={main.title} loading="lazy" />
            <div className="project-case__caption">
              <span>외부 전경</span>
              <h3>{main.title}</h3>
              <p>{main.desc}</p>
            </div>
            <span className="project-case__zoom"><Icon name="zoom" size={18} /></span>
          </Reveal>

          <div className="project-case__side">
            <div className="project-case__details">
              {details.map((item, i) => (
                <Reveal
                  key={item.img}
                  as="button"
                  type="button"
                  className="project-case__detail"
                  delay={i + 1}
                  onClick={() => setLb(i + 1)}
                  aria-label={`${item.title} 크게 보기`}
                >
                  <img src={item.img} alt={item.title} loading="lazy" />
                  <div className="project-case__detail-caption">
                    <h4>{item.title}</h4>
                    <p>{item.desc}</p>
                  </div>
                  <span className="project-case__zoom"><Icon name="zoom" size={18} /></span>
                </Reveal>
              ))}
            </div>
          </div>
        </div>
      </div>

      <div className={`lightbox${cur ? " open" : ""}`} onClick={() => setLb(null)}>
        {cur && (
          <React.Fragment>
            <img
              className="lightbox__img"
              src={cur.img}
              alt={cur.title}
              onClick={(e) => e.stopPropagation()}
            />
            <div className="lightbox__cap" onClick={(e) => e.stopPropagation()}>
              <h4>{cur.title}</h4>
              <p>{cur.desc}</p>
              <span className="count">{lb + 1} / {images.length}</span>
            </div>
          </React.Fragment>
        )}
        <button className="lb-btn lb-close" onClick={() => setLb(null)} aria-label="닫기">
          <Icon name="x" size={26} />
        </button>
        <button
          className="lb-btn lb-prev"
          aria-label="이전 사진"
          onClick={(e) => { e.stopPropagation(); setLb((current) => current === null ? null : (current - 1 + images.length) % images.length); }}
        >
          <Icon name="chevronLeft" size={26} />
        </button>
        <button
          className="lb-btn lb-next"
          aria-label="다음 사진"
          onClick={(e) => { e.stopPropagation(); setLb((current) => current === null ? null : (current + 1) % images.length); }}
        >
          <Icon name="chevronRight" size={26} />
        </button>
      </div>
    </section>
  );
}

function Trust() {
  const stats = window.STATS;
  const reviews = window.REVIEWS;
  return (
    <section className="section trust" id="trust">
      <div className="container">
        <div className="section-head section-head--center">
          <Reveal as="span" className="eyebrow eyebrow--center">신뢰 지표</Reveal>
          <Reveal as="h2" className="h-title" delay={1}>
            숫자로 보는 <span className="accent">자연 저온저장고</span>
          </Reveal>
        </div>
        <div className="stats-row">
          {stats.map((s, i) => (
            <Reveal key={s.label} className="stat-card" delay={i + 1}>
              <div className="num"><Counter to={s.num} suffix={s.suffix} /></div>
              <div className="lbl">{s.label}</div>
            </Reveal>
          ))}
        </div>
        <Reveal>
          <div className="reviews">
            {reviews.map((r, i) => (
              <div className="review" key={i}>
                <div className="review__stars">
                  {Array.from({ length: 5 }).map((_, j) => <Icon key={j} name="star" size={18} />)}
                </div>
                <p className="review__body">"{r.text}"</p>
                <div className="review__who">
                  <span className="review__avatar">{r.crop}</span>
                  <div>
                    <div className="review__name">{r.name}</div>
                    <div className="review__meta">{r.meta}</div>
                  </div>
                </div>
              </div>
            ))}
          </div>
        </Reveal>
      </div>
    </section>
  );
}

function Subsidy() {
  const S = window.SUBSIDY;
  const C = window.COMPANY;
  return (
    <section className="section section--tight" id="subsidy">
      <div className="container">
        <Reveal>
          <div className="subsidy__card">
            <div className="subsidy__left">
              <span className="subsidy__chip">
                <Icon name="doc" size={16} /> 정부 보조사업
              </span>
              <h3>저온저장고 설치<br />보조금 지원 안내</h3>
              <p>지자체 농가 저온저장고 보조사업 규격에 맞춰 시공하고, 필요한 서류 진행도 함께 안내해 드립니다.</p>
              <a className="btn btn--ghost" href={`tel:${C.phoneMobile}`}
                style={{ marginTop: 32, alignSelf: "flex-start" }}>
                <Icon name="phone" size={17} /> 보조사업 문의하기
              </a>
            </div>
            <div className="subsidy__right">
              {S.items.map((item) => (
                <div className="subsidy__item" key={item.k}>
                  <span className="k">{item.k}</span>
                  <div>
                    <h4>{item.title}</h4>
                    <p>{item.desc}</p>
                  </div>
                </div>
              ))}
              <div className="subsidy__foot">
                <Icon name="spark" size={18} />
                <span>보조금 사업은 지자체마다 예산 소진 시 조기 마감될 수 있습니다. 지금 바로 문의해 주세요.</span>
              </div>
            </div>
          </div>
        </Reveal>
      </div>
    </section>
  );
}

function FAQ() {
  const faqs = window.FAQS;
  const [open, setOpen] = useState(null);
  return (
    <section className="section faq" id="faq">
      <div className="container">
        <div className="section-head section-head--center">
          <Reveal as="span" className="eyebrow eyebrow--center">FAQ</Reveal>
          <Reveal as="h2" className="h-title" delay={1}>자주 묻는 질문</Reveal>
        </div>
        <Reveal className="faq__wrap">
          {faqs.map((f, i) => (
            <div className={`faq-item${open === i ? " open" : ""}`} key={i}>
              <button className="faq-q" onClick={() => setOpen(open === i ? null : i)}>
                <span><span className="qmark">Q.</span>{f.q}</span>
                <span className="faq-ic"><Icon name="plus" size={18} /></span>
              </button>
              <div className="faq-a" style={{ maxHeight: open === i ? 500 : 0 }}>
                <p className="faq-a__inner">{f.a}</p>
              </div>
            </div>
          ))}
        </Reveal>
      </div>
    </section>
  );
}

function Notice() {
  const notices = window.NOTICES;
  const [modal, setModal] = useState(null);
  const tagClass = { subsidy: "ntag--subsidy", tip: "ntag--tip", news: "ntag--news" };

  useEffect(() => {
    if (!modal) return;
    const onKey = (e) => { if (e.key === "Escape") setModal(null); };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [modal]);

  return (
    <section className="section section--tight notice" id="notice">
      <div className="container">
        <div className="section-head section-head--center">
          <Reveal as="span" className="eyebrow eyebrow--center">공지사항</Reveal>
          <Reveal as="h2" className="h-title" delay={1}>새소식 및 안내</Reveal>
        </div>
        <Reveal className="notice__list">
          {notices.map((n, i) => (
            <div key={i} className="notice-row" role="button" tabIndex={0}
              onClick={() => setModal(n)}
              onKeyDown={(e) => e.key === "Enter" && setModal(n)}>
              <span className={`ntag ${tagClass[n.tag] || ""}`}>{n.tagLabel}</span>
              <span className="notice-row__title">{n.title}</span>
              <span className="notice-row__date">{n.date}</span>
              <span className="notice-row__arrow"><Icon name="chevronRight" size={20} /></span>
            </div>
          ))}
        </Reveal>
      </div>

      {modal && (
        <div style={{
            position: "fixed", inset: 0, zIndex: 1200,
            background: "rgba(9,22,12,.88)",
            display: "flex", alignItems: "center", justifyContent: "center",
            padding: "20px",
          }}
          onClick={() => setModal(null)}>
          <div style={{
              background: "var(--card)", borderRadius: "var(--r-lg)",
              maxWidth: 640, width: "100%", maxHeight: "82vh",
              overflowY: "auto", padding: "clamp(26px,4vw,46px)",
              boxShadow: "var(--sh-lg)",
            }}
            onClick={(e) => e.stopPropagation()}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 16, marginBottom: 18 }}>
              <div>
                <span className={`ntag ${tagClass[modal.tag] || ""}`}
                  style={{ marginBottom: 12, display: "inline-block" }}>{modal.tagLabel}</span>
                <h3 style={{ fontSize: "clamp(17px,2.2vw,23px)", fontWeight: 800, color: "var(--forest-900)", lineHeight: 1.3 }}>
                  {modal.title}
                </h3>
                <p style={{ marginTop: 6, fontSize: 13.5, color: "var(--ink-3)" }}>{modal.date}</p>
              </div>
              <button onClick={() => setModal(null)}
                style={{ flexShrink: 0, width: 40, height: 40, borderRadius: "50%", background: "var(--paper-2)", display: "grid", placeItems: "center", color: "var(--ink-2)", cursor: "pointer" }}>
                <Icon name="x" size={20} />
              </button>
            </div>
            <div style={{ fontSize: 15.5, color: "var(--ink-2)", lineHeight: 1.85, whiteSpace: "pre-line", borderTop: "1px solid var(--line)", paddingTop: 20 }}>
              {modal.body}
            </div>
          </div>
        </div>
      )}
    </section>
  );
}

/* ---------- Consultation Form ---------- */
const FIELD_BASE = {
  width: "100%", padding: "13px 16px", borderRadius: "var(--r-sm)",
  border: "1.5px solid rgba(255,255,255,.18)", background: "rgba(255,255,255,.08)",
  color: "#fff", fontSize: 15.5, fontFamily: "inherit",
  outline: "none", transition: "border-color .2s",
};

function getPhoneDigits(value) {
  const compact = value.replace(/[\s-]/g, "");
  if (!/^\+?\d+$/.test(compact)) return "";
  return compact.startsWith("+82") ? `0${compact.slice(3)}` : compact;
}

function isValidPhoneNumber(value) {
  const digits = getPhoneDigits(value);
  const patterns = [
    /^010\d{8}$/,
    /^01[16789]\d{7,8}$/,
    /^02\d{7,8}$/,
    /^0(?:3[1-3]|4[1-4]|5[1-5]|6[1-4])\d{7,8}$/,
    /^070\d{8}$/,
    /^050[2-8]\d{7,8}$/,
    /^(?:15|16|18)\d{6}$/,
  ];

  return patterns.some((pattern) => pattern.test(digits));
}

function getPhoneError(phone) {
  if (!phone.trim()) return "연락처를 입력해 주세요.";
  if (phone.length > 40) return "연락처가 너무 깁니다.";
  if (!isValidPhoneNumber(phone)) return "연락 가능한 전화번호를 입력해 주세요. 예: 010-1234-5678";
  return "";
}

function ConsultForm() {
  const types = window.CONSULT_TYPES;
  const C = window.COMPANY;
  const empty = { name: "", phone: "", type: "", message: "", company: "" };
  const [form, setForm] = useState(empty);
  const [done, setDone] = useState(false);
  const [err, setErr] = useState({});
  const [submitting, setSubmitting] = useState(false);
  const [submitError, setSubmitError] = useState("");

  const set = (k) => (e) => {
    setForm(f => ({ ...f, [k]: e.target.value }));
    setErr(current => {
      if (!current[k]) return current;
      const next = { ...current };
      delete next[k];
      return next;
    });
    if (submitError) setSubmitError("");
  };

  const validate = () => {
    const e = {};
    if (!form.name.trim())  e.name  = "이름을 입력해 주세요.";
    const phoneError = getPhoneError(form.phone);
    if (phoneError) e.phone = phoneError;
    if (!form.type)         e.type  = "상담 유형을 선택해 주세요.";
    return e;
  };

  const handlePhoneBlur = (e) => {
    e.target.style.borderColor = "rgba(255,255,255,.18)";
    const phoneError = getPhoneError(form.phone);
    setErr(current => {
      const next = { ...current };
      if (phoneError) next.phone = phoneError;
      else delete next.phone;
      return next;
    });
  };

  const handleSubmit = async (e) => {
    e.preventDefault();
    if (submitting) return;

    setSubmitError("");
    const v = validate();
    if (Object.keys(v).length) { setErr(v); return; }
    setErr({});
    setSubmitting(true);

    try {
      const response = await fetch("/api/contact", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(form),
      });
      const result = await response.json().catch(() => ({}));

      if (!response.ok || !result.ok) {
        if (result.errors) {
          setErr(result.errors);
          setSubmitError(result.message || "입력값을 확인해 주세요.");
          return;
        }
        throw new Error(result.message || "Contact request failed");
      }

      setDone(true);
    } catch (error) {
      console.error("Contact form submit failed.", error);
      setSubmitError("전송에 실패했습니다. 잠시 후 다시 시도하거나 전화 주세요.");
    } finally {
      setSubmitting(false);
    }
  };

  const labelStyle = { display: "block", fontSize: 13, fontWeight: 700, letterSpacing: ".05em", color: "rgba(255,255,255,.7)", marginBottom: 7 };
  const errStyle   = { fontSize: 12.5, color: "#f8a38a", marginTop: 5 };
  const focusStyle = "border-color: rgba(124,199,140,.7)";

  if (done) {
    return (
      <div style={{ textAlign: "center", padding: "clamp(28px,4vw,52px) 0" }}>
        <span style={{ width: 72, height: 72, borderRadius: "50%", background: "var(--green-400)", display: "inline-grid", placeItems: "center", marginBottom: 22 }}>
          <Icon name="check" size={32} style={{ color: "#fff" }} />
        </span>
        <h3 style={{ fontSize: "clamp(20px,2.6vw,28px)", fontWeight: 800, color: "#fff", marginBottom: 12 }}>상담 신청이 접수되었습니다!</h3>
        <p style={{ color: "rgba(255,255,255,.78)", fontSize: 16, marginBottom: 28 }}>
          빠른 시일 내에 담당자가 연락드리겠습니다.<br />급하신 경우 <a href={`tel:${C.phoneMobile}`} style={{ color: "var(--green-300)", fontWeight: 700 }}>{C.phoneMobile}</a> 로 전화 주세요.
        </p>
        <button className="btn btn--ghost" onClick={() => { setDone(false); setForm(empty); setSubmitError(""); }}>
          다시 신청하기
        </button>
      </div>
    );
  }

  return (
    <form onSubmit={handleSubmit} noValidate>
      <div style={{ position: "absolute", left: "-10000px", width: 1, height: 1, overflow: "hidden" }} aria-hidden="true">
        <label>
          회사명
          <input type="text" name="company" tabIndex={-1} autoComplete="off"
            value={form.company} onChange={set("company")} />
        </label>
      </div>

      <div style={{ marginBottom: 20 }}>
        <label style={labelStyle}>상담 유형</label>
        <select value={form.type} onChange={set("type")} disabled={submitting}
          style={{ ...FIELD_BASE, appearance: "none", cursor: "pointer",
            background: form.type ? "rgba(255,255,255,.08)" : "rgba(255,255,255,.05)" }}>
          <option value="" style={{ background: "var(--forest-800)", color: "#fff" }}>유형을 선택해 주세요</option>
          {types.map(t => <option key={t} value={t} style={{ background: "var(--forest-800)", color: "#fff" }}>{t}</option>)}
        </select>
        {err.type && <p style={errStyle}>{err.type}</p>}
      </div>

      <div className="field-row" style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 18, marginBottom: 20 }}>
        <div>
          <label style={labelStyle}>이름</label>
          <input type="text" placeholder="홍길동" value={form.name} onChange={set("name")} disabled={submitting}
            style={FIELD_BASE} onFocus={e => e.target.style.borderColor="rgba(124,199,140,.7)"}
            onBlur={e => e.target.style.borderColor="rgba(255,255,255,.18)"} />
          {err.name && <p style={errStyle}>{err.name}</p>}
        </div>
        <div>
          <label style={labelStyle}>연락처</label>
          <input type="tel" inputMode="tel" autoComplete="tel" maxLength={40}
            placeholder="010-1234-5678" value={form.phone} onChange={set("phone")} disabled={submitting}
            aria-invalid={Boolean(err.phone)} aria-describedby={err.phone ? "contact-phone-error" : undefined}
            style={FIELD_BASE} onFocus={e => e.target.style.borderColor="rgba(124,199,140,.7)"}
            onBlur={handlePhoneBlur} />
          {err.phone && <p id="contact-phone-error" style={errStyle}>{err.phone}</p>}
        </div>
      </div>

      <div style={{ marginBottom: 26 }}>
        <label style={labelStyle}>문의 내용 <span style={{ fontWeight: 400, opacity: .6 }}>(선택)</span></label>
        <textarea rows={4} placeholder="설치 장소, 규모, 작물 등 간단히 적어 주시면 더 정확한 상담이 가능합니다."
          value={form.message} onChange={set("message")} disabled={submitting}
          style={{ ...FIELD_BASE, resize: "vertical", lineHeight: 1.7 }}
          onFocus={e => e.target.style.borderColor="rgba(124,199,140,.7)"}
          onBlur={e => e.target.style.borderColor="rgba(255,255,255,.18)"} />
      </div>

      {submitError && (
        <p style={{ margin: "-8px 0 16px", textAlign: "center", fontSize: 13.5, color: "#f8a38a", fontWeight: 700 }}>
          {submitError}
        </p>
      )}

      <button type="submit" className="btn btn--primary btn--block btn--lg" disabled={submitting}
        aria-busy={submitting}
        style={{ opacity: submitting ? .68 : 1, cursor: submitting ? "not-allowed" : "pointer" }}>
        <Icon name="arrowRight" size={19} /> {submitting ? "전송 중..." : "무료 상담 신청하기"}
      </button>
      <p style={{ marginTop: 14, textAlign: "center", fontSize: 13, color: "rgba(255,255,255,.5)" }}>
        개인정보는 상담 목적으로만 사용됩니다.
      </p>
    </form>
  );
}

function Contact() {
  const C = window.COMPANY;
  return (
    <section className="section contact" id="contact">
      <div className="container">
        <div className="contact__grid">
          <div>
            <Reveal as="span" className="eyebrow">CONTACT</Reveal>
            <Reveal as="h2" style={{ marginTop: 16 }} delay={1}>
              전화 한 통으로<br />무료 상담 시작하기
            </Reveal>
            <Reveal as="p" className="contact__lead" delay={2}>
              부담 없이 전화 주세요. 저장고 용도와 규모를 말씀해 주시면 대략적인 방향과 비용을 바로 안내해 드립니다.
            </Reveal>
            <Reveal className="contact__info" delay={3}>
              <div className="cinfo">
                <span className="cinfo__ic"><Icon name="phone" size={23} /></span>
                <div>
                  <div className="k">상담 전화</div>
                  <a className="v" href={`tel:${C.phoneMobile}`} style={{ color: "#fff", display: "block" }}>
                    {C.phoneMobile}
                  </a>
                </div>
              </div>
              <div className="cinfo">
                <span className="cinfo__ic"><Icon name="phone" size={23} /></span>
                <div>
                  <div className="k">사무실</div>
                  <a className="v" href={`tel:${C.phoneOffice}`} style={{ color: "#fff", display: "block" }}>
                    {C.phoneOffice} <small>사무실</small>
                  </a>
                </div>
              </div>
              <div className="cinfo">
                <span className="cinfo__ic"><Icon name="pin" size={23} /></span>
                <div>
                  <div className="k">시공 범위</div>
                  <div className="v">{C.area}</div>
                </div>
              </div>
              <div className="cinfo">
                <span className="cinfo__ic"><Icon name="clock" size={23} /></span>
                <div>
                  <div className="k">상담 시간</div>
                  <div className="v">연중무휴 <small>급한 상황은 언제든지</small></div>
                </div>
              </div>
            </Reveal>
          </div>

          <Reveal delay={2}>
            <div className="callcard">
              <span className="callcard__pulse">
                <Icon name="phone" size={32} />
              </span>
              <div className="callcard__label">무료 전화 상담</div>
              <a className="callcard__num" href={`tel:${C.phoneMobile}`}>{C.phoneMobile}</a>
              <div className="callcard__actions">
                <a className="btn btn--primary btn--block" href={`tel:${C.phoneMobile}`}>
                  <Icon name="phone" size={18} /> 지금 바로 전화하기
                </a>
              </div>
              <div className="callcard__office">
                <Icon name="phone" size={16} />
                사무실&nbsp;<strong>{C.phoneOffice}</strong>
              </div>
            </div>
          </Reveal>
        </div>

        {/* Consultation request form */}
        <Reveal style={{ marginTop: "clamp(52px,7vw,88px)" }}>
          <div style={{
            background: "rgba(255,255,255,.05)", border: "1px solid rgba(255,255,255,.12)",
            borderRadius: "var(--r-xl)", padding: "clamp(32px,4vw,56px)",
          }}>
            <div style={{ marginBottom: 32, display: "flex", alignItems: "flex-start", gap: 18, flexWrap: "wrap" }}>
              <div>
                <span className="eyebrow" style={{ color: "var(--green-300)" }}>온라인 상담 신청</span>
                <h3 style={{ fontSize: "clamp(20px,2.4vw,28px)", fontWeight: 800, color: "#fff", marginTop: 10, letterSpacing: "-.02em" }}>
                  견적 · 방문 상담 신청
                </h3>
                <p style={{ marginTop: 8, color: "rgba(255,255,255,.72)", fontSize: 15.5 }}>
                  전화가 어려우시면 온라인으로 신청해 주세요. 확인 후 빠르게 연락드립니다.
                </p>
              </div>
            </div>
            <ConsultForm />
          </div>
        </Reveal>
      </div>
    </section>
  );
}

function Footer() {
  const C = window.COMPANY;
  const year = new Date().getFullYear();
  return (
    <footer className="footer">
      <div className="container">
        <div className="footer__top">
          <div>
            <a href="#top" className="brand">
              <img className="brand__logo brand__logo--footer" src="img/logo-header.png" alt={C.legal} />
            </a>
            <p className="footer__about">
              {C.legal} · 대표 {C.ceo} · 기계설비 면허와 국가기술자격을 바탕으로 설계부터 시공, 사후관리까지 체계적으로 관리합니다.
              농가와 업체의 소중한 자산을 신선하고 안전하게 지켜드립니다.
            </p>
          </div>
          <div className="footer__col">
            <h4>바로가기</h4>
            {[["#why","왜 자연인가"],["#credentials","면허·자격"],["#types","저장고 종류"],["#process","시공 절차"],["#construction-case","시공 과정"],["#gallery","시공 사례"],["#trust","고객 후기"],["#subsidy","보조사업"]].map(([h,l]) => (
              <a key={h} href={h}>{l}</a>
            ))}
          </div>
          <div className="footer__col">
            <h4>문의 · 상담</h4>
            <p>상담 전화 {C.phoneMobile}</p>
            <p>사무실 {C.phoneOffice}</p>
            <p>전국 출장 시공</p>
            <p>상담 연중무휴</p>
            <a href="#contact" style={{ marginTop: 8, display: "inline-block" }}>온라인 상담 신청 →</a>
          </div>
        </div>
        <div className="footer__bottom">
          <span>© {year} {C.name}. All rights reserved.</span>
        </div>
      </div>
    </footer>
  );
}

Object.assign(window, { Gallery, Trust, Subsidy, FAQ, Notice, Contact, Footer });
