<?php

namespace App\Controllers;

use App\Core\Controller;
use App\Helpers\Auth;
use App\Helpers\Mailer;
use App\Helpers\Url;
use App\Models\DynamicForm;
use App\Models\DynamicFormField;
use App\Models\DynamicFormSubmission;
use App\Models\FieldTemplate;
use App\Models\FormShare;
use App\Models\AuditLog;
use App\Models\User;

class DynamicFormController extends Controller
{
    public function __construct()
    {
        parent::__construct();
    }

    public function index()
    {
        Auth::requireLogin();
        $model = new DynamicForm();
        $forms = $model->getActive();
        $templates = $model->getTemplates();
        $fieldTemplateModel = new FieldTemplate();
        $fieldTemplates = $fieldTemplateModel->getAllTemplates();
        $this->view('forms/index', [
            'forms' => $forms,
            'templates' => $templates,
            'fieldTemplates' => $fieldTemplates,
        ]);
    }

    public function create()
    {
        Auth::requireLogin();
        $fromTemplate = isset($_GET['from_template']) ? $_GET['from_template'] : null;
        $templateData = null;
        if ($fromTemplate) {
            $model = new DynamicForm();
            $templateData = $model->getWithFields($fromTemplate);
        }
        $fieldTemplateModel = new FieldTemplate();
        $fieldTemplates = $fieldTemplateModel->getAllTemplates();
        $this->view('forms/create', [
            'templateData' => $templateData,
            'fieldTemplates' => $fieldTemplates,
        ]);
    }

    public function store()
    {
        Auth::requireLogin();
        $model = new DynamicForm();
        $formId = $model->create([
            'title' => $_POST['title'] ?? '',
            'description' => $_POST['description'] ?? '',
            'table_name' => 'form_' . time(),
            'is_active' => isset($_POST['is_active']) ? 1 : 0,
            'requires_auth' => isset($_POST['requires_auth']) ? 1 : 0,
            'allow_public_submissions' => isset($_POST['allow_public_submissions']) ? 1 : 0,
            'created_by' => Auth::id(),
        ]);

        $labels = $_POST['field_label'] ?? [];
        $types = $_POST['field_type'] ?? [];
        $required = $_POST['field_required'] ?? [];

        $fieldModel = new DynamicFormField();
        foreach ($labels as $i => $label) {
            if (empty($label)) continue;
            $fieldName = 'field_' . ($i + 1);
            $fieldModel->create([
                'form_id' => $formId,
                'label' => $label,
                'field_name' => $fieldName,
                'field_type' => $types[$i] ?? 'text',
                'options' => $_POST['field_options'][$i] ?? null,
                'is_required' => isset($required[$i]) ? 1 : 0,
                'placeholder' => $_POST['field_placeholder'][$i] ?? null,
                'sort_order' => $i + 1,
            ]);
        }

        $audit = new AuditLog();
        $audit->log(Auth::id(), 'form.create', 'dynamic_forms', $formId, "Created dynamic form: {$_POST['title']}");

        $_SESSION['success'] = 'Form created successfully';
        $this->redirect('/forms');
    }

    public function show($params)
    {
        $formId = $params['id'] ?? null;
        $model = new DynamicForm();
        $form = $model->getWithFields($formId);

        if (!$form || !$form->is_active) {
            $_SESSION['error'] = 'Form not found';
            $this->redirect('/forms');
        }

        if ($form->requires_auth) {
            Auth::requireLogin();
        }

        $this->view('forms/show', ['form' => $form]);
    }

    public function submit($params)
    {
        $formId = $params['id'] ?? null;
        $model = new DynamicForm();
        $form = $model->getWithFields($formId);

        if (!$form || !$form->is_active) {
            $_SESSION['error'] = 'Form not found';
            $this->redirect('/forms');
        }

        if ($form->requires_auth) {
            Auth::requireLogin();
        }

        $submissionData = [];
        foreach ($form->fields as $field) {
            $value = $_POST[$field->field_name] ?? '';
            if ($field->field_type === 'file' && isset($_FILES[$field->field_name]) && $_FILES[$field->field_name]['error'] === UPLOAD_ERR_OK) {
                $uploadDir = $_SERVER['DOCUMENT_ROOT'] . Url::getBaseUrl() . '/uploads/form_files/';
                if (!is_dir($uploadDir)) mkdir($uploadDir, 0777, true);
                $filename = 'form_' . time() . '_' . basename($_FILES[$field->field_name]['name']);
                move_uploaded_file($_FILES[$field->field_name]['tmp_name'], $uploadDir . $filename);
                $value = '/uploads/form_files/' . $filename;
            }
            $submissionData[$field->field_name] = $value;
        }

        $submissionModel = new DynamicFormSubmission();
        $submissionModel->create([
            'form_id' => $formId,
            'user_id' => Auth::check() ? Auth::id() : null,
            'data' => json_encode($submissionData),
        ]);

        $_SESSION['success'] = 'Form submitted successfully';
        $this->redirect('/forms/' . $formId . '/thank-you');
    }

