<?php
declare(strict_types=1);

namespace App\Controllers;

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

final class OwnerOrgsController extends Controller
{
    private function require_owner(): void {
        require_login();
        if(function_exists('is_superadmin') && is_superadmin()) return;
        http_response_code(403); echo "Forbidden"; exit;
    }

    private function split_name(string $full): array {
        $full = trim(preg_replace('/\s+/', ' ', $full));
        if($full==='') return ['',''];
        $parts = explode(' ', $full);
        $first = array_shift($parts);
        $last = trim(implode(' ', $parts));
        if($last==='') $last='-';
        return [$first, $last];
    }

    public function index(): void
    {
        $this->require_owner();
        $db=Database::getInstance();

        $orgs=$db->query("SELECT * FROM organizations ORDER BY id DESC")->fetchAll() ?: [];

        // KPI stats per org (best-effort)
        $kpi=[];
        foreach($orgs as $o){
          $oid=(int)$o['id'];
          $kpi[$oid]=[
            'admins'=>0,'users'=>0,'confs'=>0,'subs'=>0
          ];
        }

        if($db->query("SELECT COUNT(*) FROM information_schema.tables WHERE table_schema=DATABASE() AND table_name='org_users'")->fetchColumn()){
          $st=$db->query("SELECT org_id, SUM(role_code='org_admin' AND is_active=1) admins, COUNT(*) users FROM org_users GROUP BY org_id");
          foreach(($st->fetchAll()?:[]) as $r){
            $oid=(int)$r['org_id']; if(!isset($kpi[$oid])) continue;
            $kpi[$oid]['admins']=(int)$r['admins'];
            $kpi[$oid]['users']=(int)$r['users'];
          }
        }

        if($db->query("SELECT COUNT(*) FROM information_schema.tables WHERE table_schema=DATABASE() AND table_name='conferences'")->fetchColumn()){
          $st=$db->query("SELECT org_id, COUNT(*) confs FROM conferences GROUP BY org_id");
          foreach(($st->fetchAll()?:[]) as $r){
            $oid=(int)$r['org_id']; if(!isset($kpi[$oid])) continue;
            $kpi[$oid]['confs']=(int)$r['confs'];
          }
        }

        if($db->query("SELECT COUNT(*) FROM information_schema.tables WHERE table_schema=DATABASE() AND table_name='submissions'")->fetchColumn()){
          // via conferences.org_id (safe)
          $st=$db->query("SELECT c.org_id, COUNT(*) subs FROM submissions s JOIN conferences c ON c.id=s.conference_id GROUP BY c.org_id");
          foreach(($st->fetchAll()?:[]) as $r){
            $oid=(int)$r['org_id']; if(!isset($kpi[$oid])) continue;
            $kpi[$oid]['subs']=(int)$r['subs'];
          }
        }

        $st=$db->prepare("
          SELECT ou.org_id, ou.user_id, ou.role_code, ou.is_active,
                 o.code AS org_code, o.name AS org_name,
                 u.email
          FROM org_users ou
          JOIN organizations o ON o.id=ou.org_id
          JOIN users u ON u.id=ou.user_id
          WHERE ou.role_code='org_admin' AND ou.is_active=1
          ORDER BY ou.org_id DESC, ou.user_id DESC
        ");
        $st->execute();
        $admins=$st->fetchAll()?:[];

        $this->view('admin/owner_orgs/index', compact('orgs','admins','kpi'));
    }

    public function create(): void
    {
        $this->require_owner();
        $this->view('admin/owner_orgs/form', ['row'=>null]);
    }

    public function edit(): void
    {
        $this->require_owner();
        $db=Database::getInstance();
        $id=(int)($_GET['id']??0);
        $st=$db->prepare("SELECT * FROM organizations WHERE id=:id LIMIT 1");
        $st->execute([':id'=>$id]);
        $row=$st->fetch()?:null;
        if(!$row){ http_response_code(404); echo "Not found"; exit; }
        $this->view('admin/owner_orgs/form', ['row'=>$row]);
    }

    public function save(): void
    {
        $this->require_owner();
        if(($_SERVER['REQUEST_METHOD']??'GET')!=='POST'){ http_response_code(405); return; }

        $db=Database::getInstance();
        $id=(int)($_POST['id']??0);
        $code=trim((string)($_POST['code']??''));
        $name=trim((string)($_POST['name']??''));
        $active=(int)($_POST['is_active']??1);

        if($code==='' || $name===''){
          if(function_exists('flash_set')) flash_set('danger','Missing code/name');
          header('Location: '.base_path('admin/owner/orgs')); exit;
        }

        if($id>0){
          $st=$db->prepare("UPDATE organizations SET code=:c,name=:n,is_active=:a WHERE id=:id");
          $st->execute([':c'=>$code,':n'=>$name,':a'=>$active,':id'=>$id]);
        } else {
          $st=$db->prepare("INSERT INTO organizations(code,name,is_active) VALUES(:c,:n,:a)");
          $st->execute([':c'=>$code,':n'=>$name,':a'=>$active]);
        }

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

    public function toggle(): void
    {
        $this->require_owner();
        $db=Database::getInstance();
        $id=(int)($_GET['id']??0);
        if($id>0){
          $db->prepare("UPDATE organizations SET is_active=IF(is_active=1,0,1) WHERE id=:id")->execute([':id'=>$id]);
        }
        header('Location: '.base_path('admin/owner/orgs')); exit;
    }

    // Soft delete: mark inactive (safe)
    public function delete(): void
    {
        $this->require_owner();
        $db=Database::getInstance();
        $id=(int)($_GET['id']??0);
        if($id>0){
          $db->prepare("UPDATE organizations SET is_active=0 WHERE id=:id")->execute([':id'=>$id]);
          // also disable org_admin memberships (optional hardening)
          $db->prepare("UPDATE org_users SET is_active=0 WHERE org_id=:o")->execute([':o'=>$id]);
        }
        header('Location: '.base_path('admin/owner/orgs')); exit;
    }

    public function adminAdd(): void
    {
        $this->require_owner();
        if(($_SERVER['REQUEST_METHOD']??'GET')!=='POST'){ http_response_code(405); return; }

        $db=Database::getInstance();
        $orgId=(int)($_POST['org_id']??0);
        $mode = trim((string)($_POST['mode'] ?? 'existing'));

        if($orgId<=0){ header('Location: '.base_path('admin/owner/orgs')); exit; }

        $uid=0;

        if($mode==='create'){
          $full=trim((string)($_POST['full_name']??''));
          $email=trim((string)($_POST['email']??''));
          $mobile=trim((string)($_POST['mobile']??''));
          $pass=(string)($_POST['password']??'');

          if($full==='' || $email==='' || $mobile==='' || $pass===''){
            if(function_exists('flash_set')) flash_set('danger','Missing required fields (name/email/phone/password)');
            header('Location: '.base_path('admin/owner/orgs')); exit;
          }

          $st=$db->prepare("SELECT id FROM users WHERE email=:e LIMIT 1");
          $st->execute([':e'=>$email]);
          $uid=(int)($st->fetchColumn()?:0);

          if($uid<=0){
            [$first,$last] = $this->split_name($full);
            $hash = password_hash($pass, PASSWORD_BCRYPT);
            $st=$db->prepare("
              INSERT INTO users(role_id,first_name,last_name,email,password_hash,mobile,preferred_lang,is_active,created_at,updated_at)
              VALUES(1,:fn,:ln,:em,:ph,:mb,'ar',1,NOW(),NOW())
            ");
            $st->execute([':fn'=>$first,':ln'=>$last,':em'=>$email,':ph'=>$hash,':mb'=>$mobile]);
            $uid=(int)$db->lastInsertId();
          }
        } else {
          $email=trim((string)($_POST['email']??''));
          if($email===''){ header('Location: '.base_path('admin/owner/orgs')); exit; }

          $st=$db->prepare("SELECT id FROM users WHERE email=:e LIMIT 1");
          $st->execute([':e'=>$email]);
          $uid=(int)($st->fetchColumn()?:0);

          if($uid<=0){
            if(function_exists('flash_set')) flash_set('danger','User not found (use Create New User)');
            header('Location: '.base_path('admin/owner/orgs')); exit;
          }
        }

        $db->prepare("
          INSERT INTO org_users(org_id,user_id,role_code,is_active)
          VALUES(:o,:u,'org_admin',1)
          ON DUPLICATE KEY UPDATE role_code='org_admin', is_active=1
        ")->execute([':o'=>$orgId,':u'=>$uid]);

        if(function_exists('flash_set')) flash_set('success','Org admin assigned');
        header('Location: '.base_path('admin/owner/orgs')); exit;
    }

    public function adminRemove(): void
    {
        $this->require_owner();
        $db=Database::getInstance();
        $orgId=(int)($_GET['org_id']??0);
        $uid=(int)($_GET['user_id']??0);

        if($orgId>0 && $uid>0){
          $db->prepare("UPDATE org_users SET is_active=0 WHERE org_id=:o AND user_id=:u AND role_code='org_admin'")
             ->execute([':o'=>$orgId,':u'=>$uid]);
        }

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