<?php
/**
 * NEWS 記事 — LISTER 互換メタ（区分・概要・メモ）+ DATE/TITLE/BODY
 */
require_once __DIR__ . '/fl-meta.php';

/** NEWS 記事フォルダ（data 直下） */
const NEWS_ARCHIVE_DIR = 'News-Archive';

const NEWS_CATEGORIES = [
    'お知らせ',
    '理事会案内',
    '理事会議事録',
    '委員会案内',
    '委員会議事録',
    '総会案内',
    '総会議事録',
    '管理者お知らせ',
];

/** PDF 添付の表示ラベル（1ファイルにつき1種類） */
const PDF_LABELS = [
    'お知らせ',
    '議案書',
    '議事録',
    '見積書',
    '参考図',
    '請求書',
    '工事報告書',
];

const PDF_LABEL_DEFAULT = '見積書';

function news_parse_categories(string $raw): array
{
    if ($raw === '') {
        return [];
    }
    $parts = preg_split('/[,、]/u', $raw);
    $out = [];
    foreach ($parts as $p) {
        $p = trim($p);
        if ($p !== '' && in_array($p, NEWS_CATEGORIES, true)) {
            $out[] = $p;
        }
    }
    return array_values(array_unique($out));
}

function news_categories_to_string(array $categories): string
{
    $valid = [];
    foreach ($categories as $c) {
        if (in_array($c, NEWS_CATEGORIES, true)) {
            $valid[] = $c;
        }
    }
    return implode(',', $valid);
}

function news_parse_content(string $content): array
{
    $meta = fl_read_meta_txt($content);
    [, $rest] = fl_split_txt_body($content);

    preg_match('/DATE:\s*(.*)/', $rest, $m1);
    preg_match('/TITLE:\s*(.*)/', $rest, $m2);
    preg_match('/BODY:\s*(.*)/s', $rest, $m3);

    return [
        'categories'  => news_parse_categories($meta['APP_CATEGORY']),
        'description' => trim($meta['APP_DESCRIPTION']),
        'memo'        => trim($meta['APP_MEMO']),
        'date'        => trim($m1[1] ?? ''),
        'title'       => trim($m2[1] ?? ''),
        'body'        => trim($m3[1] ?? ''),
    ];
}

function news_parse_file(string $path): array
{
    if (!is_file($path)) {
        return news_parse_content('');
    }
    return news_parse_content((string) file_get_contents($path));
}

function news_build_content(array $data): string
{
    $meta = [
        'APP_VERSION'     => '',
        'APP_CATEGORY'    => news_categories_to_string($data['categories'] ?? []),
        'APP_DESCRIPTION' => trim($data['description'] ?? ''),
        'APP_MEMO'        => trim($data['memo'] ?? ''),
    ];

    $date = trim($data['date'] ?? date('Y-m-d'));
    $title = trim($data['title'] ?? '');
    $body = $data['body'] ?? '';

    $newsBody = "DATE: {$date}\n";
    $newsBody .= "TITLE: {$title}\n";
    $newsBody .= "BODY:\n" . $body;

    return fl_build_txt_header($meta) . $newsBody;
}

function news_data_dir(): string
{
    return rtrim(__DIR__ . '/../data/' . NEWS_ARCHIVE_DIR, '/\\') . DIRECTORY_SEPARATOR;
}

function news_files_dir(): string
{
    return news_data_dir() . 'files' . DIRECTORY_SEPARATOR;
}

function news_files_url_prefix(): string
{
    return 'data/' . NEWS_ARCHIVE_DIR . '/files/';
}

/** 記事 ID（ファイル名）を正規化 — 編集時は .txt 付き、新規は Ymd-His.txt */
function news_normalize_article_id(string $id): string
{
    $id = trim($id);
    if ($id === '') {
        return date('Ymd-His') . '.txt';
    }
    if (strtolower(substr($id, -4)) !== '.txt') {
        $id .= '.txt';
    }
    return basename(str_replace('\\', '/', $id));
}

/** 添付ファイルの公開 URL（旧 01-news/files も参照） */
function news_resolve_attachment_url(string $filename): string
{
    $filename = basename(str_replace('\\', '/', trim($filename)));
    if ($filename === '') {
        return news_files_url_prefix();
    }

    if (is_file(news_files_dir() . $filename)) {
        return news_files_url_prefix() . rawurlencode($filename);
    }

    $legacyDir = dirname(__DIR__) . '/data/01-news/files/';
    if (is_file($legacyDir . $filename)) {
        return 'data/01-news/files/' . rawurlencode($filename);
    }

    return news_files_url_prefix() . rawurlencode($filename);
}

