<?php
require_once __DIR__ . '/../Core.php';
require_once __DIR__ . '/../models/Contact.php';
require_once __DIR__ . '/../models/Segment.php';
require_once __DIR__ . '/../models/Suppression.php';
require_once __DIR__ . '/../models/CustomField.php';
require_once __DIR__ . '/../models/ConsentLog.php';
require_once __DIR__ . '/../models/ContactTask.php';
require_once __DIR__ . '/../models/ContactNote.php';
require_once __DIR__ . '/../models/User.php';
require_once __DIR__ . '/../models/Account.php';
require_once __DIR__ . '/../models/Pipeline.php';
require_once __DIR__ . '/../models/Reminder.php';
require_once __DIR__ . '/../models/ContactList.php';

class ContactsController extends Controller
{
    public function index(): void
    {
        require_permission('contacts.view');
        $q = trim($_GET['q'] ?? '');
        $channel = $_GET['channel'] ?? 'all';
        $segmentId = (int)($_GET['segment_id'] ?? 0) ?: null;
        $page = max(1, (int)($_GET['page'] ?? 1));
        $result = (new Contact())->search($q, $channel, $page, 20, $segmentId);
        $segmentModel = new Segment();
        $segments = $segmentModel->all();
        foreach ($segments as &$segment) {
            $segment['member_count'] = $segmentModel->countMembers((int)$segment['id']);
        }
        $this->view('contacts/index', [
            'contacts' => $result['data'],
            'meta' => $result['meta'],
            'filters' => ['q' => $q, 'channel' => $channel, 'segment_id' => $segmentId],
            'segments' => $segments,
            'customFields' => (new CustomField())->all(),
            'users' => (new User())->all(),
            'accounts' => (new Account())->all(),
            'pipelines' => (new Pipeline())->all(),
            'contactLists' => (new ContactList())->all(),
        ]);
    }

    public function show(): void
    {
        require_permission('contacts.view');
        $id = (int)($_GET['id'] ?? 0);
        $contactModel = new Contact();
        $contact = $contactModel->find($id);
        if (!$contact) {
            http_response_code(404);
            exit('Contact not found.');
        }
        $suppression = new Suppression();
        $suppressed = [];
        if (!empty($contact['phone'])) {
            $suppressed['sms'] = $suppression->isSuppressed('sms', $contact['phone']);
        }
        if (!empty($contact['email'])) {
            $suppressed['email'] = $suppression->isSuppressed('email', $contact['email']);
        }
        $customFieldModel = new CustomField();
        $this->view('contacts/show', [
            'contact' => $contact,
            'summary' => $contactModel->engagementSummary($id),
            'timeline' => $contactModel->activityTimeline($id),
            'suppressed' => $suppressed,
            'customFields' => $customFieldModel->all(),
            'customValues' => $customFieldModel->valuesForContact($id),
            'consentLogs' => (new ConsentLog())->forContact($id),
            'tasks' => (new ContactTask())->forContact($id),
            'notes' => (new ContactNote())->forContact($id),
            'users' => (new User())->all(),
            'accounts' => (new Account())->all(),
            'pipelines' => (new Pipeline())->all(),
            'contactLists' => (new ContactList())->all(),
        ]);
    }

    public function save(): void
    {
        require_permission('contacts.manage');
        verify_csrf();
        try {
            $contactModel = new Contact();
            $listId = (int)($_POST['add_to_list_id'] ?? 0);
            $contactId = 0;
            $existing = null;
            if ($listId > 0) {
                $list = (new ContactList())->find($listId);
                if (!$list) {
                    throw new RuntimeException('The selected list was not found.');
                }
                $email = trim((string)($_POST['email'] ?? ''));
                $phone = trim((string)($_POST['phone'] ?? ''));
                if ($email !== '') {
                    $existing = $contactModel->findByAddress('email', $email);
                }
                if (!$existing && $phone !== '') {
                    $existing = $contactModel->findByAddress('sms', $phone);
                }
            }
            if ($existing) {
                $contactId = (int)$existing['id'];
            } else {
                $contactId = $contactModel->createAndGetId($_POST);
            }
            if ($listId > 0) {
                (new ContactList())->addMember($listId, $contactId);
                flash('success', $existing ? 'Existing contact added to the selected list.' : 'Contact saved and added to the selected list.');
            } else {
                flash('success', 'Contact saved successfully.');
            }
        } catch (Throwable $e) {
            flash('error', $e->getMessage());
        }
        redirect('contacts/index');
    }

