// StoryDirector.ts: orchestrates per-day structure, tasks, clue gating, endings.
import { director } from './CorruptionDirector';
import { AFU_ANNOUNCE, TASKS, CLUES, NPCS, C4_GARBLE } from '../data/gamedata';
import { DialogueLine } from '../scenes/UIScene';

class StoryDirector {
  // greeting progress per day (T3/T10): count distinct NPCs greeted
  greetProgress: Record<number, Set<string>> = {};
  // bread delivery progress (T1/T8): deliver to dabao/mimi/grandpa
  breadProgress: Record<number, Set<string>> = {};
  // letters (T4): deliver 3 to yuanyuan/mimi/dr_fu
  letterProgress = new Set<string>();
  // berries (T6)
  berriesPicked = 0;
  // ribbons (T13)
  ribbonsHung = 0;
  // watering (T2/T9)
  wateredToday: Record<number, number> = {};
  // day phase: morning/afternoon/evening
  phase: 'morning'|'afternoon'|'evening'|'sleeping' = 'morning';
  // whether board announcement shown today
  announcementShown = false;
  // whether player has taken bread today (for T1/T8)
  breadTaken: Record<number, boolean> = {};
  // whether player has taken letters today (for T4)
  lettersTaken: Record<number, boolean> = {};

  resetDay() {
    this.announcementShown = false;
    this.phase = 'morning';
    this.letterProgress.clear();
  }

  // record a greeting; completes T3 (day1) / T10 (day4) when 3 distinct NPCs greeted
  recordGreet(npcKey: string) {
    const d = director.day;
    (this.greetProgress[d] ||= new Set()).add(npcKey);
    const n = this.greetProgress[d].size;
    if ((d === 1 || d === 4) && n >= 3 && !director.tasksDone.has(d === 1 ? 'T3' : 'T10')) {
      this.completeTask(d === 1 ? 'T3' : 'T10', 10);
    }
  }

  // deliver bread to an NPC (T1 day1 / T8 day4)
  deliverBread(npcKey: string, onLine: (l: DialogueLine[]) => void) {
    const d = director.day;
    if (d !== 1 && d !== 4) { onLine([{ speaker:'', text:'现在不需要送面包。' }]); return; }
    if (!this.breadTaken[d]) { onLine([{ speaker:'', text:'你还没从圆圆那里取面包呢。' }]); return; }
    const taskId = d === 1 ? 'T1' : 'T8';
    const set = (this.breadProgress[d] ||= new Set());
    if (set.has(npcKey)) { onLine([{ speaker:'', text:'已经送过了。' }]); return; }
    set.add(npcKey);
    const npc = NPCS[npcKey];
    onLine([{ speaker: npc.name, npcKey, portrait: npc.portrait.smile, text:'哇，蜂蜜面包！谢谢你！' }]);
    if (set.size >= 3) this.completeTask(taskId, 15);
  }

  // take bread from yuanyuan (T1/T8)
  takeBread(onLine: (l: DialogueLine[]) => void) {
    const d = director.day;
    if (d === 1 || d === 4) {
      this.breadTaken[d] = true;
      onLine([{ speaker:'圆圆', npcKey:'yuanyuan', portrait: NPCS.yuanyuan.portrait.smile, text:'这是蜂蜜面包，请帮我送给大宝、咪咪、龟爷爷吧！' }]);
    }
  }

  // take letters from dabao (T4 day2)
  takeLetters(onLine: (l: DialogueLine[]) => void) {
    if (director.day === 2) {
      this.lettersTaken[2] = true;
      onLine([
        { speaker:'大宝', npcKey:'dabao', portrait: NPCS.dabao.portrait.smile, text:'帮我送三封信吧，收件人是圆圆、咪咪、芙医生。' },
      ]);
    }
  }