    public function submissions($params)
    {
        Auth::requireLogin();
        $formId = $params['id'] ?? null;
        $model = new DynamicFormSubmission();
        $submissions = $model->getByForm($formId);
        $formModel = new DynamicForm();
        $form = $formModel->getWithFields($formId);
        $this->view('forms/submissions', ['submissions' => $submissions, 'form' => $form]);
    }

    public function thankYou($params)
    {
        $formId = $params['id'] ?? null;
        $formModel = new DynamicForm();
        $form = $formModel->find($formId);
        $this->view('forms/thank_you', ['form' => $form]);
    }

    public function edit($params)
    {
        Auth::requireLogin();
        $formId = $params['id'] ?? null;
        $model = new DynamicForm();
        $form = $model->getWithFields($formId);
        if (!$form) {
            $_SESSION['error'] = 'Form not found';
            $this->redirect('/forms');
        }
        $fieldTemplateModel = new FieldTemplate();
        $fieldTemplates = $fieldTemplateModel->getAllTemplates();
        $this->view('forms/edit', ['form' => $form, 'fieldTemplates' => $fieldTemplates]);
    }

    public function update($params)
    {
        Auth::requireLogin();
        $formId = $params['id'] ?? null;
        $model = new DynamicForm();
        $form = $model->find($formId);
        if (!$form) {
            $_SESSION['error'] = 'Form not found';
            $this->redirect('/forms');
        }

        $model->update($formId, [
            'title' => $_POST['title'] ?? '',
            'description' => $_POST['description'] ?? '',
            'is_active' => isset($_POST['is_active']) ? 1 : 0,
            'requires_auth' => isset($_POST['requires_auth']) ? 1 : 0,
            'allow_public_submissions' => isset($_POST['allow_public_submissions']) ? 1 : 0,
        ]);

        $fieldModel = new DynamicFormField();
        $existingFields = $fieldModel->getByForm($formId);
        foreach ($existingFields as $ef) {
            $fieldModel->delete($ef->id);
        }

        $labels = $_POST['field_label'] ?? [];
        $types = $_POST['field_type'] ?? [];
        $required = $_POST['field_required'] ?? [];

        foreach ($labels as $i => $label) {
            if (empty($label)) continue;
            $fieldModel->create([
                'form_id' => $formId,
                'label' => $label,
                'field_name' => 'field_' . ($i + 1),
                'field_type' => $types[$i] ?? 'text',
                'options' => $_POST['field_options'][$i] ?? null,
                'is_required' => isset($required[$i]) ? 1 : 0,
                'placeholder' => $_POST['field_placeholder'][$i] ?? null,
                'sort_order' => $i + 1,
            ]);
        }

        $_SESSION['success'] = 'Form updated successfully';
        $this->redirect('/forms');
    }

    public function delete($params)
    {
        Auth::requireLogin();
        $id = $params['id'] ?? null;
        $model = new DynamicForm();
        $form = $model->find($id);
        if ($form) {
            $audit = new AuditLog();
            $audit->log(Auth::id(), 'form.delete', 'dynamic_forms', $id, "Deleted form: {$form->title}");
            $model->delete($id);
            $_SESSION['success'] = 'Form deleted';
        }
        $this->redirect('/forms');
    }

    // ---- DUPLICATE ----
    public function duplicate($params)
    {
        Auth::requireLogin();
        $id = $params['id'] ?? null;
        $model = new DynamicForm();
        $original = $model->find($id);
        if (!$original) {
            $_SESSION['error'] = 'Form not found';
            $this->redirect('/forms');
        }
        $newTitle = ($original->title ?: 'Untitled') . ' (Copy)';
        $newId = $model->duplicate($id, $newTitle, Auth::id());
        if ($newId) {
            $audit = new AuditLog();
            $audit->log(Auth::id(), 'form.duplicate', 'dynamic_forms', $newId, "Duplicated form '{$original->title}' as '{$newTitle}'");
            $_SESSION['success'] = "Form duplicated as '{$newTitle}'";
        } else {
            $_SESSION['error'] = 'Failed to duplicate form';
        }
        $this->redirect('/forms');
    }

