/**
 * `/youtube` slash command 의 LLM 입력 빌더 + 자막 변환 헬퍼.
 *   - formatHms / fullScriptFromSegments / bucketSegments — segment list 가공
 *   - YoutubeAnalysisMode — info/benchmark/both 라우팅 enum (slashRouter 가 사용)
 *   - buildInfoExtractionPrompt — *영상 내용(지식)* 카드 추출 프롬프트
 *   - build4LensPrompt — 영상 *제작 기법* (훅/구조/제작/CTR) 4-렌즈 분석 프롬프트
 *
 * 옛 코드: slashRouter.ts 의 320줄짜리 inline 블록. 분리해 (a) 두 프롬프트가 같은
 * segment 변환 helper 를 자연스럽게 공유, (b) 새 모드 추가 시 한 파일만 수정,
 * (c) 단위 테스트로 prompt 회귀 확인 가능.
 */

export function formatHms(totalSec: number): string {
    if (!isFinite(totalSec) || totalSec <= 0) return '00:00';
    const s = Math.floor(totalSec);
    const h = Math.floor(s / 3600);
    const m = Math.floor((s % 3600) / 60);
    const sec = s % 60;
    return h > 0
        ? `${h}:${String(m).padStart(2, '0')}:${String(sec).padStart(2, '0')}`
        : `${m}:${String(sec).padStart(2, '0')}`;
}

/**
 * 영상 전체 자막을 30초 버킷으로 묶어 `[mm:ss] 문장…` 형태의 읽기 좋은 full script로 변환.
 * YouTube 자동자막은 segment가 잘게 끊겨 그대로 나열하면 가독성이 나쁘므로 묶는다.
 */
export function fullScriptFromSegments(segments: any[] | undefined): string {
    if (!segments || segments.length === 0) return '(자막 없음 — 자동 자막이 없는 영상일 수 있습니다.)';
    const buckets = new Map<number, string[]>();
    for (const seg of segments) {
        const b = Math.floor((seg.start || 0) / 30);
        const arr = buckets.get(b) || [];
        arr.push(String(seg.text || '').trim());
        buckets.set(b, arr);
    }
    return Array.from(buckets.entries())
        .sort((a, b) => a[0] - b[0])
        .map(([b, texts]) => `**[${formatHms(b * 30)}]** ${texts.join(' ').replace(/\s+/g, ' ').trim()}`)
        .join('\n\n');
}

/**
 * timestamped segments → 분 단위 버킷으로 묶은 "타임라인 뼈대" 텍스트.
 * §2 구조 분석에서 LLM 토큰을 아낀다.
 */
export function bucketSegments(segments: any[] | undefined, bucketSec = 30): { time: string; text: string }[] {
    if (!segments || segments.length === 0) return [];
    const buckets = new Map<number, string[]>();
    for (const seg of segments) {
        const bucket = Math.floor(seg.start / bucketSec);
        const arr = buckets.get(bucket) || [];
        arr.push(String(seg.text || '').trim());
        buckets.set(bucket, arr);
    }
    return Array.from(buckets.entries())
        .sort((a, b) => a[0] - b[0])
        .map(([bucket, texts]) => ({
            time: formatHms(bucket * bucketSec),
            text: texts.join(' ').replace(/\s+/g, ' ').trim().slice(0, 240),
        }));
}

/** Astra `/youtube` 의 분석 모드. 사용자 입력 `mode:info|benchmark|both`. */
export type YoutubeAnalysisMode = 'info' | 'benchmark' | 'both';

/**
 * 정보 추출(info) 모드 LLM 프롬프트 — 영상의 *내용·지식* 자체를 다룬다.
 *
 * 의도: build4LensPrompt 가 "이 영상을 어떻게 베껴 만들지" 의 벤치마킹 톤이라
 * 튜토리얼·강의·뉴스·인터뷰·리뷰 같은 정보형 영상에서는 가치가 낮다. 이 함수는
 * 정반대 방향 — 영상이 *말한 것* 을 사실·주장·근거 단위로 추출해서, 사용자가
 * 영상을 안 다시 봐도 의사결정·학습·인용에 바로 쓸 수 있는 지식 카드로 정리한다.
 *
 * 출력 규칙은 build4LensPrompt 와 일관 (마크다운, 한국어, 자막에 있는 것만 인용).
 */
