// MKT-01 · 30일 콘텐츠 캘린더 자동 생성
// 난이도 ★ · 예상 30분 · 전제: 구글 계정 + Gemini API 키
// 출처: https://www.nedabah.org/resources/automation/marketing/01-content-calendar-generator.html
// Apps Script 편집기에 붙여넣은 뒤 스크립트 속성에 PROPS 항목을 등록하세요.

const PROPS = PropertiesService.getScriptProperties();
const SHEET_ID  = PROPS.getProperty('SHEET_ID');
const GEMINI    = PROPS.getProperty('GEMINI_API_KEY');

function onOpen() {
  SpreadsheetApp.getUi()
    .createMenu('🤖 콘텐츠 자동화')
    .addItem('30일 캘린더 생성', 'generateCalendar')
    .addItem('선택 행 다시 쓰기', 'regenerateRow')
    .addToUi();
}

function readInputs() {
  const ss = SpreadsheetApp.openById(SHEET_ID);
  const inp = Object.fromEntries(ss.getSheetByName('input').getDataRange().getValues().slice(1));
  const pillars = ss.getSheetByName('pillars').getRange('A2:A').getValues().flat().filter(Boolean);
  const channels = String(inp['채널']||'').split(',').map(s=>s.trim()).filter(Boolean);
  return {
    theme: inp['월 테마'], business: inp['비즈니스'], target: inp['타깃'],
    channels, tone: inp['톤'], startDate: new Date(inp['시작일']),
    pillars
  };
}

function generateCalendar() {
  const ui = SpreadsheetApp.getUi();
  const i = readInputs();
  if (!i.theme || !i.channels.length) {
    ui.alert('input 탭의 월 테마/채널을 먼저 입력하세요.'); return;
  }

  const prompt = buildMonthPrompt(i);
  const items = callGemini(prompt); // [{date, channel, format, headline, hook, body, cta, hashtags}, ...]

  const cal = SpreadsheetApp.openById(SHEET_ID).getSheetByName('calendar');
  cal.clearContents();
  cal.appendRow(['날짜','채널','형식','헤드라인','후크','본문 가이드','CTA','해시태그','상태']);
  items.forEach(it => cal.appendRow([
    it.date, it.channel, it.format, it.headline, it.hook, it.body, it.cta, (it.hashtags||[]).join(' '), '예정'
  ]));
  ui.alert(`✅ ${items.length}건 생성 완료`);
}

function buildMonthPrompt(i) {
  const pillarLine = i.pillars.length ? `다음 콘텐츠 기둥을 균형 있게 분배: ${i.pillars.join(', ')}` : '주제는 자율적으로 다양화';
  return `
당신은 ${i.business} 도메인의 시니어 콘텐츠 디렉터입니다.
다음 정보로 30일 콘텐츠 캘린더를 작성하세요.

월 테마: ${i.theme}
타깃: ${i.target}
채널: ${i.channels.join(', ')}
톤: ${i.tone}
시작일: ${i.startDate.toISOString().slice(0,10)}
${pillarLine}

규칙:
- 각 채널 특성에 맞춰 톤·형식 분기 (예: 블로그=long, 인스타=짧은 후크+이미지 가이드, 링크드인=인사이트, 뉴스레터=주제 묶음)
- 같은 주제도 채널별 변주
- 날짜는 시작일부터 30일, 하루에 1~2건 배치 (총 약 30~40건)
- 헤드라인은 12~22자, 후크는 1문장, 본문 가이드는 50자 이내, CTA는 명확한 행동 1개, 해시태그 3~6개
- 자기과시·과장 금지

JSON 배열만 반환:
[{"date":"YYYY-MM-DD","channel":"...","format":"long|short|image|reel|email","headline":"...","hook":"...","body":"...","cta":"...","hashtags":["..."]}]
`;
}

function callGemini(prompt) {
  const url = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=${GEMINI}`;
  const res = UrlFetchApp.fetch(url, {
    method:'post', contentType:'application/json',
    payload: JSON.stringify({
      contents:[{parts:[{text: prompt}]}],
      generationConfig:{responseMimeType:'application/json', maxOutputTokens: 8192}
    })
  });
  return JSON.parse(JSON.parse(res.getContentText()).candidates[0].content.parts[0].text);
}

function regenerateRow() {
  const ss = SpreadsheetApp.openById(SHEET_ID);
  const sh = ss.getSheetByName('calendar');
  const r  = sh.getActiveCell().getRow();
  if (r === 1) return;
  const row = sh.getRange(r, 1, 1, 9).getValues()[0];
  const [date, channel, format, headline] = row;

  const i = readInputs();
  const prompt = `
다음 한 건만 새로운 변형으로 다시 작성하세요(같은 날짜·채널·형식 유지).
원본 헤드라인: ${headline}
월 테마: ${i.theme}, 타깃: ${i.target}, 톤: ${i.tone}

JSON 단일 객체:
{"headline":"...","hook":"...","body":"...","cta":"...","hashtags":["..."]}
`;
  const o = JSON.parse(JSON.parse(UrlFetchApp.fetch(
    `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=${GEMINI}`,
    {method:'post', contentType:'application/json',
     payload: JSON.stringify({contents:[{parts:[{text:prompt}]}], generationConfig:{responseMimeType:'application/json'}})}
  ).getContentText()).candidates[0].content.parts[0].text);

  sh.getRange(r, 4).setValue(o.headline);
  sh.getRange(r, 5).setValue(o.hook);
  sh.getRange(r, 6).setValue(o.body);
  sh.getRange(r, 7).setValue(o.cta);
  sh.getRange(r, 8).setValue((o.hashtags||[]).join(' '));
}