<?php

declare(strict_types=1);

namespace App\Framework\Mcp\Core\ValueObjects;

/**
 * Enum für unterstützte Diagramm-Typen in Mermaid und PlantUML
 *
 * Bietet Typsicherheit und zentrale Definition aller verfügbaren Diagramm-Formate
 */
enum DiagramType: string
{
    case FLOWCHART = 'flowchart';
    case CLASS_DIAGRAM = 'classDiagram';
    case SEQUENCE_DIAGRAM = 'sequenceDiagram';
    case STATE_DIAGRAM = 'stateDiagram';
    case ENTITY_RELATIONSHIP = 'erDiagram';
    case USER_JOURNEY = 'journey';
    case GANTT = 'gantt';
    case PIE_CHART = 'pie';
    case GIT_GRAPH = 'gitgraph';
    case MINDMAP = 'mindmap';
    case TIMELINE = 'timeline';
    case SANKEY = 'sankey';

    // PlantUML specific types
    case PLANTUML_CLASS = 'plantuml_class';
    case PLANTUML_SEQUENCE = 'plantuml_sequence';
    case PLANTUML_USE_CASE = 'plantuml_usecase';
    case PLANTUML_ACTIVITY = 'plantuml_activity';
    case PLANTUML_COMPONENT = 'plantuml_component';
    case PLANTUML_DEPLOYMENT = 'plantuml_deployment';

    /**
     * Gibt eine Beschreibung des Diagramm-Typs zurück
     */
    public function getDescription(): string
    {
        return match ($this) {
            self::FLOWCHART => 'Flowchart for processes and workflows',
            self::CLASS_DIAGRAM => 'Class diagram for object-oriented design',
            self::SEQUENCE_DIAGRAM => 'Sequence diagram for interactions over time',
            self::STATE_DIAGRAM => 'State diagram for state transitions',
            self::ENTITY_RELATIONSHIP => 'Entity relationship diagram for databases',
            self::USER_JOURNEY => 'User journey diagram for user experience',
            self::GANTT => 'Gantt chart for project timelines',
            self::PIE_CHART => 'Pie chart for data distribution',
            self::GIT_GRAPH => 'Git graph for version control visualization',
            self::MINDMAP => 'Mind map for hierarchical information',
            self::TIMELINE => 'Timeline for chronological events',
            self::SANKEY => 'Sankey diagram for flow visualization',
            self::PLANTUML_CLASS => 'PlantUML class diagram',
            self::PLANTUML_SEQUENCE => 'PlantUML sequence diagram',
            self::PLANTUML_USE_CASE => 'PlantUML use case diagram',
            self::PLANTUML_ACTIVITY => 'PlantUML activity diagram',
            self::PLANTUML_COMPONENT => 'PlantUML component diagram',
            self::PLANTUML_DEPLOYMENT => 'PlantUML deployment diagram'
        };
    }

    /**
     * Prüft ob es sich um einen Mermaid Diagramm-Typ handelt
     */
    public function isMermaid(): bool
    {
        return match ($this) {
            self::FLOWCHART, self::CLASS_DIAGRAM, self::SEQUENCE_DIAGRAM,
            self::STATE_DIAGRAM, self::ENTITY_RELATIONSHIP, self::USER_JOURNEY,
            self::GANTT, self::PIE_CHART, self::GIT_GRAPH, self::MINDMAP,
            self::TIMELINE, self::SANKEY => true,
            default => false
        };
    }

    /**
     * Prüft ob es sich um einen PlantUML Diagramm-Typ handelt
     */
    public function isPlantUml(): bool
    {
        return match ($this) {
            self::PLANTUML_CLASS, self::PLANTUML_SEQUENCE, self::PLANTUML_USE_CASE,
            self::PLANTUML_ACTIVITY, self::PLANTUML_COMPONENT, self::PLANTUML_DEPLOYMENT => true,
            default => false
        };
    }

    /**
     * Gibt die Komplexität des Diagramm-Typs zurück
     */
    public function getComplexity(): string
    {
        return match ($this) {
            self::PIE_CHART, self::TIMELINE => 'simple',
            self::FLOWCHART, self::MINDMAP, self::GIT_GRAPH => 'medium',
            self::CLASS_DIAGRAM, self::SEQUENCE_DIAGRAM, self::STATE_DIAGRAM,
            self::ENTITY_RELATIONSHIP, self::USER_JOURNEY, self::GANTT => 'complex',
            self::SANKEY, self::PLANTUML_CLASS, self::PLANTUML_SEQUENCE,
            self::PLANTUML_USE_CASE, self::PLANTUML_ACTIVITY, self::PLANTUML_COMPONENT,
            self::PLANTUML_DEPLOYMENT => 'advanced'
        };
    }

    /**
     * Gibt passende Diagramm-Typen basierend auf Datenstruktur zurück
     */
    public static function detectFromData(array $data): self
    {
        // Look for patterns that suggest specific diagram types
        $keys = array_keys($data);
        $keyString = implode(' ', $keys);

        // Check for specific patterns
        if (preg_match('/\b(class|method|property|inheritance)\b/i', $keyString)) {
            return self::CLASS_DIAGRAM;
        }

        if (preg_match('/\b(participant|message|sequence|interaction)\b/i', $keyString)) {
            return self::SEQUENCE_DIAGRAM;
        }

        if (preg_match('/\b(state|transition|status)\b/i', $keyString)) {
            return self::STATE_DIAGRAM;
        }

        if (preg_match('/\b(entity|table|relationship|foreign)\b/i', $keyString)) {
            return self::ENTITY_RELATIONSHIP;
        }

        if (preg_match('/\b(timeline|history|chronological|date)\b/i', $keyString)) {
            return self::TIMELINE;
        }

        if (preg_match('/\b(commit|branch|git|version)\b/i', $keyString)) {
            return self::GIT_GRAPH;
        }

        if (preg_match('/\b(journey|user|experience|step)\b/i', $keyString)) {
            return self::USER_JOURNEY;
        }

        if (preg_match('/\b(task|project|schedule|duration)\b/i', $keyString)) {
            return self::GANTT;
        }

        // Check for pie chart data (simple numeric values)
        if (count($data) <= 10 && $this->isNumericData($data)) {
            return self::PIE_CHART;
        }

        // Default to flowchart for hierarchical or process data
        return self::FLOWCHART;
    }

    /**
     * Prüft ob die Daten hauptsächlich numerisch sind
     */
    private static function isNumericData(array $data): bool
    {
        $numericCount = 0;
        $totalCount = count($data);

        foreach ($data as $value) {
            if (is_numeric($value)) {
                $numericCount++;
            }
        }

        return $totalCount > 0 && ($numericCount / $totalCount) >= 0.7;
    }

    /**
     * Gibt alle Mermaid Diagramm-Typen zurück
     */
    public static function getMermaidTypes(): array
    {
        return array_filter(self::cases(), fn (self $type) => $type->isMermaid());
    }

    /**
     * Gibt alle PlantUML Diagramm-Typen zurück
     */
    public static function getPlantUmlTypes(): array
    {
        return array_filter(self::cases(), fn (self $type) => $type->isPlantUml());
    }

    /**
     * Erstellt DiagramType aus String mit Fallback
     */
    public static function fromString(string $type): self
    {
        return self::tryFrom(strtolower($type)) ?? self::FLOWCHART;
    }
}
