// 이 파일이 하는 일: "코딩이란 무엇인가"를 이 앱의 실제 코드로 배우는 학습 페이지.
// 서버에서 데이터를 가져오지 않는, 내용이 고정된(정적) 페이지다.
// 학습 포인트: 모든 페이지가 API를 부를 필요는 없다. 이런 페이지는 JSX만으로 충분하다.

// ---------- 아래 코드 조각들은 이 앱에 실제로 있는 코드다 ----------
// 학습 포인트: 코드 조각을 JSX 안에 직접 쓰면 중괄호 {}를 React가 해석해 버려서 깨진다.
// 그래서 자바스크립트 문자열(백틱 ` )로 먼저 만들어 두고 {변수}로 끼워 넣는다.
// 문자열 안의 백틱은 \\` 처럼 역슬래시로 "이건 그냥 글자야"라고 표시(이스케이프)한다.

// ② src/pages/LoginPage.jsx에서 가져온 조각
const CODE_LOGIN_STATE = `// 화면이 기억해야 하는 값 = 상태(state). useState가 만들어 준다.
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [error, setError] = useState('');

// 로그인 버튼을 누르면 실행되는 함수
async function handleSubmit(e) {
  e.preventDefault();      // 브라우저의 새로고침을 막고
  setSubmitting(true);
  try {
    await login(username, password);   // 서버에 로그인을 요청한 뒤
    navigate('/', { replace: true });  // 성공하면 대시보드로 이동
  } catch (err) {
    setError('아이디 또는 비밀번호가 맞지 않아요. 다시 확인해 주세요.');
  } finally {
    setSubmitting(false);
  }
}`;

// ③ src/pages/DashboardPage.jsx에서 가져온 조각
const CODE_DASHBOARD_MAP = `{groupItems.map((item) => {
  const done = checkedIds.has(item.id);   // 이 항목이 체크됐는가? (조건)
  return (
    <label key={item.id} className={\`check-row\${done ? ' done' : ''}\`}>
      <input
        type="checkbox"
        checked={done}
        onChange={() => toggle(item.id)}
      />
      <span className="check-label">{item.label}</span>
    </label>
  );
})}`;

// ④ 프론트엔드 ↔ 백엔드가 대화하는 흐름 (텍스트 다이어그램)
const DIAGRAM_FRONT_BACK = `[여러분의 브라우저]                         [AWESOMEDEV 서버]

  React 앱 (프론트엔드)                     Spring Boot (백엔드)
 ┌───────────────────┐                     ┌───────────────────┐
 │  로그인 버튼 클릭  │ ── POST /api/auth/login ──▶ │ 아이디·비밀번호 확인 │
 │                   │    { username, password }   │  (진짜 검증은 여기!) │
 │                   │                     │                   │
 │  "환영합니다" 표시 │ ◀── 200 OK + 세션 쿠키 ──── │ 세션 만들어 응답     │
 └───────────────────┘                     └────────┬──────────┘
                                                    │
                                                    ▼
                                           [PostgreSQL 데이터베이스]
                                            users 테이블에서 조회`;

// ⑤ backend/src/main/java/dev/awesomedev/mirim/domain/User.java에서 가져온 조각
const CODE_USER_ENTITY = `@Entity
@Table(name = "users") // "user"는 일부 DB에서 예약어라 "users"로 피해간다.
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    /** 로그인 아이디. 중복될 수 없다. */
    @Column(nullable = false, unique = true)
    private String username;

    /** 비밀번호는 절대 원문으로 저장하지 않는다. BCrypt 해시만 저장. */
    @Column(nullable = false)
    private String passwordHash;

    /** 트랙: "DEV" | "DESIGN" | "NONE" (멘토는 NONE) */
    @Column(nullable = false)
    private String track;
}`;