    // ---- SAVE AS TEMPLATE ----
    public function saveAsTemplate($params)
    {
        Auth::requireLogin();
        $id = $params['id'] ?? null;
        $model = new DynamicForm();
        $original = $model->getWithFields($id);
        if (!$original) {
            $_SESSION['error'] = 'Form not found';
            $this->redirect('/forms');
        }
        $templateName = $_POST['template_name'] ?? ($original->title . ' Template');
        $newId = $model->create([
            'title' => $original->title,
            'description' => $original->description,
            'table_name' => 'template_' . time(),
            'is_active' => 0,
            'requires_auth' => $original->requires_auth,
            'is_template' => 1,
            'template_name' => $templateName,
            'source_form_id' => $id,
            'created_by' => Auth::id(),
        ]);
        $fieldModel = new DynamicFormField();
        foreach ($original->fields as $i => $field) {
            $fieldModel->create([
                'form_id' => $newId,
                'label' => $field->label,
                'field_name' => 'field_' . ($i + 1),
                'field_type' => $field->field_type,
                'options' => $field->options,
                'is_required' => $field->is_required,
                'placeholder' => $field->placeholder,
                'sort_order' => $i + 1,
            ]);
        }
        $audit = new AuditLog();
        $audit->log(Auth::id(), 'form.save_template', 'dynamic_forms', $newId, "Saved form '{$original->title}' as template '{$templateName}'");
        $_SESSION['success'] = "Form saved as template '{$templateName}'";
        $this->redirect('/forms');
    }

    public function deleteTemplate($params)
    {
        Auth::requireLogin();
        $id = $params['id'] ?? null;
        $model = new DynamicForm();
        $form = $model->find($id);
        if ($form && $form->is_template) {
            $audit = new AuditLog();
            $audit->log(Auth::id(), 'form.delete_template', 'dynamic_forms', $id, "Deleted template: {$form->template_name}");
            $model->delete($id);
            $_SESSION['success'] = 'Template deleted';
        }
        $this->redirect('/forms');
    }

    // ---- FIELD TEMPLATES ----
    public function fieldTemplates()
    {
        Auth::requireLogin();
        $model = new FieldTemplate();
        $templates = $model->getAllTemplates();
        $this->view('forms/field_templates', ['fieldTemplates' => $templates]);
    }

    public function storeFieldTemplate()
    {
        Auth::requireLogin();
        $model = new FieldTemplate();
        $model->create([
            'name' => $_POST['name'] ?? '',
            'field_type' => $_POST['field_type'] ?? 'text',
            'label' => $_POST['label'] ?? '',
            'options' => $_POST['options'] ?? null,
            'is_required' => isset($_POST['is_required']) ? 1 : 0,
            'placeholder' => $_POST['placeholder'] ?? null,
            'validation_rules' => $_POST['validation_rules'] ?? null,
            'created_by' => Auth::id(),
        ]);
        $_SESSION['success'] = 'Field template saved';
        $this->redirect('/forms/field-templates');
    }

    public function deleteFieldTemplate($params)
    {
        Auth::requireLogin();
        $id = $params['id'] ?? null;
        $model = new FieldTemplate();
        $model->delete($id);
        $_SESSION['success'] = 'Field template deleted';
        $this->redirect('/forms/field-templates');
    }

    // ---- SHARING ----
    public function share($params)
    {
        Auth::requireLogin();
        $formId = $params['id'] ?? null;
        $formModel = new DynamicForm();
        $form = $formModel->find($formId);
        if (!$form) {
            $_SESSION['error'] = 'Form not found';
            $this->redirect('/forms');
        }
        $shareModel = new FormShare();
        $shares = $shareModel->getSharesForForm($formId);
        $userModel = new User();
        $members = $userModel->where('approval_status', 'approved');
        $this->view('forms/share', ['form' => $form, 'shares' => $shares, 'members' => $members]);
    }

    public function generateShareLink($params)
    {
        Auth::requireLogin();
        $formId = $params['id'] ?? null;
        $formModel = new DynamicForm();
        $form = $formModel->find($formId);
        if (!$form) {
            $_SESSION['error'] = 'Form not found';
            $this->json(['error' => 'Form not found'], 404);
        }
        $shareModel = new FormShare();
        $token = $shareModel->generateToken();
        $expiresAt = !empty($_POST['expires_in']) ? date('Y-m-d H:i:s', strtotime($_POST['expires_in'])) : null;
        $shareModel->create([
            'form_id' => $formId,
            'token' => $token,
            'shared_by' => Auth::id(),
            'shared_with' => !empty($_POST['shared_with']) ? $_POST['shared_with'] : null,
            'message' => $_POST['message'] ?? null,
            'expires_at' => $expiresAt,
        ]);
        $audit = new AuditLog();
        $audit->log(Auth::id(), 'form.share', 'dynamic_forms', $formId, "Generated share link for form '{$form->title}'");
        $shareUrl = Url::to('/forms/shared/' . $token);
        $_SESSION['success'] = 'Share link generated';
        $this->redirect('/forms/' . $formId . '/share');
    }