  // deliver a letter (T4). 3rd letter shows garbled signature (C4)
  deliverLetter(npcKey: string, onLine: (l: DialogueLine[]) => void) {
    if (director.day !== 2 || !this.lettersTaken[2]) { onLine([{ speaker:'', text:'现在没有信要送。' }]); return; }
    if (this.letterProgress.has(npcKey)) { onLine([{ speaker:'', text:'这封信已经送了。' }]); return; }
    this.letterProgress.add(npcKey);
    const count = this.letterProgress.size;
    const npc = NPCS[npcKey];
    const lines: DialogueLine[] = [{ speaker: npc.name, npcKey, portrait: npc.portrait.smile, text:'收到信啦，谢谢你！' }];
    if (count === 3) {
      // garbled signature flash 0.2s (C4)
      lines.push({ speaker:'', text:`署名闪过乱码「${this.letterGarble()}」`, glitch: true });
      director.discoverClue('C4');
    }
    onLine(lines);
    if (count >= 3) this.completeTask('T4', 15);
  }

  // Get today's active tasks
  todayTasks() { return TASKS.filter(t => t.day === director.day); }

  //阿福 announcement lines (verbatim per day)
  announcementLines(): DialogueLine[] {
    const txt = AFU_ANNOUNCE[director.day] || AFU_ANNOUNCE[1];
    return [
      { speaker: '阿福', npcKey: 'afu', portrait: NPCS.afu.portrait.smile, text: txt },
    ];
  }

  // standard NPC talk lines per NPC (sample, affected by corruption via layer)
  npcTalk(npcKey: string): DialogueLine[] {
    const npc = NPCS[npcKey];
    if (!npc) return [];
    const base: Record<string, string[]> = {
      afu: ['今天也是美好的一天呀。', '大家都要开心哦。'],
      yuanyuan: ['面包刚出炉，香喷喷的！', '甜的东西能让人幸福呢。'],
      dabao: ['今天也有好多信要送。', '每一封信都通往一个朋友。'],
      mimi: ['欢迎光临～', '货架满满的，真开心呀。'],
      dr_fu: ['村里有诊所，但你不需要去那里哦。', '大家都健健康康的，真好。'],
      bird: ['（鸟儿在树梢欢快地歌唱）'],
      grandpa: [],
    };
    if (npcKey === 'grandpa') return this.grandpaLines();
    const lines = base[npcKey] || [];
    return lines.map(t => ({ speaker: npc.name, npcKey, portrait: this.portraitFor(npcKey), text: t }));
  }

  // 龟爷爷 C9 progression per D2/D4/D6
  grandpaLines(): DialogueLine[] {
    const d = director.day;
    let txt = '这里的湖水一直很平静。';
    if (d >= 6 || director.clues.has('C9')) txt = '孩子，今天是第几个今天？';
    else if (d >= 4) txt = '面包一直是那个味道。';
    // discover C9 when reaching the third line
    if (d >= 6 && !director.clues.has('C9')) director.discoverClue('C9');
    return [{ speaker: '龟爷爷', npcKey: 'grandpa', portrait: NPCS.grandpa.portrait.smile, text: txt }];
  }

  portraitFor(npcKey: string): number {
    const npc = NPCS[npcKey];
    const stage = director.stage;
    // apply individual threshold shift
    const order = ['smile','flat','off'] as const;
    let idx = 0;
    if (stage === 'S2') idx = 0;
    else if (stage === 'S3') idx = 1;
    else if (stage === 'S4') idx = 2;
    // mimi earlier
    if (npc.thresholdShift < 0) idx = Math.min(2, idx+1);
    else if (npc.thresholdShift > 0) idx = Math.max(0, idx-1);
    // dr_fu never changes
    if (npcKey === 'dr_fu') idx = 0;
    if (npcKey === 'grandpa') idx = 0; // grandpa doesn't corrupt
    const key = order[idx] as 'smile'|'flat'|'off';
    return npc.portrait[key];
  }

  // reward a task
  completeTask(taskId: string, reward: number) {
    if (director.tasksDone.has(taskId)) return;
    director.tasksDone.add(taskId);
    if (reward > 0) director.addHappiness(reward);
    director.emit('taskDone', taskId);
  }

  // letter C4 garbled signature flash (0.2s)
  letterGarble(): string { return C4_GARBLE; }
}

export const story = new StoryDirector();