    public function import(): void
    {
        require_permission('contacts.manage');
        verify_csrf();
        try {
            $file = upload_file($_FILES['csv_file'] ?? [], ['csv']);
            if (!$file) {
                throw new RuntimeException('Please upload a CSV file.');
            }
            $count = (new Contact())->importCsv(uploaded_file_path($file));
            flash('success', 'Imported ' . $count . ' contacts.');
        } catch (Throwable $e) {
            flash('error', $e->getMessage());
        }
        redirect('contacts/index');
    }

    public function exportCsv(): void
    {
        require_permission('messages.export');
        $q = trim($_GET['q'] ?? '');
        $channel = $_GET['channel'] ?? 'all';
        $segmentId = (int)($_GET['segment_id'] ?? 0) ?: null;
        $rows = (new Contact())->exportRows($q, $channel, $segmentId);
        header('Content-Type: text/csv');
        header('Content-Disposition: attachment; filename="contacts_export.csv"');
        $out = fopen('php://output', 'w');
        fputcsv($out, ['ID','First Name','Last Name','Phone','Email','Company','Tags','Timezone','Lifecycle Stage','Score','Unsubscribed SMS','Unsubscribed Email']);
        foreach ($rows as $row) {
            fputcsv($out, [$row['id'], $row['first_name'], $row['last_name'], $row['phone'], $row['email'], $row['company'], $row['tags'], $row['timezone'] ?? '', $row['lifecycle_stage'] ?? '', $row['score'] ?? 0, $row['unsubscribed_sms'], $row['unsubscribed_email']]);
        }
        fclose($out);
        exit;
    }

    public function delete(): void
    {
        require_permission('contacts.delete');
        $id = (int)($_GET['id'] ?? 0);
        if ($id) {
            (new Contact())->delete($id);
            flash('success', 'Contact deleted.');
        }
        redirect('contacts/index');
    }

    public function saveSegment(): void
    {
        require_permission('segments.manage');
        verify_csrf();
        $id = (new Segment())->create($_POST);
        audit_log('segment.created', 'segment', $id, ['name' => $_POST['name'] ?? null]);
        flash('success', 'Segment saved.');
        redirect('contacts/index');
    }

    public function deleteSegment(): void
    {
        require_permission('segments.manage');
        $id = (int)($_GET['id'] ?? 0);
        if ($id) {
            (new Segment())->delete($id);
            audit_log('segment.deleted', 'segment', $id);
            flash('success', 'Segment deleted.');
        }
        redirect('contacts/index');
    }



    public function saveContactList(): void
    {
        require_permission('contacts.manage');
        verify_csrf();
        $id = (new ContactList())->create([
            'name' => $_POST['name'] ?? '',
            'channel' => $_POST['channel'] ?? 'both',
            'description' => $_POST['description'] ?? '',
            'created_by' => current_user()['id'] ?? null,
        ]);
        audit_log('contact_list.created', 'contact_list', $id, ['name' => $_POST['name'] ?? '']);
        flash('success', 'Contact list saved.');
        redirect('contacts/index');
    }

    public function importContactList(): void
    {
        require_permission('contacts.manage');
        verify_csrf();
        $listId = (int)($_POST['list_id'] ?? 0);
        try {
            $file = upload_file($_FILES['csv_file'] ?? [], ['csv']);
            if (!$file) {
                throw new RuntimeException('Please upload a CSV file.');
            }
            $count = (new ContactList())->importCsv($listId, uploaded_file_path($file));
            audit_log('contact_list.imported', 'contact_list', $listId, ['count' => $count]);
            flash('success', 'Imported ' . $count . ' list members.');
        } catch (Throwable $e) {
            flash('error', $e->getMessage());
        }
        redirect('contacts/index');
    }

    public function deleteContactList(): void
    {
        require_permission('contacts.manage');
        $id = (int)($_GET['id'] ?? 0);
        if ($id) {
            (new ContactList())->delete($id);
            audit_log('contact_list.deleted', 'contact_list', $id);
            flash('success', 'Contact list deleted.');
        }
        redirect('contacts/index');
    }

    public function saveCustomValues(): void
    {
        require_permission('contacts.manage');
        verify_csrf();
        $contactId = (int)($_POST['contact_id'] ?? 0);
        (new CustomField())->saveValuesForContact($contactId, $_POST['custom'] ?? []);
        audit_log('contact.custom_fields.updated', 'contact', $contactId);
        flash('success', 'Custom field values saved.');
        redirect_url('index.php?route=contacts/show&id=' . $contactId);
    }

