<?php
/**
 * Taxonomy Model
 * Manages taxonomies and terms
 */
namespace Models;

class Taxonomy
{
    private static $pdo;

    public static function setPdo($pdo)
    {
        self::$pdo = $pdo;
    }

    /**
     * Get all taxonomies
     */
    public static function all()
    {
        $stmt = self::$pdo->query("SELECT * FROM taxonomies ORDER BY label");
        return $stmt->fetchAll(\PDO::FETCH_ASSOC);
    }

    /**
     * Get taxonomies for a post type
     */
    public static function forPostType($postType)
    {
        $stmt = self::$pdo->prepare("SELECT * FROM taxonomies WHERE post_type = ? ORDER BY label");
        $stmt->execute([$postType]);
        return $stmt->fetchAll(\PDO::FETCH_ASSOC);
    }

    /**
     * Get taxonomy by name
     */
    public static function get($name)
    {
        $stmt = self::$pdo->prepare("SELECT * FROM taxonomies WHERE name = ?");
        $stmt->execute([$name]);
        return $stmt->fetch(\PDO::FETCH_ASSOC);
    }

    /**
     * Create taxonomy
     */
    public static function create($data)
    {
        $stmt = self::$pdo->prepare("
            INSERT INTO taxonomies (name, label, post_type, hierarchical)
            VALUES (?, ?, ?, ?)
        ");

        $stmt->execute([
            $data['name'],
            $data['label'],
            $data['post_type'],
            $data['hierarchical'] ?? 0
        ]);

        return self::$pdo->lastInsertId();
    }

    /**
     * Delete taxonomy
     */
    public static function delete($name)
    {
        // Delete terms
        $stmt = self::$pdo->prepare("DELETE FROM terms WHERE taxonomy = ?");
        $stmt->execute([$name]);

        // Delete taxonomy
        $stmt = self::$pdo->prepare("DELETE FROM taxonomies WHERE name = ?");
        return $stmt->execute([$name]);
    }

    /**
     * Get all terms for a taxonomy
     */
    public static function getTerms($taxonomyName, $parentId = null)
    {
        if ($parentId === null) {
            $stmt = self::$pdo->prepare("SELECT * FROM terms WHERE taxonomy = ? ORDER BY name");
            $stmt->execute([$taxonomyName]);
        } else {
            $stmt = self::$pdo->prepare("SELECT * FROM terms WHERE taxonomy = ? AND parent_id = ? ORDER BY name");
            $stmt->execute([$taxonomyName, $parentId]);
        }
        return $stmt->fetchAll(\PDO::FETCH_ASSOC);
    }

    /**
     * Get hierarchical terms (tree structure)
     */
    public static function getTermTree($taxonomyName)
    {
        $terms = self::getTerms($taxonomyName);
        return self::buildTree($terms);
    }

    /**
     * Build tree from flat array
     */
    private static function buildTree($terms, $parentId = null)
    {
        $tree = [];
        foreach ($terms as $term) {
            if ($term['parent_id'] == $parentId) {
                $term['children'] = self::buildTree($terms, $term['id']);
                $tree[] = $term;
            }
        }
        return $tree;
    }

    /**
     * Get term by ID
     */
    public static function getTerm($id)
    {
        $stmt = self::$pdo->prepare("SELECT * FROM terms WHERE id = ?");
        $stmt->execute([$id]);
        return $stmt->fetch(\PDO::FETCH_ASSOC);
    }

    /**
     * Create term
     */
    public static function createTerm($data)
    {
        $slug = strtolower(trim($data['name']));
        $slug = preg_replace('/[^a-z0-9]+/', '-', $slug);
        $slug = trim($slug, '-');

        $stmt = self::$pdo->prepare("
            INSERT INTO terms (taxonomy, name, slug, description, parent_id)
            VALUES (?, ?, ?, ?, ?)
        ");

        $stmt->execute([
            $data['taxonomy'],
            $data['name'],
            $data['slug'] ?? $slug,
            $data['description'] ?? '',
            $data['parent_id'] ?? null
        ]);

        return self::$pdo->lastInsertId();
    }

    /**
     * Update term
     */
    public static function updateTerm($id, $data)
    {
        $fields = [];
        $values = [];

        $allowedFields = ['name', 'slug', 'description', 'parent_id'];

        foreach ($allowedFields as $field) {
            if (isset($data[$field])) {
                $fields[] = "$field = ?";
                $values[] = $data[$field];
            }
        }

        if (empty($fields))
            return false;

        $values[] = $id;
        $sql = "UPDATE terms SET " . implode(', ', $fields) . " WHERE id = ?";

        $stmt = self::$pdo->prepare($sql);
        return $stmt->execute($values);
    }

    /**
     * Delete term
     */
    public static function deleteTerm($id)
    {
        // Delete relationships
        $stmt = self::$pdo->prepare("DELETE FROM term_relationships WHERE term_id = ?");
        $stmt->execute([$id]);

        // Update children to have no parent
        $stmt = self::$pdo->prepare("UPDATE terms SET parent_id = NULL WHERE parent_id = ?");
        $stmt->execute([$id]);

        // Delete term
        $stmt = self::$pdo->prepare("DELETE FROM terms WHERE id = ?");
        return $stmt->execute([$id]);
    }

    /**
     * Seed default taxonomies
     */
    public static function seedDefaults()
    {
        $defaults = [
            // Product taxonomies
            ['name' => 'product_category', 'label' => 'Product Categories', 'post_type' => 'product', 'hierarchical' => 1],
            ['name' => 'product_tag', 'label' => 'Product Tags', 'post_type' => 'product', 'hierarchical' => 0],

            // Property taxonomies
            ['name' => 'property_type', 'label' => 'Property Types', 'post_type' => 'property', 'hierarchical' => 1],
            ['name' => 'property_location', 'label' => 'Locations', 'post_type' => 'property', 'hierarchical' => 1],

            // Portfolio taxonomies
            ['name' => 'portfolio_category', 'label' => 'Categories', 'post_type' => 'portfolio', 'hierarchical' => 1],

            // Event taxonomies
            ['name' => 'event_type', 'label' => 'Event Types', 'post_type' => 'event', 'hierarchical' => 1]
        ];

        foreach ($defaults as $tax) {
            $existing = self::get($tax['name']);
            if (!$existing) {
                self::create($tax);
            }
        }
    }
}