// 작은 보조 컴포넌트: 코드 조각을 보여주는 상자.
// 학습 포인트: <pre>는 "줄바꿈·공백을 그대로 보여줘"라는 태그,
// <code>는 "이건 코드야"라는 의미 태그. 둘을 겹쳐 쓰는 게 관례다.
function CodeBlock({ title, children }) {
  return (
    <div style={{ margin: '12px 0' }}>
      {title && (
        <div className="muted" style={{ fontSize: 12, fontWeight: 700, marginBottom: 4 }}>
          {title}
        </div>
      )}
      <pre
        style={{
          background: 'var(--bg)',
          border: '1px solid var(--line)',
          borderRadius: 10,
          padding: '12px 14px',
          overflowX: 'auto', // 긴 줄은 상자 안에서만 가로 스크롤되게
          fontSize: 13,
          lineHeight: 1.7,
        }}
      >
        <code>{children}</code>
      </pre>
    </div>
  );
}

// "직접 확인해 보기" 안내 상자
function TryIt({ children }) {
  return (
    <div
      style={{
        background: 'var(--primary-soft)',
        borderRadius: 10,
        padding: '10px 14px',
        marginTop: 12,
      }}
    >
      <div style={{ fontSize: 13, fontWeight: 700, color: 'var(--primary)', marginBottom: 4 }}>
        직접 확인해 보기
      </div>
      <div style={{ fontSize: 14 }}>{children}</div>
    </div>
  );
}

// 섹션 하나 = 번호 + 제목 + 내용 카드
function Section({ number, title, children }) {
  return (
    <div className="card" style={{ marginTop: 14 }}>
      <h2 style={{ fontSize: 17, fontWeight: 800, marginBottom: 10 }}>
        <span style={{ color: 'var(--primary)' }}>{number}</span> {title}
      </h2>
      {children}
    </div>
  );
}