    public function addConsent(): void
    {
        require_permission('contacts.manage');
        verify_csrf();
        $contactId = (int)($_POST['contact_id'] ?? 0);
        $channel = $_POST['channel'] ?? 'email';
        $status = $_POST['status'] ?? 'opt_in';
        (new ConsentLog())->create([
            'contact_id' => $contactId,
            'channel' => $channel,
            'status' => $status,
            'source' => trim($_POST['source'] ?? 'manual'),
            'proof_note' => trim($_POST['proof_note'] ?? ''),
            'ip_address' => $_SERVER['REMOTE_ADDR'] ?? null,
            'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? null,
            'created_by' => current_user()['id'] ?? null,
        ]);
        $contact = (new Contact())->find($contactId);
        if ($contact) {
            if ($channel === 'sms') {
                (new Contact())->setUnsubscribed('sms', (string)$contact['phone'], $status !== 'opt_in');
            } else {
                (new Contact())->setUnsubscribed('email', (string)$contact['email'], $status !== 'opt_in');
            }
        }
        audit_log('contact.consent.logged', 'contact', $contactId, ['channel' => $channel, 'status' => $status]);
        flash('success', 'Consent record added.');
        redirect_url('index.php?route=contacts/show&id=' . $contactId);
    }

    public function updateProfile(): void
    {
        require_permission('contacts.manage');
        verify_csrf();
        $contactId = (int)($_POST['contact_id'] ?? 0);
        if ($contactId > 0) {
            (new Contact())->updateLifecycleProfile($contactId, [
                'lifecycle_stage' => $_POST['lifecycle_stage'] ?? 'lead',
                'score' => (int)($_POST['score'] ?? 0),
                'owner_user_id' => (int)($_POST['owner_user_id'] ?? 0) ?: null,
            ]);
            audit_log('contact.profile.updated', 'contact', $contactId, ['lifecycle_stage' => $_POST['lifecycle_stage'] ?? 'lead', 'score' => (int)($_POST['score'] ?? 0)]);
            flash('success', 'Contact lifecycle profile updated.');
        }
        redirect_url('index.php?route=contacts/show&id=' . $contactId);
    }

    public function addTask(): void
    {
        require_permission('contacts.manage');
        verify_csrf();
        $contactId = (int)($_POST['contact_id'] ?? 0);
        $taskId = (new ContactTask())->create($_POST);
        audit_log('contact.task.created', 'contact_task', $taskId, ['contact_id' => $contactId]);
        flash('success', 'Task added.');
        redirect_url('index.php?route=contacts/show&id=' . $contactId);
    }

    public function completeTask(): void
    {
        require_permission('contacts.manage');
        $taskId = (int)($_GET['task_id'] ?? 0);
        $contactId = (int)($_GET['contact_id'] ?? 0);
        if ($taskId > 0) {
            (new ContactTask())->markDone($taskId);
            audit_log('contact.task.completed', 'contact_task', $taskId, ['contact_id' => $contactId]);
            flash('success', 'Task marked done.');
        }
        redirect_url('index.php?route=contacts/show&id=' . $contactId);
    }

    public function addNote(): void
    {
        require_permission('contacts.manage');
        verify_csrf();
        $contactId = (int)($_POST['contact_id'] ?? 0);
        $noteId = (new ContactNote())->create($_POST);
        audit_log('contact.note.created', 'contact_note', $noteId, ['contact_id' => $contactId]);
        flash('success', 'Note added.');
        redirect_url('index.php?route=contacts/show&id=' . $contactId);
    }

    public function addReminder(): void
    {
        require_permission('contacts.manage');
        verify_csrf();
        $contactId = (int)($_POST['contact_id'] ?? 0);
        $id = (new Reminder())->create($_POST);
        audit_log('contact.reminder.created', 'reminder', $id, ['contact_id' => $contactId]);
        flash('success', 'Reminder added.');
        redirect_url('index.php?route=contacts/show&id=' . $contactId);
    }

    public function completeReminder(): void
    {
        require_permission('contacts.manage');
        $contactId = (int)($_GET['contact_id'] ?? 0);
        $reminderId = (int)($_GET['reminder_id'] ?? 0);
        if ($reminderId) {
            (new Reminder())->markDone($reminderId);
            audit_log('contact.reminder.completed', 'reminder', $reminderId, ['contact_id' => $contactId]);
            flash('success', 'Reminder completed.');
        }
        redirect_url('index.php?route=contacts/show&id=' . $contactId);
    }
}
