<?php
// ════════════════════════════════════════════════════════
// DESCRIPTIONS API
// Place in: Triangle_Tree_Life_Number/api/data/descriptions.php
// ════════════════════════════════════════════════════════

error_reporting(E_ALL);
ini_set('display_errors', 0);

// Remove any existing headers first
if (function_exists('header_remove')) {
    header_remove('Access-Control-Allow-Methods');
}

// Force CORS headers
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
header('Access-Control-Allow-Credentials: true');

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(200);
    exit();
}

require_once __DIR__ . '/../config/db.php';
require_once __DIR__ . '/../config/helpers.php';

// Verify JWT token
$headers = getallheaders();
$authHeader = $headers['Authorization'] ?? '';

if (empty($authHeader) || !preg_match('/Bearer\s+(.*)$/i', $authHeader, $matches)) {
    http_response_code(401);
    echo json_encode(['error' => 'Unauthorized']);
    exit();
}

$token = $matches[1];
$jwtSecret = getenv('JWT_SECRET') ?: 'default_secret_change_this';
$payload = verifyJWT($token, $jwtSecret);

if (!$payload) {
    http_response_code(401);
    echo json_encode(['error' => 'Invalid token']);
    exit();
}

// Accept both GET and POST
$method = $_SERVER['REQUEST_METHOD'];

