<?php
declare(strict_types=1);

namespace App\Controllers;

use App\Core\Controller;
use App\Core\Database;

final class AdminDecisionBoardController extends Controller
{
    private function tableExists($db, string $t): bool {
        $st=$db->prepare("SELECT COUNT(*) FROM information_schema.tables WHERE table_schema=DATABASE() AND table_name=:t");
        $st->execute([':t'=>$t]);
        return (int)$st->fetchColumn()>0;
    }
    private function cols($db, string $t): array {
        $st=$db->prepare("SELECT column_name, column_type FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name=:t");
        $st->execute([':t'=>$t]);
        $rows=$st->fetchAll()?:[];
        $m=[];
        foreach($rows as $r){ $m[(string)$r['column_name']] = (string)$r['column_type']; }
        return $m;
    }
    private function pickDecisionAllowed(?string $colType, string $val): string {
        $val = trim($val);
        if ($val==='') return 'pending';
        // if enum('a','b',..) parse allowed
        if ($colType && str_starts_with($colType, "enum(")) {
            preg_match_all("/'([^']+)'/", $colType, $m);
            $allowed = $m[1] ?? [];
            if (!$allowed) return $val;
            // normalize common variants to your enums
            $map = [
              'accept'=>'accepted','accepted'=>'accepted',
              'reject'=>'rejected','rejected'=>'rejected',
              'minor'=>'minor_revision','minor_revision'=>'minor_revision',
              'major'=>'major_revision','major_revision'=>'major_revision',
              'revision'=>'revision','revise'=>'revision',
              'pending'=>'pending'
            ];
            $vv = strtolower($val);
            $vv = $map[$vv] ?? $vv;
            if (in_array($vv, $allowed, true)) return $vv;
            // fallback to first enum option
            return (string)$allowed[0];
        }
        return $val;
    }

    public function index(): void
    {
        require_admin_area();
        // keep existing index view if you already have it elsewhere
        $this->view('admin/decision_board/index', []);
    }

    public function decide(): void
    {
        require_admin_area();
        $db = Database::getInstance();

        if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') { http_response_code(405); echo "Method Not Allowed"; return; }

        $submissionId = (int)($_POST['submission_id'] ?? $_POST['id'] ?? 0);
        $decisionRaw  = (string)($_POST['decision'] ?? '');
        $notes        = trim((string)($_POST['chair_comments'] ?? $_POST['notes'] ?? ''));

        if ($submissionId <= 0) {
            if (function_exists('flash_set')) flash_set('danger', 'Missing submission_id');
            header('Location: ' . base_path('admin/decision-board'));
            exit;
        }

        // 1) Update submissions.status if exists
        try {
            if ($this->tableExists($db,'submissions')) {
                $sc = $this->cols($db,'submissions');
                if (isset($sc['status'])) {
                    $status = $decisionRaw;
                    // normalize common statuses
                    $norm = [
                      'accept'=>'accepted','accepted'=>'accepted',
                      'reject'=>'rejected','rejected'=>'rejected',
                      'minor'=>'minor_revision','minor_revision'=>'minor_revision',
                      'major'=>'major_revision','major_revision'=>'major_revision',
                      'revision'=>'revision'
                    ];
                    $status = $norm[strtolower($status)] ?? $status;
                    $db->prepare("UPDATE submissions SET status=:s WHERE id=:id")->execute([':s'=>$status, ':id'=>$submissionId]);
                }
            }
        } catch (\Throwable $e) {
            // ignore; decision table will still be written
        }

        // 2) Upsert into decisions table if exists, otherwise create minimal
        if (!$this->tableExists($db,'decisions')) {
            $db->exec("
              CREATE TABLE IF NOT EXISTS decisions (
                id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
                submission_id BIGINT UNSIGNED NOT NULL,
                decision VARCHAR(40) NOT NULL,
                chair_comments LONGTEXT NULL,
                decided_by BIGINT UNSIGNED NULL,
                decided_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
                created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
                updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
                PRIMARY KEY(id),
                KEY idx_sub (submission_id)
              ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
            ");
        }

        $dc = $this->cols($db,'decisions');
        $decision = $this->pickDecisionAllowed($dc['decision'] ?? null, $decisionRaw);

        // find existing decision row
        $st = $db->prepare("SELECT id FROM decisions WHERE submission_id=:sid ORDER BY id DESC LIMIT 1");
        $st->execute([':sid'=>$submissionId]);
        $did = (int)($st->fetchColumn() ?: 0);

        $uid = function_exists('auth_id') ? (int)auth_id() : null;

        if ($did > 0) {
            $fields = [];
            $params = [':id'=>$did];
            if (isset($dc['decision'])) { $fields[]="decision=:d"; $params[':d']=$decision; }
            if (isset($dc['chair_comments'])) { $fields[]="chair_comments=:c"; $params[':c']=($notes!==''?$notes:null); }
            if (isset($dc['decided_by'])) { $fields[]="decided_by=:u"; $params[':u']=$uid; }
            if (isset($dc['decided_at'])) { $fields[]="decided_at=NOW()"; }

            if ($fields) {
                $db->prepare("UPDATE decisions SET ".implode(',', $fields)." WHERE id=:id")->execute($params);
            }
        } else {
            $cols=[]; $vals=[]; $params=[];
            if (isset($dc['submission_id'])) { $cols[]='submission_id'; $vals[]=':sid'; $params[':sid']=$submissionId; }
            if (isset($dc['decision'])) { $cols[]='decision'; $vals[]=':d'; $params[':d']=$decision; }
            if (isset($dc['chair_comments'])) { $cols[]='chair_comments'; $vals[]=':c'; $params[':c']=($notes!==''?$notes:null); }
            if (isset($dc['decided_by'])) { $cols[]='decided_by'; $vals[]=':u'; $params[':u']=$uid; }
            if (isset($dc['decided_at'])) { $cols[]='decided_at'; $vals[]='NOW()'; }

            $sql="INSERT INTO decisions (".implode(',',$cols).") VALUES (".implode(',',$vals).")";
            $db->prepare($sql)->execute($params);
        }

        // notify author if possible (optional)
        try {
            if (function_exists('notify_user_dynamic')) {
                // find author_id
                if ($this->tableExists($db,'submissions')) {
                    $sc = $this->cols($db,'submissions');
                    if (isset($sc['author_id'])) {
                        $st=$db->prepare("SELECT author_id FROM submissions WHERE id=:id LIMIT 1");
                        $st->execute([':id'=>$submissionId]);
                        $aid=(int)($st->fetchColumn()?:0);
                        if($aid>0){
                            $msg = "Decision: ".$decision;
                            if ($notes!=='') $msg .= " — ".$notes;
                            notify_user_dynamic($aid, "Submission decision", $msg, "info");
                        }
                    }
                }
            }
        } catch (\Throwable $e) {}

        if (function_exists('flash_set')) flash_set('success','Decision saved');
        header('Location: ' . base_path('admin/decision-board'));
        exit;
    }
}