function news_parse_pdf_label(string $raw): string
{
    $raw = trim($raw);
    if ($raw === '' || !in_array($raw, PDF_LABELS, true)) {
        return '';
    }
    return $raw;
}

/** [pdf]ラベル|ファイル名[/pdf] または旧形式 [pdf]ファイル名[/pdf] */
function news_parse_pdf_tag_inner(string $inner): array
{
    $inner = trim($inner);
    if ($inner === '') {
        return ['label' => '', 'filename' => ''];
    }

    $pos = strpos($inner, '|');
    if ($pos !== false) {
        $label = news_parse_pdf_label(substr($inner, 0, $pos));
        $filename = basename(str_replace('\\', '/', trim(substr($inner, $pos + 1))));
        return ['label' => $label, 'filename' => $filename];
    }

    return [
        'label'    => '',
        'filename' => basename(str_replace('\\', '/', $inner)),
    ];
}

function news_build_pdf_tag(string $label, string $filename): string
{
    $filename = basename(str_replace('\\', '/', trim($filename)));
    $label = news_parse_pdf_label($label);
    if ($filename === '') {
        return '';
    }
    if ($label === '') {
        $label = PDF_LABEL_DEFAULT;
    }
    return "[pdf]{$label}|{$filename}[/pdf]";
}

function news_pdf_display_text(string $label, string $filename): string
{
    if ($label !== '') {
        return $label;
    }
    if ($filename !== '') {
        $stem = pathinfo($filename, PATHINFO_FILENAME);
        return $stem !== '' ? $stem : $filename;
    }
    return 'PDF';
}

function news_extract_attachments(string $body): array
{
    $images = [];
    $pdfs = [];

    if (preg_match_all('/\[img\](.*?)\[\/img\]/s', $body, $mImg)) {
        foreach ($mImg[1] as $img) {
            $img = trim($img);
            if ($img !== '') {
                $images[] = $img;
            }
        }
    }

    if (preg_match_all('/\[pdf\](.*?)\[\/pdf\]/s', $body, $mPdf)) {
        foreach ($mPdf[1] as $inner) {
            $parsed = news_parse_pdf_tag_inner(trim($inner));
            if ($parsed['filename'] !== '') {
                $pdfs[] = $parsed;
            }
        }
    }

    return ['images' => $images, 'pdfs' => $pdfs];
}

function news_render_body_html(string $body): string
{
    $body = htmlspecialchars($body, ENT_QUOTES, 'UTF-8');

    preg_match_all('/\[img\](.*?)\[\/img\]/s', $body, $imgs);
    if (!empty($imgs[1])) {
        $gallery = '<div class="gallery">';
        foreach ($imgs[1] as $img) {
            $img = trim(html_entity_decode($img, ENT_QUOTES | ENT_HTML5, 'UTF-8'));
            $url = news_resolve_attachment_url($img);
            $gallery .=
                '<a href="' . htmlspecialchars($url, ENT_QUOTES, 'UTF-8') . '" target="_blank" rel="noopener">' .
                '<img class="news-image" src="' . htmlspecialchars($url, ENT_QUOTES, 'UTF-8') . '" alt="">' .
                '</a>';
        }
        $gallery .= '</div>';
        $body = preg_replace('/(\[img\].*?\[\/img\]\s*)+/s', $gallery, $body, 1);
    }

    $body = preg_replace_callback(
        '/\[pdf\](.*?)\[\/pdf\]/s',
        function ($m) {
            $parsed = news_parse_pdf_tag_inner(
                html_entity_decode(trim($m[1]), ENT_QUOTES | ENT_HTML5, 'UTF-8')
            );
            $url = news_resolve_attachment_url($parsed['filename']);
            $text = news_pdf_display_text($parsed['label'], $parsed['filename']);
            $title = $parsed['filename'] !== '' ? ' title="' . htmlspecialchars($parsed['filename'], ENT_QUOTES, 'UTF-8') . '"' : '';

            return
                '<p class="pdf-link">' .
                '<a href="' . htmlspecialchars($url, ENT_QUOTES, 'UTF-8') . '" target="_blank" rel="noopener"' . $title . '>' .
                '📄 ' . htmlspecialchars($text, ENT_QUOTES, 'UTF-8') .
                '</a>' .
                '</p>';
        },
        $body
    );

    return nl2br($body);
}

function news_category_labels_html(array $categories): string
{
    if ($categories === []) {
        return '';
    }
    $html = '';
    foreach ($categories as $c) {
        $html .= '<span class="news-cat">' . htmlspecialchars($c, ENT_QUOTES, 'UTF-8') . '</span>';
    }
    return $html;
}