export function buildInfoExtractionPrompt(video: any, userContent: string): string {
    const meta = video.metadata || {};
    const segments = video.segments || [];

    // 자막 본문 — info 모드는 *전체* 본문을 보여줘야 사실 추출이 정확. 단,
    // LLM 컨텍스트 한도 고려해 너무 길면 trim. 12000자 = 가벼운 강의 60분 분량 정도.
    const fullText = segments.map((s: any) => String(s.text || '').trim()).join(' ').replace(/\s+/g, ' ');
    const trimmed = fullText.length > 12000 ? fullText.slice(0, 12000) + ' …[자막 일부 잘림]' : fullText;

    const slim = {
        url: meta.webpage_url || `https://www.youtube.com/watch?v=${video.video_id}`,
        title: meta.title || video.title,
        channel: meta.channel,
        durationSec: meta.duration,
        durationHms: meta.duration_string,
        uploadDate: meta.upload_date,
        viewCount: meta.view_count,
        likeCount: meta.like_count,
        tags: (meta.tags || []).slice(0, 8),
        categories: meta.categories,
        chapters: meta.chapters,
        descriptionPreview: (meta.description || '').slice(0, 600),
    };

    const today = new Date().toISOString().slice(0, 10);
    const userBlock = userContent.trim()
        ? `\n\n[사용자 컨텍스트 — 사용자가 어떤 관점에서 이 영상을 활용하려는지]\n${userContent.trim()}`
        : '';

    return `당신은 영상 콘텐츠를 *지식 카드*로 변환하는 정보 큐레이터입니다. 사장님이
이 영상을 다시 보지 않고도 핵심 정보를 그대로 활용할 수 있도록, 영상이 *말한 것*
(주장·사실·근거·결론)을 구조화해서 정리하세요.

[분석 원칙 — 모두 반드시 준수]
1. **출처 분리** — 영상 본문(자막)에 *명시된 것* 만 핵심 섹션에 넣음. 정리자의 추론·외부
   지식·자기 해석은 별도 \`## 🧩 정리자 노트\` 섹션에만. 두 줄 섞지 말 것.
2. **빈 곳 채우지 말 것** — 자막에 없는 사실은 "본문에 명시되지 않음" 또는 "해당 사례 없음".
3. **신뢰도 라벨 필수** — 모든 핵심 주장 앞에 다음 중 하나:
   - \`[근거 명시]\` 구체 출처·수치·인용이 본문에 있음
   - \`[화자 주장]\` 출처 없는 단정 (디노가 그렇게 말함)
   - \`[가정]\` 조건부·"~인 것 같다" 표현
   - \`[정리자 추론]\` 본문에 없지만 정리자가 추가 (이건 정리자 노트 섹션 전용)
4. **타임스탬프 필수** — 본문 인용·구간 요약·발언 따옴표는 끝에 \`(mm:ss)\` 무조건 붙임.
   이걸 빠뜨리면 fail. "(시점 미상)" 도 허용 안 함 — 모르면 인용 자체 빼기.
5. **화자 한 줄 비유 보존 + 방향 보존** — 영상에 비유·은유·"X 는 Y 같은 것" 식 압축 표현이
   있으면 반드시 별도 섹션 \`## 💡 화자 한 줄 비유\` 에 보존. 영상의 결정적 요약이 거기
   들어 있을 가능성 큼. 없으면 "본문에 명시된 한 줄 비유 없음" 명시.
   ⚠️ **비유는 방향이 뒤집히기 쉬움** — 화자가 "Hugging Face = 자료실, Reddit = 공부방"
   이라 했으면 정확히 그 짝(어느 쪽이 자료실이고 어느 쪽이 공부방인지)을 그대로 따옴표
   인용으로 보존. 정리자가 단어 위치를 바꾸거나 뜻을 의역하면 안 됨. 고유명사·수치·
   대응 관계도 마찬가지 — 본문 그대로.
6. **순서·단계 발명 금지** — 화자가 "A → B → C 순서로" 라고 명시하지 *않았으면* "단계적
   학습 순서" 같은 흐름을 정리자가 만들지 말 것. 굳이 필요하면 정리자 노트로.
7. 한국어 마크다운. **헤더에 이모지 금지** — 스캔할 때 시선이 분산되어 내용이 가려진다.
8. **표 사용 신중** — 모든 셀이 명확한 값으로 채워질 확신이 없으면 표 만들지 말고 bullet로. 깨진 셀(\`way\` 같은 LLM artifact)·빈 셀·"…" placeholder 절대 노출 금지.
9. **중복 금지** — 같은 내용은 한 곳에만. "한 줄 요약"이 여러 섹션에 반복되면 안 됨. 30초 요약에 한 번, 끝.

[영상 메타데이터]
\`\`\`json
${JSON.stringify(slim, null, 2)}
\`\`\`

[자막 본문]
${trimmed}${userBlock}

[필수 출력 형식 — 정확히 이 구조. 아래 4개 ## 섹션 외 추가 금지. 3-tier 깊이: ① 30초 요약(skim) → ② 핵심 개념(이해) → ③ 깊이 분석(deep dive). 읽는 사람이 목적에 따라 멈출 수 있게.]

# ${slim.title || video.title} — 정보 추출 카드

> **영상 URL**: ${slim.url} · **분석 일자**: ${today} · **길이**: ${slim.durationHms || (slim.durationSec ? formatHms(slim.durationSec) : '?')} · **채널**: ${slim.channel || '?'}

> 신뢰도 라벨: \`[근거 명시]\` 본문 출처/수치 · \`[화자 주장]\` 출처 없는 단정 · \`[가정]\` 조건부 · \`[정리자 추론]\` 정리자 노트 전용

---

## 30초 요약

*바쁜 사람은 여기서 멈춰도 영상을 안 본 것보다 낫게.*

- **한 줄**: 영상 전체를 한 문장으로 — "무엇이 누구에게 왜 중요한가". 화자 표현 기준, 정리자 의역 금지.
- **핵심 포인트 3개**: 영상이 *명시한* 결론·주장만 (정리자 추론 금지). 각 항목 신뢰도 라벨 + 한 줄 + 타임스탬프.
  1. **[근거 명시]** ... — (mm:ss)
  2. **[화자 주장]** ... — (mm:ss)
  3. ... — (mm:ss)
- **화자 한 줄 비유** (있는 경우만): 화자가 *전체 메시지를 한 줄로 압축한 비유·은유* 그대로 따옴표.
  ⚠️ 방향 보존 필수 — "Hugging Face = 자료실, Reddit = 공부방" 같으면 짝과 순서를 본문 그대로. 정리자가 단어 위치를 바꾸거나 의역하면 안 됨. 고유명사·수치·대응관계도 본문 그대로.
  예: "..." — (mm:ss). 본문에 비유 없으면 이 bullet 통째로 생략(line drop).

---

## 핵심 개념 설명

*개념을 이해하고 싶은 사람을 위해.*

영상이 다룬 *주요 개념·용어* 2-5개. 각각 정의 + 영상에서의 등장 맥락. 영상이 개념 위주가 아니라 사례·잡담·일화 위주면 이 ## 섹션 통째로 한 줄로 갈음: "이 영상은 개념보다 사례·주장 위주 — 핵심은 30초 요약 참조."

### {개념 이름 1}
- **정의**: 화자가 어떻게 정의했는지 (또는 일반 정의 + 화자 사용 방식).
- **영상에서**: "직접 인용" — (mm:ss). 등장 맥락 1-2문장.

### {개념 이름 2}
- **정의**: ...
- **영상에서**: ...

---

## 깊이 분석

*깊게 보고 싶은 사람을 위한 추가 자료.*

### 타임라인
영상 30분 이상이면 chapters(메타데이터에 있으면 사용) 또는 흐름 단위로 4-7개 구간 압축. 30분 미만이면 이 sub-section 통째로 한 줄: "영상이 짧아 생략."
- **[mm:ss–mm:ss]** 구간 핵심 한 문장
- ...

### 결정적 발언 (인용용)
글·발표·메모에 그대로 복붙 가능한 *한 문장 인용* 3-5개. 타임스탬프 필수. 위 30초 요약의 핵심 포인트와 중복되는 인용은 빼고, 보조 발언 위주로.
- "직접 인용 한 문장" — ${slim.channel || '?'} (mm:ss)
- ...

### 더 파고들 질문
영상이 답하지 않았거나 추가 검증 필요한 사항 2-4개. 사장님이 다음 자료를 찾을 때 검색어로 쓸 수 있게 구체적으로.
- "본문에서 X 가 Y 라고 했지만 Z 데이터 출처는 명시 안 됨 — 원 데이터 찾아볼 것"
- ...

### 구체 수치·데이터
**표 만들지 말 것** — bullet로, *완성된 정보만*. 본문에 모호하거나 정리자 추측이 들어가야 할 데이터는 통째로 생략. 항목: \`{이름}: {값} (mm:ss)\` 형태.
- ...
(본문에 명시된 구체 수치 없으면 이 sub-section 통째로 한 줄: "본문에 명시된 구체 수치 없음.")

---

## 정리자 노트 (선택)

*본문에 없지만* 정리자가 추가로 짚고 싶은 맥락·해석·연결·경고. 모두 \`[정리자 추론]\` 라벨로 시작 — 독자가 "이건 화자가 말한 게 아니라 LLM이 추론한 것"으로 즉시 식별.
- **[정리자 추론]** ...
- ...

보강할 게 없으면 이 ## 섹션 통째로 한 줄: "정리자 추가 노트 없음 — 본문 그대로가 명확함."`;
}

