<?php
declare(strict_types=1);

namespace App\Controllers;

require_once BASE_PATH . '/app/helpers/permissions.php';

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

final class AdminDictionaryTenantController extends Controller
{
    private function guard(): array {
        require_admin_or_chair_tenant();
        require_org_context();
        $db = Database::getInstance();
        $orgId = (int) current_org_id();
        return [$db, $orgId];
    }

    private function hasOrg(PDO $db): bool {
        $st=$db->prepare("SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='dictionary' AND COLUMN_NAME='org_id'");
        $st->execute();
        return (int)$st->fetchColumn() > 0;
    }

    private function cols(PDO $db): array {
        $st=$db->prepare("SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='dictionary'");
        $st->execute();
        return array_map(fn($r)=>$r['COLUMN_NAME'], $st->fetchAll(PDO::FETCH_ASSOC)?:[]);
    }

    public function index(): void
    {
        [$db,$orgId] = $this->guard();
        $hasOrg = $this->hasOrg($db);
        $cols = $this->cols($db);

        $q = trim((string)($_GET['q'] ?? ''));
        $onlyActive = (int)($_GET['active'] ?? 0);

        $where = [];
        $bind = [];

        if($hasOrg){
            $where[] = "(org_id=:o OR org_id IS NULL)";
            $bind[':o'] = $orgId;
        }

        if($q !== ''){
            $where[] = "(dict_key LIKE :q OR value_en LIKE :q OR value_ar LIKE :q)";
            $bind[':q'] = "%$q%";
        }

        if($onlyActive === 1 && in_array('is_active',$cols,true)){
            $where[] = "is_active=1";
        }

        $sql = "SELECT * FROM dictionary";
        if(!empty($where)) $sql .= " WHERE ".implode(" AND ", $where);
        $sql .= " ORDER BY dict_key ASC, id ASC LIMIT 500";

        $st = $db->prepare($sql);
        $st->execute($bind);
        $rows = $st->fetchAll(PDO::FETCH_ASSOC) ?: [];

        $editId = (int)($_GET['edit'] ?? 0);
        $editRow = null;
        if($editId>0){
            foreach($rows as $r){ if((int)$r['id']===$editId){ $editRow=$r; break; } }
        }

        $this->view('admin/dictionary/index', compact('rows','q','onlyActive','editId','editRow','hasOrg'));
    }

    public function save(): void
    {
        [$db,$orgId] = $this->guard();
        if(($_SERVER['REQUEST_METHOD']??'GET')!=='POST'){ http_response_code(405); exit; }

        $cols = $this->cols($db);
        $hasOrg = $this->hasOrg($db);

        $id = (int)($_POST['id'] ?? 0);
        $key = trim((string)($_POST['dict_key'] ?? ''));
        $en  = trim((string)($_POST['value_en'] ?? ''));
        $ar  = trim((string)($_POST['value_ar'] ?? ''));
        $active = (int)($_POST['is_active'] ?? 1) ? 1 : 0;

        if($key==='' || $en==='' || $ar===''){
            if(function_exists('flash_set')) flash_set('danger','Key + EN + AR are required');
            header('Location: '.base_path('admin/dictionary')); exit;
        }

        // normalize key
        $key = preg_replace('/\s+/', '_', $key);
        $key = strtolower((string)$key);

        if($id>0){
            $sql="UPDATE dictionary SET dict_key=:k, value_en=:en, value_ar=:ar";
            if(in_array('is_active',$cols,true)) $sql.=", is_active=:ia";
            $sql.=" WHERE id=:id";
            $bind=[':k'=>$key,':en'=>$en,':ar'=>$ar,':id'=>$id];
            if(in_array('is_active',$cols,true)) $bind[':ia']=$active;
            if($hasOrg){ $sql.=" AND (org_id=:o OR org_id IS NULL)"; $bind[':o']=$orgId; }
            $db->prepare($sql)->execute($bind);
        } else {
            // try update existing key within org first (avoid duplicates)
            if($hasOrg){
                $st=$db->prepare("SELECT id FROM dictionary WHERE dict_key=:k AND org_id=:o LIMIT 1");
                $st->execute([':k'=>$key,':o'=>$orgId]);
                $existing=(int)$st->fetchColumn();
                if($existing>0){
                    $sql="UPDATE dictionary SET value_en=:en, value_ar=:ar";
                    if(in_array('is_active',$cols,true)) $sql.=", is_active=:ia";
                    $sql.=" WHERE id=:id";
                    $bind=[':en'=>$en,':ar'=>$ar,':id'=>$existing];
                    if(in_array('is_active',$cols,true)) $bind[':ia']=$active;
                    $db->prepare($sql)->execute($bind);
                } else {
                    $fields = "org_id,dict_key,value_en,value_ar";
                    $vals   = ":o,:k,:en,:ar";
                    $bind   = [':o'=>$orgId,':k'=>$key,':en'=>$en,':ar'=>$ar];
                    if(in_array('is_active',$cols,true)){ $fields.=",is_active"; $vals.=", :ia"; $bind[':ia']=$active; }
                    $db->prepare("INSERT INTO dictionary($fields) VALUES($vals)")->execute($bind);
                }
            } else {
                $fields = "dict_key,value_en,value_ar";
                $vals   = ":k,:en,:ar";
                $bind   = [':k'=>$key,':en'=>$en,':ar'=>$ar];
                if(in_array('is_active',$cols,true)){ $fields.=",is_active"; $vals.=", :ia"; $bind[':ia']=$active; }
                $db->prepare("INSERT INTO dictionary($fields) VALUES($vals)")->execute($bind);
            }
        }

        if(function_exists('flash_set')) flash_set('success','Saved');
        header('Location: '.base_path('admin/dictionary')); exit;
    }

    public function toggle(): void
    {
        [$db,$orgId] = $this->guard();
        if(($_SERVER['REQUEST_METHOD']??'GET')!=='POST'){ http_response_code(405); exit; }

        $cols=$this->cols($db);
        if(!in_array('is_active',$cols,true)){ http_response_code(400); echo "No is_active column"; exit; }

        $id=(int)($_POST['id'] ?? 0);
        $hasOrg=$this->hasOrg($db);

        $sql="UPDATE dictionary SET is_active=IF(is_active=1,0,1) WHERE id=:id";
        $bind=[':id'=>$id];
        if($hasOrg){ $sql.=" AND (org_id=:o OR org_id IS NULL)"; $bind[':o']=$orgId; }
        $db->prepare($sql)->execute($bind);

        header('Location: '.base_path('admin/dictionary')); exit;
    }

    public function delete(): void
    {
        [$db,$orgId] = $this->guard();
        if(($_SERVER['REQUEST_METHOD']??'GET')!=='POST'){ http_response_code(405); exit; }

        $id=(int)($_POST['id'] ?? 0);
        $hasOrg=$this->hasOrg($db);

        $sql="DELETE FROM dictionary WHERE id=:id";
        $bind=[':id'=>$id];
        if($hasOrg){ $sql.=" AND (org_id=:o OR org_id IS NULL)"; $bind[':o']=$orgId; }
        $db->prepare($sql)->execute($bind);

        header('Location: '.base_path('admin/dictionary')); exit;
    }
}