try {
    if ($method === 'GET') {
        // ══════════════════════════════════════
        // GET - Load all descriptions
        // ══════════════════════════════════════
        
        // Load single nodes (numbers 1-9 descriptions)
        $stmt = $pdo->query("
            SELECT 
                id, 
                node, 
                val,
                desc_en,
                desc_ms,
                desc_zh,
                sens_en,
                sens_ms,
                sens_zh
            FROM single_nodes
            ORDER BY val ASC
        ");
        $singleNodesRaw = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        // Transform to format expected by frontend
        $singleNodes = array_map(function($row) {
            return [
                'id' => (int)$row['id'],
                'node' => $row['node'],
                'val' => (int)$row['val'],
                'desc' => [
                    'en' => $row['desc_en'] ?? '',
                    'ms' => $row['desc_ms'] ?? '',
                    'zh' => $row['desc_zh'] ?? ''
                ],
                'sensDesc' => [
                    'en' => $row['sens_en'] ?? '',
                    'ms' => $row['sens_ms'] ?? '',
                    'zh' => $row['sens_zh'] ?? ''
                ]
            ];
        }, $singleNodesRaw);
        
        // Load combo rules (number combinations)
        $stmt = $pdo->query("
            SELECT 
                id,
                combo,
                groups_json,
                desc_en,
                desc_ms,
                desc_zh,
                sens_en,
                sens_ms,
                sens_zh
            FROM combo_rules
            ORDER BY id ASC
        ");
        $comboRulesRaw = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        $comboRules = array_map(function($row) {
            $groups = json_decode($row['groups_json'] ?? '[]', true);
            return [
                'id' => (int)$row['id'],
                'combo' => $row['combo'] ?? '',
                'groups' => is_array($groups) ? $groups : [],
                'desc' => [
                    'en' => $row['desc_en'] ?? '',
                    'ms' => $row['desc_ms'] ?? '',
                    'zh' => $row['desc_zh'] ?? ''
                ],
                'sensDesc' => [
                    'en' => $row['sens_en'] ?? '',
                    'ms' => $row['sens_ms'] ?? '',
                    'zh' => $row['sens_zh'] ?? ''
                ]
            ];
        }, $comboRulesRaw);
        
        // Load frequency rules
        $stmt = $pdo->query("
            SELECT 
                id,
                num,
                cnt,
                desc_en,
                desc_ms,
                desc_zh,
                sens_en,
                sens_ms,
                sens_zh,
                op
            FROM freq_rules
            ORDER BY num ASC, cnt ASC
        ");
        $freqRulesRaw = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        $freqRules = array_map(function($row) {
            return [
                'id' => (int)$row['id'],
                'num' => (int)$row['num'],
                'cnt' => (int)$row['cnt'],
                'op'  => $row['op'] ?? 'eq',
                'desc' => [
                    'en' => $row['desc_en'] ?? '',
                    'ms' => $row['desc_ms'] ?? '',
                    'zh' => $row['desc_zh'] ?? ''
                ],
                'sensDesc' => [
                    'en' => $row['sens_en'] ?? '',
                    'ms' => $row['sens_ms'] ?? '',
                    'zh' => $row['sens_zh'] ?? ''
                ]
            ];
        }, $freqRulesRaw);
        
        // Load node combination rules (will add when you have data)
        $nodeCombRules = [];
        
        // Load tiangan descriptions
        $stmt = $pdo->query("
            SELECT 
                id,
                tg,
                num,
                desc_en,
                desc_ms,
                desc_zh,
                sens_en,
                sens_ms,
                sens_zh
            FROM tiangan_desc
            ORDER BY num ASC
        ");
        $tianganRaw = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        // Transform to format expected by frontend
        $tianganDesc = array_map(function($row) {
            return [
                'id' => (int)$row['id'],
                'tg' => $row['tg'],
                'num' => (int)$row['num'],
                'desc' => [
                    'en' => $row['desc_en'] ?? '',
                    'ms' => $row['desc_ms'] ?? '',
                    'zh' => $row['desc_zh'] ?? ''
                ],
                'sensDesc' => [
                    'en' => $row['sens_en'] ?? '',
                    'ms' => $row['sens_ms'] ?? '',
                    'zh' => $row['sens_zh'] ?? ''
                ]
            ];
        }, $tianganRaw);
        
        // Load personal_year_nodes
        $pyStmt = $pdo->query("SELECT id, node, val, desc_en, desc_ms, desc_zh, sens_en, sens_ms, sens_zh FROM personal_year_nodes ORDER BY node, val");
        $pyRows  = $pyStmt->fetchAll(PDO::FETCH_ASSOC);
        $personalYearNodes = array_map(function($r){
            return ['id'=>(int)$r['id'],'node'=>$r['node'],'val'=>(int)$r['val'],
                'desc'=>['en'=>$r['desc_en']??'','ms'=>$r['desc_ms']??'','zh'=>$r['desc_zh']??''],
                'sensDesc'=>['en'=>$r['sens_en']??'','ms'=>$r['sens_ms']??'','zh'=>$r['sens_zh']??'']];
        }, $pyRows);

        echo json_encode([
            'singleNodes'       => $singleNodes,
            'personalYearNodes' => $personalYearNodes,
            'comboRules'        => $comboRules,
            'freqRules'         => $freqRules,
            'nodeCombRules'     => $nodeCombRules,
            'tianganDesc'       => $tianganDesc
        ]);
        
    } elseif ($method === 'POST') {
        // ══════════════════════════════════════
        // POST - Save descriptions to database
        // numeric id  -> UPDATE existing row
        // "new_" id   -> INSERT new row, return real id
        // ══════════════════════════════════════
        
        $input = json_decode(file_get_contents('php://input'), true);
        
        if (!is_array($input)) {
            http_response_code(400);
            echo json_encode(['error' => 'Invalid JSON payload']);
            exit();
        }
        
        // A row is "existing" only if its id is a positive integer.
        // Anything else (new_1, null, '') is treated as a new INSERT.
        $isExistingId = function($id) {
            return is_int($id) || (is_string($id) && ctype_digit($id) && (int)$id > 0);
        };
        
        $idMap = []; // temp id -> new real id, returned to the app
        
        $pdo->beginTransaction();
        
        try {
            // ---- personal_year_nodes ----
            if (isset($input['personalYearNodes']) && is_array($input['personalYearNodes'])) {
                $pyUp  = $pdo->prepare("UPDATE personal_year_nodes SET node=?,val=?,desc_en=?,desc_ms=?,desc_zh=?,sens_en=?,sens_ms=?,sens_zh=?,updated_at=NOW() WHERE id=?");
                $pyIns = $pdo->prepare("INSERT INTO personal_year_nodes (node,val,desc_en,desc_ms,desc_zh,sens_en,sens_ms,sens_zh) VALUES (?,?,?,?,?,?,?,?)");
                foreach ($input['personalYearNodes'] as $r) {
                    $d=$r['desc']??[]; $s=$r['sensDesc']??[];
                    if (is_numeric($r['id']??null)) {
                        $pyUp->execute([$r['node'],$r['val'],$d['en']??'',$d['ms']??'',$d['zh']??'',$s['en']??'',$s['ms']??'',$s['zh']??'',$r['id']]);
                    } else {
                        $pyIns->execute([$r['node'],$r['val'],$d['en']??'',$d['ms']??'',$d['zh']??'',$s['en']??'',$s['ms']??'',$s['zh']??'']);
                        $idMap[(string)($r['id']??'')] = (int)$pdo->lastInsertId();
                    }
                }
            }

            // ---- single_nodes ----
            if (isset($input['singleNodes']) && is_array($input['singleNodes'])) {
                $up  = $pdo->prepare("UPDATE single_nodes SET node=?, val=?, desc_en=?, desc_ms=?, desc_zh=?, sens_en=?, sens_ms=?, sens_zh=? WHERE id=?");
                $ins = $pdo->prepare("INSERT INTO single_nodes (node, val, desc_en, desc_ms, desc_zh, sens_en, sens_ms, sens_zh) VALUES (?,?,?,?,?,?,?,?)");
                foreach ($input['singleNodes'] as $row) {
                    $desc = is_array($row['desc'] ?? null) ? $row['desc'] : ['en'=>(string)($row['desc'] ?? ''),'ms'=>'','zh'=>''];
                    $sens = is_array($row['sensDesc'] ?? null) ? $row['sensDesc'] : ['en'=>'','ms'=>'','zh'=>''];
                    $vals = [
                        $row['node'] ?? 'O',
                        (int)($row['val'] ?? 0),
                        $desc['en'] ?? '', $desc['ms'] ?? '', $desc['zh'] ?? '',
                        $sens['en'] ?? '', $sens['ms'] ?? '', $sens['zh'] ?? ''
                    ];
                    if ($isExistingId($row['id'] ?? null)) {
                        $up->execute(array_merge($vals, [(int)$row['id']]));
                    } else {
                        $ins->execute($vals);
                        if (isset($row['id'])) $idMap[(string)$row['id']] = (int)$pdo->lastInsertId();
                    }
                }
            }
            
            // ---- tiangan_desc ----
            if (isset($input['tianganDesc']) && is_array($input['tianganDesc'])) {
                $up  = $pdo->prepare("UPDATE tiangan_desc SET tg=?, num=?, desc_en=?, desc_ms=?, desc_zh=?, sens_en=?, sens_ms=?, sens_zh=? WHERE id=?");
                $ins = $pdo->prepare("INSERT INTO tiangan_desc (tg, num, desc_en, desc_ms, desc_zh, sens_en, sens_ms, sens_zh) VALUES (?,?,?,?,?,?,?,?)");
                foreach ($input['tianganDesc'] as $row) {
                    $desc = is_array($row['desc'] ?? null) ? $row['desc'] : ['en'=>(string)($row['desc'] ?? ''),'ms'=>'','zh'=>''];
                    $sens = is_array($row['sensDesc'] ?? null) ? $row['sensDesc'] : ['en'=>'','ms'=>'','zh'=>''];
                    $vals = [
                        $row['tg'] ?? '',
                        (int)($row['num'] ?? 0),
                        $desc['en'] ?? '', $desc['ms'] ?? '', $desc['zh'] ?? '',
                        $sens['en'] ?? '', $sens['ms'] ?? '', $sens['zh'] ?? ''
                    ];
                    if ($isExistingId($row['id'] ?? null)) {
                        $up->execute(array_merge($vals, [(int)$row['id']]));
                    } else {
                        $ins->execute($vals);
                        if (isset($row['id'])) $idMap[(string)$row['id']] = (int)$pdo->lastInsertId();
                    }
                }
            }
            
            // ---- freq_rules ----
            if (isset($input['freqRules']) && is_array($input['freqRules'])) {
                $up  = $pdo->prepare("UPDATE freq_rules SET num=?, cnt=?, op=?, desc_en=?, desc_ms=?, desc_zh=?, sens_en=?, sens_ms=?, sens_zh=? WHERE id=?");
                $ins = $pdo->prepare("INSERT INTO freq_rules (num, cnt, op, desc_en, desc_ms, desc_zh, sens_en, sens_ms, sens_zh) VALUES (?,?,?,?,?,?,?,?,?)");
                $validOps = ['eq','gte','lte','gt','lt'];
                foreach ($input['freqRules'] as $row) {
                    $desc = is_array($row['desc'] ?? null) ? $row['desc'] : ['en'=>(string)($row['desc'] ?? ''),'ms'=>'','zh'=>''];
                    $sens = is_array($row['sensDesc'] ?? null) ? $row['sensDesc'] : ['en'=>'','ms'=>'','zh'=>''];
                    $op = in_array(($row['op'] ?? 'eq'), $validOps, true) ? $row['op'] : 'eq';
                    $vals = [
                        (int)($row['num'] ?? 0),
                        (int)($row['cnt'] ?? 0),
                        $op,
                        $desc['en'] ?? '', $desc['ms'] ?? '', $desc['zh'] ?? '',
                        $sens['en'] ?? '', $sens['ms'] ?? '', $sens['zh'] ?? ''
                    ];
                    if ($isExistingId($row['id'] ?? null)) {
                        $up->execute(array_merge($vals, [(int)$row['id']]));
                    } else {
                        $ins->execute($vals);
                        if (isset($row['id'])) $idMap[(string)$row['id']] = (int)$pdo->lastInsertId();
                    }
                }
            }
            
            // ---- combo_rules ----
            if (isset($input['comboRules']) && is_array($input['comboRules'])) {
                $up  = $pdo->prepare("UPDATE combo_rules SET combo=?, groups_json=?, desc_en=?, desc_ms=?, desc_zh=?, sens_en=?, sens_ms=?, sens_zh=? WHERE id=?");
                $ins = $pdo->prepare("INSERT INTO combo_rules (combo, groups_json, desc_en, desc_ms, desc_zh, sens_en, sens_ms, sens_zh) VALUES (?,?,?,?,?,?,?,?)");
                foreach ($input['comboRules'] as $row) {
                    $desc = is_array($row['desc'] ?? null) ? $row['desc'] : ['en'=>(string)($row['desc'] ?? ''),'ms'=>'','zh'=>''];
                    $sens = is_array($row['sensDesc'] ?? null) ? $row['sensDesc'] : ['en'=>'','ms'=>'','zh'=>''];
                    $groupsJson = isset($row['groups']) ? json_encode($row['groups']) : ($row['groups_json'] ?? '[]');
                    $vals = [
                        $row['combo'] ?? '',
                        $groupsJson,
                        $desc['en'] ?? '', $desc['ms'] ?? '', $desc['zh'] ?? '',
                        $sens['en'] ?? '', $sens['ms'] ?? '', $sens['zh'] ?? ''
                    ];
                    if ($isExistingId($row['id'] ?? null)) {
                        $up->execute(array_merge($vals, [(int)$row['id']]));
                    } else {
                        $ins->execute($vals);
                        if (isset($row['id'])) $idMap[(string)$row['id']] = (int)$pdo->lastInsertId();
                    }
                }
            }
            
            $pdo->commit();
            echo json_encode([
                'success' => true,
                'message' => 'Descriptions saved to database',
                'idMap'   => $idMap
            ]);
            
        } catch (Exception $e) {
            $pdo->rollBack();
            http_response_code(500);
            echo json_encode([
                'error'   => 'Save failed',
                'message' => $e->getMessage()
            ]);
        }
        
    } elseif ($method === 'DELETE') {
        // ══════════════════════════════════════
        // DELETE - remove a single row
        // expects ?table=single_nodes&id=5
        // ══════════════════════════════════════
        
        $table = $_GET['table'] ?? '';
        $id    = $_GET['id'] ?? '';
        
        $allowedTables = ['single_nodes', 'freq_rules', 'combo_rules', 'tiangan_desc', 'personal_year_nodes'];
        
        if (!in_array($table, $allowedTables, true)) {
            http_response_code(400);
            echo json_encode(['error' => 'Invalid table']);
            exit();
        }
        
        if (!ctype_digit((string)$id) || (int)$id <= 0) {
            http_response_code(400);
            echo json_encode(['error' => 'Invalid id']);
            exit();
        }
        
        $stmt = $pdo->prepare("DELETE FROM `$table` WHERE id = ?");
        $stmt->execute([(int)$id]);
        
        echo json_encode([
            'success'  => true,
            'message'  => 'Row deleted',
            'deleted'  => $stmt->rowCount()
        ]);
        
    } else {
        // Method not supported
        http_response_code(405);
        echo json_encode(['error' => 'Method not allowed']);
    }
    
} catch (Exception $e) {
    http_response_code(500);
    echo json_encode([
        'error' => 'Server error', 
        'message' => $e->getMessage()
    ]);
}
?>