/**
 * extract된 영상 → 유튜브 4-렌즈(훅/구조/제작/CTR) 분석 LLM 프롬프트.
 * Datacollect 웹앱(YoutubePanel)의 build4LensPrompt를 그대로 이식.
 */
export function build4LensPrompt(video: any, userContent: string): string {
    const meta = video.metadata || {};
    const segments = video.segments || [];

    // 초반 30초 / 60초 텍스트 — §1 훅 분석용.
    const first30s = segments.filter((s: any) => s.start < 30).map((s: any) => String(s.text || '').trim()).join(' ').slice(0, 600);
    const first60s = segments.filter((s: any) => s.start < 60).map((s: any) => String(s.text || '').trim()).join(' ').slice(0, 1200);

    // 타임라인 버킷 (30초 단위) — §2 구조 분석용.
    const timelineBuckets = bucketSegments(segments, 30);
    const timelinePreview = timelineBuckets.slice(0, 24).map(b => `[${b.time}] ${b.text}`).join('\n');

    // 인게이지먼트 키워드 매치 — §2 보조.
    const engagementHits = segments
        .filter((s: any) => /구독|좋아요|알림|댓글|공유|subscribe|like|comment/i.test(String(s.text || '')))
        .slice(0, 5)
        .map((s: any) => ({ t: formatHms(s.start), text: String(s.text || '').trim().slice(0, 100) }));

    const slim = {
        url: meta.webpage_url || `https://www.youtube.com/watch?v=${video.video_id}`,
        title: meta.title || video.title,
        channel: meta.channel,
        durationSec: meta.duration,
        durationHms: meta.duration_string,
        viewCount: meta.view_count,
        likeCount: meta.like_count,
        commentCount: meta.comment_count,
        uploadDate: meta.upload_date,
        thumbnail: meta.thumbnail,
        tags: (meta.tags || []).slice(0, 12),
        categories: meta.categories,
        chapters: meta.chapters,
        descriptionPreview: (meta.description || '').slice(0, 600),
        opening30s: first30s,
        opening60s: first60s,
        engagementMoments: engagementHits,
        segmentCount: segments.length,
        timelinePreview,
    };

    const today = new Date().toISOString().slice(0, 10);
    const userBlock = userContent.trim()
        ? userContent.trim()
        : '(미입력 — 일반 콘텐츠 제작자 컨텍스트로 작성)';

    return `당신은 유튜브 '대본(스크립트)' 분석 전문가이자 콘텐츠 작가입니다. 사장님이
이 영상과 비슷한 콘텐츠의 **대본을 직접 쓰려** 합니다. 영상 연출이 아니라 오직
스크립트(텍스트)와 언어 구조만 분석해, 읽자마자 자기 대본에 복붙하듯 써먹을 수 있는
'유저 친화적 역기획서'를 작성하세요.

[분석 원칙]
1. BGM·자막·컷 전환·썸네일 등 대본만으로 알 수 없는 '영상 연출' 항목은 과감히 생략한다.
   오직 스크립트(텍스트)와 언어 구조에만 집중한다.
2. 대사를 단순 인용하지 말고, 그 대사가 시청자 심리를 어떻게 건드렸는지 '언어적 장치'를
   태그로 라벨링한다. 아래 태그 어휘에서만 골라 일관되게 사용한다:
   #FOMO #권위부여 #호기심갭 #사회적증명 #페르소나 #약속Promise #공감후킹
   #반전 #숫자강조 #문제고발 #브릿지멘트 #쉬운비유
3. 전문 용어가 나오면, 화자가 그것을 어떤 '쉬운 비유'나 일상어로 풀어 말했는지
   그 구어체 '말의 맛'을 반드시 분석에 포함한다.
4. 한국어. 자막(text)·chapters·메타데이터에 있는 것만 인용(추측 금지). 타임스탬프는 mm:ss.

[영상 데이터]
\`\`\`json
${JSON.stringify(slim, null, 2)}
\`\`\`

[우리가 만들고 싶은 콘텐츠 / 채널 컨텍스트]
${userBlock}

[필수 출력 형식 — 정확히 이 구조. 아래 5개 섹션 외 추가 금지]

# ${slim.title || video.title} — 대본 역기획서

> **영상 URL**: ${slim.url} · **분석 일자**: ${today} · **길이**: ${slim.durationHms || (slim.durationSec ? formatHms(slim.durationSec) : '?')} · **채널**: ${slim.channel || '?'}

## 🎬 한 줄 인상 (One-line Read)
(이 영상 스크립트의 핵심 성격과 설득 전략을 한 줄로. 예: "전문 지식을 친구에게
설명하듯 풀어내고, 호기심 갭으로 끝까지 끌고 가는 정보형 대본")

## 1. 스크립트 뼈대 구조도 (Script Architecture)
구간별 마크다운 표 1개. '레퍼런스 실제 대사'는 자막에서 1문장 이내로 짧게 따옴표 인용.
'스크립트 기능'에는 위 태그 어휘를 1~2개 붙인다. 비중 %는 durationSec 기준,
chapters가 있으면 그것을, 없으면 timelinePreview로 구간을 추정.

| 구간 (비중) | 스크립트 기능 (태그) | 레퍼런스 실제 대사 | 벤치마킹 핵심 기술 |
| --- | --- | --- | --- |
| 오프닝 Hook (0:00~?, ?%) | #호기심갭 #약속Promise | "첫 대사…" | 결과를 미리 흘려 이탈 차단 |
| 도입부 (?~?, ?%) | … | … | … |
| 본론 (?~?, ?%) | … | … | … |
| 아웃트로·CTA (?~?, ?%) | … | … | … |

## 2. 말의 맛 & 톤앤매너 (Tone & Manner)
- **문장 길이 특징**: 단문/장문, 호흡, 리듬 — 실제 자막 예시 1개를 따옴표로.
- **어조 페르소나**: 예) 친근한 전문가체 / 단정적 신뢰체 — 근거 대사 1개.
- **핵심 대사 장치**: 시청자 중간 이탈을 막으려 대본 사이에 심은 미끼 문장·브릿지 멘트를
  타임스탬프와 함께 2~3개 추출, 각각 태그 라벨을 붙인다.
- **전문용어 → 쉬운 비유**: 어려운 개념을 화자가 어떤 비유·일상어로 풀었는지
  \`용어 → "화자의 실제 표현"\` 형태로 2~3개. 사례가 없으면 "해당 사례 없음"이라 명시.

## 3. 내 대본에 바로 쓰는 액션 체크리스트 (Action Items)
다음 대본을 쓸 때 무조건 적용할 행동 지침 3~4개. 반드시 체크박스로, 구체적 수치를 포함.
- [ ] (예: 오프닝 15초 안에 '내가 누구인지' 페르소나 한 문장 박기)
- [ ] …
- [ ] …

## ✂️ 빈칸 채우기식 대본 템플릿 (Fill-in-the-Blank)
레퍼런스의 말하기 구조·접속사·리듬은 그대로 살리고, 내 콘텐츠 내용만 [ ]에 채우면
대본이 완성되는 형태. 각 [ ] 안에는 무엇을 넣을지 짧은 힌트를 적는다.

\`\`\`
[오프닝 — Hook]
"여러분, 혹시 [시청자의 흔한 고민]… 해보신 적 있으세요?
오늘은 [이 영상이 줄 핵심 결과]를 [숫자]분 만에 끝내 드릴게요."

[도입부 — 공감 + 권위]
…

[본론 — 단계별 설명]
…

[아웃트로 — CTA]
…
\`\`\`

> ⚠️ 본 분석은 스크립트의 언어·구조 패턴 학습용입니다. 대사·자료는 직접 창작/라이선스 확보.`;
}
