<?php

namespace App\Support;

/**
 * Maps a raw Notion task page (Tabex "Tasks" database) into the fields
 * the documentation pipeline and The Manifest site need.
 *
 * Real schema reference:
 *   Task name (title), Type (select: "Bug 🐞" | "Task 🔨" | "Epic ⛰️" | "Small 🤪"),
 *   Tipo de Chamado (multi_select), Dev-Status (status), Conclusion (rich_text),
 *   Tabex Card (url), Sprint (relation), Project (relation), Task ID (unique_id),
 *   Documentation Status (select), Technical Doc (url), Release Note (url).
 */
class NotionTask
{
    public static function title(array $page): string
    {
        return self::richText($page['properties']['Task name'] ?? []);
    }

    /**
     * Human title without the "[1234] - " card prefix.
     */
    public static function cleanTitle(array $page): string
    {
        return trim(preg_replace('/^\[\d+\]\s*-?\s*/', '', self::title($page)));
    }

    /**
     * Documentation category: bug | issue | project.
     * Bugs → Type "Bug 🐞" or Tipo de Chamado BUG/MISTYPE/CORREÇÃO.
     * Projects → Type "Epic ⛰️", linked Project, or NEW RELEASE chamado.
     * Everything else (tasks, melhorias, small fixes) → issue.
     */
    public static function category(array $page): string
    {
        $type    = self::select($page['properties']['Type'] ?? []);
        $chamado = self::multiSelect($page['properties']['Tipo de Chamado'] ?? []);
        $project = $page['properties']['Project']['relation'] ?? [];

        return match (true) {
            str_contains($type, 'Bug')
                || array_intersect(['BUG', 'MISTYPE', 'CORREÇÃO'], $chamado) !== [] => 'bug',
            str_contains($type, 'Epic')
                || $project !== []
                || in_array('NEW RELEASE', $chamado, true)                          => 'project',
            default                                                                 => 'issue',
        };
    }

    public static function categoryLabel(string $category): string
    {
        return match ($category) {
            'bug'     => 'Correções (Bugs)',
            'project' => 'Novos Projetos',
            default   => 'Melhorias e Ajustes',
        };
    }

    public static function conclusion(array $page): string
    {
        return self::richText($page['properties']['Conclusion'] ?? []);
    }

    public static function devStatus(array $page): string
    {
        return $page['properties']['Dev-Status']['status']['name'] ?? '';
    }

    public static function documentationStatus(array $page): string
    {
        return self::select($page['properties']['Documentation Status'] ?? []);
    }

    public static function cardUrl(array $page): ?string
    {
        return $page['properties']['Tabex Card']['url'] ?? null;
    }

    public static function releaseNoteUrl(array $page): ?string
    {
        return $page['properties']['Release Note']['url'] ?? null;
    }

    public static function lastEdited(array $page): ?string
    {
        return $page['last_edited_time'] ?? null;
    }

    /**
     * Extract the 32-char page ID from a Notion page URL (with or without dashes).
     */
    public static function pageIdFromUrl(?string $url): ?string
    {
        if (! $url || ! preg_match('/([0-9a-f]{32})/i', str_replace('-', '', $url), $m)) {
            return null;
        }

        return preg_replace(
            '/^(.{8})(.{4})(.{4})(.{4})(.{12})$/',
            '$1-$2-$3-$4-$5',
            strtolower($m[1])
        );
    }

    /**
     * "Container number" for the Pátio do Porto: the [1234] card number
     * prefixed like a real container ID, e.g. "TBX 2318".
     */
    public static function cardNumber(array $page): ?string
    {
        if (preg_match('/^\[(\d+)\]/', self::title($page), $m)) {
            return "TBX {$m[1]}";
        }

        return null;
    }

    /**
     * Title of any Notion page (scans for the title-type property).
     */
    public static function pageTitle(array $page): string
    {
        foreach ($page['properties'] ?? [] as $prop) {
            if (($prop['type'] ?? '') === 'title') {
                return implode('', array_map(fn ($rt) => $rt['plain_text'] ?? '', $prop['title'] ?? []));
            }
        }

        return '';
    }

    // ── Property extraction primitives ───────────────────────────────────────

    public static function richText(array $prop): string
    {
        $richTexts = $prop['rich_text'] ?? $prop['title'] ?? [];

        return implode('', array_map(fn ($rt) => $rt['plain_text'] ?? '', $richTexts));
    }

    public static function select(array $prop): string
    {
        return $prop['select']['name'] ?? '';
    }

    public static function multiSelect(array $prop): array
    {
        return array_map(fn ($o) => $o['name'] ?? '', $prop['multi_select'] ?? []);
    }
}
