<?php
declare(strict_types=1);

namespace App\Modules\Workflow\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;
use App\Core\App;
use App\Modules\Workflow\Models\WorkflowDefinition;
use App\Modules\Workflow\Models\WorkflowInstance;
use App\Modules\Workflow\Models\WorkflowTransitionLog;
use App\Modules\Workflow\Services\WorkflowEngine;

class WorkflowController extends Controller
{
    public function index(Request $request): Response
    {
        $definitions = WorkflowDefinition::allActive();

        $db = App::getInstance()->db();
        $stats = [];
        foreach ($definitions as $def) {
            $activeCount = $db->selectOne(
                "SELECT COUNT(*) as cnt FROM workflow_instances WHERE workflow_code = ? AND is_completed = 0",
                [$def['workflow_code']]
            );
            $completedCount = $db->selectOne(
                "SELECT COUNT(*) as cnt FROM workflow_instances WHERE workflow_code = ? AND is_completed = 1",
                [$def['workflow_code']]
            );
            $stats[$def['workflow_code']] = [
                'active'    => (int) ($activeCount['cnt'] ?? 0),
                'completed' => (int) ($completedCount['cnt'] ?? 0),
            ];
        }

        return $this->view('Workflow.Views.index', [
            'definitions' => $definitions,
            'stats'       => $stats,
        ]);
    }

    public function instance(Request $request, string $id): Response
    {
        $instance = WorkflowInstance::find((int) $id);
        if (!$instance) {
            return $this->redirect('/workflows')->withError('مثيل دورة العمل غير موجود');
        }

        $definition = $instance->getDefinition();
        $history = WorkflowEngine::getHistory((int) $instance->id);
        $available = WorkflowEngine::getAvailableTransitions((int) $instance->id);

        return $this->view('Workflow.Views.instance', [
            'instance'   => $instance,
            'definition' => $definition,
            'history'    => $history,
            'available'  => $available,
        ]);
    }

    public function transition(Request $request, string $id): Response
    {
        $transitionName = trim((string) $request->post('transition_name', ''));
        $notes = trim((string) $request->post('notes', ''));

        if ($transitionName === '') {
            return $this->redirect("/workflows/instances/{$id}")->withError('يرجى تحديد الانتقال');
        }

        try {
            WorkflowEngine::transition((int) $id, $transitionName, $notes ?: null, 'manual');
            return $this->redirect("/workflows/instances/{$id}")->withSuccess('تم تنفيذ الانتقال بنجاح');
        } catch (\RuntimeException $e) {
            return $this->redirect("/workflows/instances/{$id}")->withError('فشل تنفيذ الانتقال: ' . $e->getMessage());
        }
    }

    public function diagram(Request $request, string $code): Response
    {
        $definition = WorkflowDefinition::findByCode($code);
        if (!$definition) {
            return $this->redirect('/workflows')->withError('تعريف دورة العمل غير موجود');
        }

        return $this->view('Workflow.Views.diagram', [
            'definition' => $definition,
        ]);
    }

    public function instances(Request $request, string $code): Response
    {
        $db = App::getInstance()->db();
        $status = $request->get('status', '');

        $where = "wi.workflow_code = ?";
        $params = [$code];

        if ($status === 'active') {
            $where .= " AND wi.is_completed = 0";
        } elseif ($status === 'completed') {
            $where .= " AND wi.is_completed = 1";
        }

        $rows = $db->select(
            "SELECT wi.*, wd.name_ar as definition_name_ar
             FROM workflow_instances wi
             JOIN workflow_definitions wd ON wd.id = wi.workflow_definition_id
             WHERE {$where}
             ORDER BY wi.updated_at DESC
             LIMIT 100",
            $params
        );

        $definition = WorkflowDefinition::findByCode($code);

        return $this->view('Workflow.Views.index', [
            'definitions'      => WorkflowDefinition::allActive(),
            'stats'            => [],
            'filteredInstances' => $rows,
            'filterCode'       => $code,
            'filterStatus'     => $status,
            'currentDef'       => $definition,
        ]);
    }

    public function processTimeouts(Request $request): Response
    {
        $processed = WorkflowEngine::processTimeouts();
        $count = count($processed);
        return $this->redirect('/workflows')->withSuccess("تم معالجة {$count} انتقال تلقائي");
    }

    public function edit(Request $request, string $code): Response
    {
        $definition = WorkflowDefinition::findByCode($code);
        if (!$definition) {
            return $this->redirect('/workflows')->withError('تعريف دورة العمل غير موجود');
        }

        return $this->view('Workflow.Views.edit', [
            'definition' => $definition,
        ]);
    }

    public function update(Request $request, string $code): Response
    {
        $db = App::getInstance()->db();

        $definition = WorkflowDefinition::findByCode($code);
        if (!$definition) {
            return $this->redirect('/workflows')->withError('تعريف دورة العمل غير موجود');
        }

        $nameAr = trim((string) $request->post('name_ar', ''));
        $nameEn = trim((string) $request->post('name_en', ''));
        $descriptionAr = trim((string) $request->post('description_ar', ''));

        if ($nameAr === '') {
            return $this->redirect("/workflows/edit/{$code}")->withError('الاسم بالعربي مطلوب');
        }

        $defJson = $definition->getDefinition();

        // Update state labels
        $statesInput = $request->post('states', []);
        if (is_array($statesInput)) {
            foreach ($statesInput as $key => $stateData) {
                if (isset($defJson['states'][$key])) {
                    if (!empty($stateData['label_ar'])) {
                        $defJson['states'][$key]['label_ar'] = trim($stateData['label_ar']);
                    }
                    if (!empty($stateData['label_en'])) {
                        $defJson['states'][$key]['label_en'] = trim($stateData['label_en']);
                    }
                }
            }
        }

        // Update transition triggers
        $transitionsInput = $request->post('transitions', []);
        if (is_array($transitionsInput)) {
            foreach ($transitionsInput as $idx => $tData) {
                if (isset($defJson['transitions'][$idx]) && !empty($tData['trigger_edit'])) {
                    $defJson['transitions'][$idx]['trigger'] = $tData['trigger_edit'];
                }
            }
        }

        $newVersion = (int) $definition->version + 1;

        $db->update('workflow_definitions', [
            'name_ar'         => $nameAr,
            'name_en'         => $nameEn ?: null,
            'description_ar'  => $descriptionAr ?: null,
            'definition_json' => json_encode($defJson, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT),
            'version'         => $newVersion,
            'updated_at'      => date('Y-m-d H:i:s'),
        ], '`id` = ?', [(int) $definition->id]);

        return $this->redirect("/workflows/diagram/{$code}")->withSuccess('تم تحديث دورة العمل — الإصدار ' . $newVersion);
    }
}