export default function CodingBasicsPage() {
  return (
    <div>
      <h1 className="page-title">코딩 기초</h1>
      <p className="page-desc">
        여러분이 지금 쓰고 있는 이 학습 플랫폼의 진짜 코드로 코딩의 큰 그림을 잡아 봅니다.
        위에서 아래로 천천히 읽어 보세요.
      </p>

      <Section number="①" title="코딩이란?">
        <p>
          코딩은 <strong>컴퓨터에게 일을 시키는 글쓰기</strong>입니다. 사람에게 부탁할 때는
          "적당히 알아서 해줘"가 통하지만, 컴퓨터는 적힌 대로만 정확하게 움직입니다. 그래서
          "무엇을, 어떤 순서로, 어떤 조건에서" 할지를 빠짐없이 적어야 하고, 그 글이 곧
          코드입니다.
        </p>
        <p style={{ marginTop: 8 }}>
          멀리서 찾을 필요 없습니다. 여러분이 방금 누른 <strong>로그인 버튼</strong>도
          누군가 적어 둔 코드입니다. "버튼이 눌리면 → 아이디·비밀번호를 서버로 보내고 →
          맞으면 대시보드를 보여줘"라는 지시문이죠. 이 페이지에서 그 코드를 직접 보게 됩니다.
        </p>
        <TryIt>
          로그아웃했다가 비밀번호를 일부러 틀리게 입력해 보세요. "아이디 또는 비밀번호가 맞지
          않아요"라는 문구가 뜨는데, 그 문구도 아래 ②에서 볼 코드 안에 글자 그대로 적혀 있습니다.
        </TryIt>
      </Section>

      <Section number="②" title="변수와 함수 — 이 앱의 로그인 코드">
        <p>
          <strong>변수</strong>는 값을 담아 두는 이름표, <strong>함수</strong>는 여러 줄의
          지시를 묶어 이름을 붙인 것입니다. 아래는 이 앱 로그인 페이지의 실제 코드입니다.
        </p>
        <CodeBlock title="frontend/src/pages/LoginPage.jsx (일부)">{CODE_LOGIN_STATE}</CodeBlock>
        <p>
          <code>useState('')</code>는 React식 변수 선언입니다. <code>username</code>은 현재
          값, <code>setUsername</code>은 값을 바꾸는 함수인데, 이 함수로 값을 바꾸면 React가
          "값이 바뀌었네? 화면도 다시 그리자"라고 알아챕니다. 여러분이 입력창에 한 글자 칠
          때마다 이 일이 일어나고 있습니다.
        </p>
        <p style={{ marginTop: 8 }}>
          <code>handleSubmit</code> 함수는 "로그인 버튼이 눌리면 할 일" 묶음입니다.{' '}
          <code>try</code>(시도하고) / <code>catch</code>(실패하면 이렇게) 구조로 "비밀번호가
          틀렸을 때"까지 미리 준비해 둔 점을 눈여겨보세요.
        </p>
        <TryIt>
          에디터에서 <code>frontend/src/pages/LoginPage.jsx</code>를 열어 이 코드를 찾아보세요.
          에러 문구를 다른 문장으로 바꾸고 저장하면, 브라우저에 바로 반영됩니다.
        </TryIt>
      </Section>

      <Section number="③" title="조건과 반복 — 체크리스트가 그려지는 원리">
        <p>
          대시보드의 체크리스트는 항목 하나하나를 손으로 그린 게 아닙니다. 서버가 준
          목록(배열)을 <strong>반복</strong>해서 같은 모양으로 찍어냅니다. 아래가 그 실제
          코드입니다.
        </p>
        <CodeBlock title="frontend/src/pages/DashboardPage.jsx (일부)">
          {CODE_DASHBOARD_MAP}
        </CodeBlock>
        <p>
          <code>.map()</code>은 "배열의 각 항목마다 이 모양을 하나씩 만들어라"라는 반복
          도구입니다. 항목이 5개면 체크박스 5개, 20개면 20개가 자동으로 만들어집니다.
        </p>
        <p style={{ marginTop: 8 }}>
          <strong>조건</strong>도 들어 있습니다. <code>done ? ' done' : ''</code>은 "체크됐으면
          done이라는 CSS 클래스를 붙이고, 아니면 붙이지 마라"라는 뜻입니다. 풀어 쓰면 이런
          if문과 같습니다: "만약 체크됐다면 → 회색 취소선 스타일, 아니면 → 보통 스타일".
          체크박스를 누를 때 글자에 취소선이 생기는 이유가 바로 이 한 줄입니다.
        </p>
        <svg
          className="diagram"
          viewBox="0 0 640 366"
          xmlns="http://www.w3.org/2000/svg"
          role="img"
          aria-label="체크리스트가 그려지는 흐름도: 서버가 준 배열을 map으로 반복하고, 항목마다 done 조건을 검사해 취소선 스타일 또는 보통 스타일로 화면에 출력한다"
        >
          <rect x="20" y="52" width="150" height="64" rx="8" fill="var(--card)" stroke="var(--line)" />
          <text x="95" y="78" textAnchor="middle" fontSize="14" fontWeight="700" fill="var(--ink)">서버가 준 목록</text>
          <text x="95" y="98" textAnchor="middle" fontSize="12" fill="var(--muted)">(배열)</text>
          <line x1="170" y1="84" x2="209" y2="84" stroke="var(--muted)" strokeWidth="1.5" />
          <path d="M218 84 l-9 -5 v10 z" fill="var(--muted)" />
          <rect x="218" y="52" width="150" height="64" rx="8" fill="var(--card)" stroke="var(--primary)" strokeWidth="1.5" />
          <text x="293" y="78" textAnchor="middle" fontSize="14" fontWeight="700" fill="var(--ink)">.map() 반복</text>
          <text x="293" y="98" textAnchor="middle" fontSize="12" fill="var(--muted)">항목마다 한 번씩</text>
          <line x1="368" y1="84" x2="396" y2="84" stroke="var(--muted)" strokeWidth="1.5" />
          <path d="M405 84 l-9 -5 v10 z" fill="var(--muted)" />
          <path d="M470 40 L535 84 L470 128 L405 84 Z" fill="var(--card)" stroke="var(--amber)" strokeWidth="1.5" />
          <text x="470" y="80" textAnchor="middle" fontSize="13" fontWeight="700" fill="var(--ink)">체크됐나?</text>
          <text x="470" y="99" textAnchor="middle" fontSize="11" fill="var(--muted)">(done 조건)</text>
          <polyline points="470,128 470,160 360,160 360,181" fill="none" stroke="var(--muted)" strokeWidth="1.5" />
          <path d="M360 190 l-5 -9 h10 z" fill="var(--muted)" />
          <text x="478" y="152" fontSize="12" fontWeight="700" fill="var(--teal)">예</text>
          <polyline points="535,84 563,84 563,181" fill="none" stroke="var(--muted)" strokeWidth="1.5" />
          <path d="M563 190 l-5 -9 h10 z" fill="var(--muted)" />
          <text x="570" y="108" fontSize="12" fontWeight="700" fill="var(--rose)">아니오</text>
          <rect x="285" y="190" width="150" height="60" rx="8" fill="var(--card)" stroke="var(--teal)" />
          <text x="360" y="215" textAnchor="middle" fontSize="13" fontWeight="700" fill="var(--ink)">취소선 스타일</text>
          <text x="360" y="235" textAnchor="middle" fontSize="11.5" fill="var(--muted)">done 클래스 붙음</text>
          <rect x="490" y="190" width="146" height="60" rx="8" fill="var(--card)" stroke="var(--line)" />
          <text x="563" y="215" textAnchor="middle" fontSize="13" fontWeight="700" fill="var(--ink)">보통 스타일</text>
          <text x="563" y="235" textAnchor="middle" fontSize="11.5" fill="var(--muted)">클래스 없음</text>
          <line x1="360" y1="250" x2="360" y2="287" stroke="var(--muted)" strokeWidth="1.5" />
          <path d="M360 296 l-5 -9 h10 z" fill="var(--muted)" />
          <line x1="563" y1="250" x2="563" y2="287" stroke="var(--muted)" strokeWidth="1.5" />
          <path d="M563 296 l-5 -9 h10 z" fill="var(--muted)" />
          <rect x="285" y="296" width="351" height="56" rx="8" fill="var(--card)" stroke="var(--line)" />
          <text x="460" y="320" textAnchor="middle" fontSize="14" fontWeight="700" fill="var(--ink)">화면에 체크박스 한 줄 출력</text>
          <text x="460" y="340" textAnchor="middle" fontSize="12" fill="var(--muted)">항목 수만큼 자동으로 그려진다</text>
          <polyline points="285,324 230,324 230,125" fill="none" stroke="var(--primary)" strokeWidth="1.5" strokeDasharray="4 4" />
          <path d="M230 116 l-5 9 h10 z" fill="var(--primary)" />
          <text x="238" y="170" fontSize="11.5" fontWeight="700" fill="var(--primary)">다음 항목</text>
        </svg>
        <p className="muted" style={{ fontSize: 12.5, textAlign: 'center', marginTop: 2 }}>
          그림: 배열 → 반복(.map) → 조건(done?) → 화면 출력 — 체크리스트 한 줄이 그려지는 흐름
        </p>
        <TryIt>
          대시보드에서 아무 항목이나 체크해 보세요. 글자 색이 바뀌고 취소선이 생기는 순간,
          위 코드의 <code>done</code>이 false에서 true로 바뀐 것입니다.
        </TryIt>
      </Section>

      <Section number="④" title="프론트엔드와 백엔드 — 왜 둘로 나뉘어 있을까?">
        <p>
          이 앱은 두 개의 프로그램이 협력합니다. <strong>프론트엔드</strong>(React)는
          여러분의 브라우저에서 실행되며 화면을 그리고, <strong>백엔드</strong>(Spring
          Boot)는 회사 서버에서 실행되며 데이터를 지키고 규칙을 검사합니다.
        </p>
        <CodeBlock title="로그인 한 번에 일어나는 일">{DIAGRAM_FRONT_BACK}</CodeBlock>
        <p>
          왜 나눌까요? 브라우저에서 도는 코드는 <strong>사용자가 얼마든지 열어보고 고칠 수
          있기 때문</strong>입니다. "비밀번호가 맞는지"를 브라우저에서 검사하면, 검사 코드를
          지워버리고 통과할 수 있겠죠. 그래서 믿을 수 있는 판단(로그인, 권한, 저장)은 전부
          서버가 하고, 프론트는 그 결과를 보기 좋게 그리는 역할을 맡습니다.
        </p>
        <p style={{ marginTop: 8 }}>
          둘 사이의 대화가 바로 <code>/api/...</code>로 시작하는 요청들입니다. 이 앱의 모든
          페이지는 <code>client.get(...)</code>, <code>client.post(...)</code>로 서버와
          대화합니다.
        </p>
        <TryIt>
          브라우저에서 F12를 눌러 개발자 도구를 열고 [Network] 탭을 켠 채 대시보드의 주차
          탭을 눌러 보세요. <code>/api/checklist?week=2</code> 같은 요청이 실제로 오가는 게
          보입니다.
        </TryIt>
      </Section>

      <Section number="⑤" title="데이터베이스 — 체크 하나가 테이블의 한 줄이 된다">
        <p>
          서버가 껐다 켜져도 여러분의 체크 기록이 남는 이유는{' '}
          <strong>데이터베이스(PostgreSQL)</strong>에 저장되기 때문입니다. 데이터베이스는
          엑셀 표와 비슷한 "테이블"들의 모음이고, 체크리스트에서 체크 하나를 누를 때마다
          진행 기록 테이블에 한 줄이 생기거나 지워집니다.
        </p>
        <p style={{ marginTop: 8 }}>
          자바 백엔드에서는 테이블 하나를 클래스 하나로 표현합니다(이를 "엔티티"라고
          부릅니다). 아래는 여러분의 계정이 저장되는 users 테이블의 실제 코드입니다.
        </p>
        <CodeBlock title="backend/.../domain/User.java (일부)">{CODE_USER_ENTITY}</CodeBlock>
        <p>
          필드 하나가 곧 테이블의 컬럼 하나입니다. <code>unique = true</code>가 붙은{' '}
          <code>username</code>은 "같은 아이디로 두 명이 가입할 수 없다"는 규칙을
          데이터베이스 차원에서 강제합니다. 그리고 <code>passwordHash</code> — 비밀번호를
          원문 그대로 저장하지 않고 복원 불가능한 형태(해시)로만 저장하는 것은, 어떤 회사든
          지켜야 하는 기본 보안 수칙입니다.
        </p>
        <svg
          className="diagram"
          viewBox="0 0 640 264"
          xmlns="http://www.w3.org/2000/svg"
          role="img"
          aria-label="User 자바 클래스의 필드 네 개가 users 테이블의 컬럼 네 개와 하나씩 짝지어지는 그림"
        >
          <text x="320" y="34" textAnchor="middle" fontSize="12.5" fill="var(--muted)">필드 하나 = 컬럼 하나 (@Entity의 약속)</text>
          <rect x="30" y="48" width="230" height="182" rx="8" fill="var(--card)" stroke="var(--primary)" strokeWidth="1.5" />
          <text x="145" y="74" textAnchor="middle" fontSize="14" fontWeight="700" fill="var(--ink)">User 클래스 (자바)</text>
          <line x1="30" y1="88" x2="260" y2="88" stroke="var(--line)" />
          <text x="48" y="116" fontSize="13" fill="var(--ink)">Long id</text>
          <text x="48" y="148" fontSize="13" fill="var(--ink)">String username</text>
          <text x="48" y="180" fontSize="13" fill="var(--ink)">String passwordHash</text>
          <text x="48" y="212" fontSize="13" fill="var(--ink)">String track</text>
          <rect x="380" y="48" width="230" height="182" rx="8" fill="var(--card)" stroke="var(--teal)" strokeWidth="1.5" />
          <text x="495" y="74" textAnchor="middle" fontSize="14" fontWeight="700" fill="var(--ink)">users 테이블 (DB)</text>
          <line x1="380" y1="88" x2="610" y2="88" stroke="var(--line)" />
          <text x="398" y="116" fontSize="13" fill="var(--ink)">id</text>
          <text x="398" y="148" fontSize="13" fill="var(--ink)">username</text>
          <text x="398" y="180" fontSize="13" fill="var(--ink)">password_hash</text>
          <text x="398" y="212" fontSize="13" fill="var(--ink)">track</text>
          <text x="594" y="148" textAnchor="end" fontSize="11" fill="var(--amber)">중복 금지</text>
          <text x="594" y="180" textAnchor="end" fontSize="11" fill="var(--rose)">해시만 저장</text>
          <line x1="268" y1="112" x2="366" y2="112" stroke="var(--muted)" strokeWidth="1.5" />
          <path d="M375 112 l-9 -5 v10 z" fill="var(--muted)" />
          <line x1="268" y1="144" x2="366" y2="144" stroke="var(--muted)" strokeWidth="1.5" />
          <path d="M375 144 l-9 -5 v10 z" fill="var(--muted)" />
          <line x1="268" y1="176" x2="366" y2="176" stroke="var(--muted)" strokeWidth="1.5" />
          <path d="M375 176 l-9 -5 v10 z" fill="var(--muted)" />
          <line x1="268" y1="208" x2="366" y2="208" stroke="var(--muted)" strokeWidth="1.5" />
          <path d="M375 208 l-9 -5 v10 z" fill="var(--muted)" />
          <text x="145" y="252" textAnchor="middle" fontSize="11.5" fill="var(--muted)">User.java에 적는 코드</text>
          <text x="495" y="252" textAnchor="middle" fontSize="11.5" fill="var(--muted)">실제로 저장되는 표</text>
        </svg>
        <p className="muted" style={{ fontSize: 12.5, textAlign: 'center', marginTop: 2 }}>
          그림: 자바 클래스의 필드가 테이블의 컬럼과 하나씩 짝을 이룬다 (엔티티 ↔ 테이블)
        </p>
        <TryIt>
          회원가입할 때 이미 있는 아이디를 입력해 보세요. "이미 사용 중인 아이디예요"라고
          뜨는 것이 바로 위 <code>unique = true</code> 규칙이 동작한 결과입니다.
        </TryIt>
      </Section>

      <Section number="⑥" title="다음 단계 — 이제 직접 만져 볼 차례">
        <p>여기까지 왔다면 큰 그림은 잡힌 것입니다. 다음 순서로 이어가 보세요.</p>
        <ul style={{ paddingLeft: 20, marginTop: 8 }}>
          <li style={{ marginBottom: 6 }}>
            <strong>STUDY.md</strong> — 프로젝트 루트에 있는 학습 가이드 문서. 이 앱의 폴더
            구조와 코드를 어떤 순서로 읽으면 좋은지 안내합니다.
          </li>
          <li style={{ marginBottom: 6 }}>
            <strong>학습 문서(문서함)</strong> — 상단 메뉴의 "학습 문서"에 아침 수업 자료와
            주차별 커리큘럼이 있습니다. 그날 수업 전에 미리 읽어 오면 훨씬 수월합니다.
          </li>
          <li>
            <strong>직접 해보기 미니 과제</strong> — 아래 세 가지를 순서대로 시도해 보세요.
            막히면 멘토에게 질문하는 것도 실력입니다.
          </li>
        </ul>
        <div
          style={{
            background: 'var(--bg)',
            border: '1px solid var(--line)',
            borderRadius: 10,
            padding: '12px 14px',
            marginTop: 10,
            fontSize: 14,
          }}
        >
          <ol style={{ paddingLeft: 20 }}>
            <li style={{ marginBottom: 6 }}>
              로그인 페이지의 로고 문구("AWESOMEDEV 수습 플랫폼")를 내 마음대로
              바꿔서 화면에 반영해 보기 — <code>LoginPage.jsx</code>
            </li>
            <li style={{ marginBottom: 6 }}>
              대시보드의 주차 배열 <code>WEEKS</code>에 9를 추가하면 무슨 일이 생기는지
              관찰하고, 왜 그런지 설명해 보기 — <code>DashboardPage.jsx</code>
            </li>
            <li>
              개발자 도구 Network 탭으로 "과제 제출" 버튼을 눌렀을 때 서버로 어떤 데이터가
              날아가는지 확인하고 한 줄로 정리해 보기
            </li>
          </ol>
        </div>
      </Section>
    </div>
  );
}