    public function revokeShare($params)
    {
        Auth::requireLogin();
        $shareId = $params['shareId'] ?? null;
        $shareModel = new FormShare();
        $share = $shareModel->find($shareId);
        if ($share) {
            $shareModel->delete($shareId);
            $_SESSION['success'] = 'Share link revoked';
        }
        $this->redirect('/forms/' . ($share->form_id ?? '') . '/share');
    }

    public function sendShare($params)
    {
        Auth::requireLogin();
        $formId = $params['id'] ?? null;
        $shareToken = $params['token'] ?? null;
        $recipientIds = $_POST['recipients'] ?? [];
        $message = $_POST['personal_message'] ?? '';

        if (empty($recipientIds)) {
            $_SESSION['error'] = 'Please select at least one recipient';
            $this->redirect('/forms/' . $formId . '/share');
        }

        $formModel = new DynamicForm();
        $form = $formModel->find($formId);
        $shareUrl = Url::to('/forms/shared/' . $shareToken);
        $userModel = new User();
        $senderName = Auth::user()->name;

        foreach ($recipientIds as $uid) {
            $user = $userModel->find($uid);
            if (!$user || !$user->email) continue;
            $recipientName = $user->first_name ? trim($user->first_name . ' ' . $user->last_name) : $user->name;
            $subject = "Form Shared: {$form->title}";
            $body = "<p>Dear {$recipientName},</p><p><strong>{$senderName}</strong> has shared a form with you: <strong>{$form->title}</strong>.</p>";
            if ($message) $body .= "<p><em>{$message}</em></p>";
            $body .= "<p><a href='{$shareUrl}' style='display:inline-block;padding:12px 30px;background:linear-gradient(135deg,#4e73df,#224abe);color:white;text-decoration:none;border-radius:8px;font-weight:bold;'>Open Form</a></p>";
            Mailer::send($user->email, $subject, $body);
            $this->db->prepare("INSERT INTO messages (sender_id, subject, body) VALUES (?, ?, ?)")->execute([Auth::id(), $subject, strip_tags(str_replace('</p>', "\n\n", $body))]);
            $msgId = $this->db->lastInsertId();
            $this->db->prepare("INSERT INTO message_recipients (message_id, recipient_id) VALUES (?, ?)")->execute([$msgId, $uid]);
        }

        $_SESSION['success'] = 'Form shared with ' . count($recipientIds) . ' member(s)';
        $this->redirect('/forms/' . $formId . '/share');
    }

    public function accessShared($params)
    {
        $token = $params['token'] ?? null;
        if (!$token) {
            $_SESSION['error'] = 'Invalid share link';
            $this->redirect('/forms');
        }
        $model = new DynamicForm();
        $form = $model->getByShareToken($token);
        if (!$form) {
            $_SESSION['error'] = 'Share link is invalid or expired';
            $this->redirect('/forms');
        }
        $this->view('forms/show', ['form' => $form, 'sharedToken' => $token]);
    }

    public function submitShared($params)
    {
        $token = $params['token'] ?? null;
        if (!$token) {
            $_SESSION['error'] = 'Invalid share link';
            $this->redirect('/forms');
        }
        $model = new DynamicForm();
        $form = $model->getByShareToken($token);
        if (!$form) {
            $_SESSION['error'] = 'Share link is invalid or expired';
            $this->redirect('/forms');
        }

        $submissionData = [];
        foreach ($form->fields as $field) {
            $value = $_POST[$field->field_name] ?? '';
            if ($field->field_type === 'file' && isset($_FILES[$field->field_name]) && $_FILES[$field->field_name]['error'] === UPLOAD_ERR_OK) {
                $uploadDir = $_SERVER['DOCUMENT_ROOT'] . Url::getBaseUrl() . '/uploads/form_files/';
                if (!is_dir($uploadDir)) mkdir($uploadDir, 0777, true);
                $filename = 'form_' . time() . '_' . basename($_FILES[$field->field_name]['name']);
                move_uploaded_file($_FILES[$field->field_name]['tmp_name'], $uploadDir . $filename);
                $value = '/uploads/form_files/' . $filename;
            }
            $submissionData[$field->field_name] = $value;
        }

        $submissionModel = new DynamicFormSubmission();
        $submissionModel->create([
            'form_id' => $form->id,
            'user_id' => Auth::check() ? Auth::id() : null,
            'data' => json_encode($submissionData),
        ]);

        $_SESSION['success'] = 'Form submitted successfully';
        $this->redirect('/forms/shared/' . $token . '/thank-you');
    }

    public function thankYouShared($params)
    {
        $token = $params['token'] ?? null;
        $this->view('forms/thank_you', ['sharedToken' => $token]);
    }
}
