import fs from 'node:fs/promises';
import path from 'node:path';
import process from 'node:process';

const KST_DATE_FORMATTER = new Intl.DateTimeFormat('en-CA', {
  timeZone: 'Asia/Seoul',
  year: 'numeric',
  month: '2-digit',
  day: '2-digit',
});

const WORKLOG_TEMPLATE = `# {date} 작업일지

## 오늘 작업

- 화면 캡처 추가 예정

## 스크린샷

- 저장소 기준 연결된 스크린샷 없음

## 소스

### 파일 1: \`path/to/file.tsx\`

- 변경 목적과 핵심 수정 내용을 한 줄로 정리

\`\`\`diff
# 이 파일의 핵심 diff
- before
+ after
\`\`\`

### 파일 2: \`path/to/another-file.ts\`

- 필요 없으면 이 섹션은 삭제

## 실행 커맨드

\`\`\`bash
\`\`\`

## 변경 파일

-
`;

const OBSOLETE_WORKLOG_SECTION_TITLES = new Set([
  '커밋 목록',
  '변경 요약',
  '변경 통계',
  '라인 통계',
]);

function normalizeLevelTwoHeading(section) {
  const match = section.match(/^##\s+([^\n]+)$/m);

  if (!match) {
    return '';
  }

  return match[1]?.replace(/\s+\(.*\)\s*$/u, '').trim() ?? '';
}

function stripObsoleteWorklogSections(content) {
  const sections = content.split(/\n(?=##\s+)/);
  const preservedSections = sections.filter((section) => {
    const normalizedHeading = normalizeLevelTwoHeading(section);
    return !OBSOLETE_WORKLOG_SECTION_TITLES.has(normalizedHeading);
  });

  return `${preservedSections.join('\n\n').replace(/\n{3,}/g, '\n\n').trimEnd()}\n`;
}

export async function ensureDirectory(dirPath) {
  await fs.mkdir(dirPath, { recursive: true });
}

export function getKstDate(date = new Date()) {
  return KST_DATE_FORMATTER.format(date);
}

export async function ensureWorklogFile(worklogPath, captureDate) {
  try {
    await fs.access(worklogPath);
    const content = await fs.readFile(worklogPath, 'utf8');
    const normalizedContent = stripObsoleteWorklogSections(content);

    if (normalizedContent !== content) {
      await fs.writeFile(worklogPath, normalizedContent, 'utf8');
    }
  } catch {
    await ensureDirectory(path.dirname(worklogPath));
    const content = WORKLOG_TEMPLATE.replaceAll('{date}', captureDate);
    await fs.writeFile(worklogPath, content, 'utf8');
  }
}

export async function updateWorklogCaptureSection({
  worklogPath,
  captureDate,
  imageAlt,
  markdownImagePath,
}) {
  await ensureWorklogFile(worklogPath, captureDate);

  const imageLine = `![${imageAlt}](${markdownImagePath})`;
  let content = await fs.readFile(worklogPath, 'utf8');

  if (content.includes(imageLine)) {
    return;
  }

  if (!content.includes('## 스크린샷') && !content.includes('## 화면 캡처')) {
    content += `\n\n## 스크린샷\n\n${imageLine}\n`;
    await fs.writeFile(worklogPath, content, 'utf8');
    return;
  }

  const sections = content.split(/\n(?=##\s+)/);
  const screenshotSections = [];
  const remainingSections = [];

  for (const section of sections) {
    if (/^##\s+(?:스크린샷|화면 캡처)\s*$/m.test(section)) {
      screenshotSections.push(section);
    } else {
      remainingSections.push(section);
    }
  }

  const mergedScreenshotBody = screenshotSections
    .map((section) => section.replace(/^##\s+(?:스크린샷|화면 캡처)\s*$/m, '').trim())
    .filter(Boolean)
    .join('\n\n');

  const screenshotLines = Array.from(
    new Set(
      [mergedScreenshotBody, imageLine]
        .join('\n')
        .split('\n')
        .map((line) => line.trim())
        .filter((line) => line && line !== '- 저장소 기준 연결된 스크린샷 없음'),
    ),
  );

  const mergedScreenshotSection = `## 스크린샷\n\n${screenshotLines.join('\n')}`.trim();
  const sourceSectionIndex = remainingSections.findIndex((section) => /^##\s+소스\s*$/m.test(section));

  if (sourceSectionIndex === -1) {
    remainingSections.push(mergedScreenshotSection);
  } else {
    remainingSections.splice(Math.max(1, sourceSectionIndex), 0, mergedScreenshotSection);
  }

  content = remainingSections.join('\n\n').replace(/\n{3,}/g, '\n\n').trimEnd() + '\n';
  await fs.writeFile(worklogPath, content, 'utf8');
}

export function resolveCapturePaths({
  cwd = process.cwd(),
  captureDate,
  screenshotFileName,
}) {
  const screenshotDir = path.join(cwd, 'docs', 'assets', 'worklogs', captureDate);
  const screenshotPath = path.join(screenshotDir, screenshotFileName);
  const worklogPath = path.join(cwd, 'docs', 'worklogs', `${captureDate}.md`);
  const markdownImagePath = `../assets/worklogs/${captureDate}/${screenshotFileName}`;

  return {
    screenshotDir,
    screenshotPath,
    worklogPath,
    markdownImagePath,
  };
}
