<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Core\BaseController;
use App\Core\Database;
use App\Core\Request;
use App\Core\Response;
use App\Helpers\AjaxResponse;
use App\Models\EmailMessageModel;
use App\Services\ActivityLogger;
use App\Services\MailService;

/**
 * PersonalEmailController
 *
 * "Send Individual Email" from the brief — a single, immediate,
 * synchronous send (not queued, since it's one email a staff member is
 * actively waiting on) to one lead or customer, logged to
 * email_messages so it shows up in that record's Communication
 * History alongside campaign sends.
 */
final class PersonalEmailController extends BaseController
{
    public function index(Request $request): Response
    {
        $rows = (new EmailMessageModel())->recentSent();

        return AjaxResponse::success($rows);
    }

    public function forEntity(Request $request, array $params): Response
    {
        $rows = (new EmailMessageModel())->forEntity($params['entityType'], (int) $params['entityId']);

        return AjaxResponse::success($rows);
    }

    public function send(Request $request): Response
    {
        $data = $this->validateOrFail($request, [
            'to_email' => 'required|email',
            'to_name' => 'nullable|string|max:191',
            'subject' => 'required|string|max:255',
            'body_html' => 'required|string',
            'related_lead_id' => 'nullable|integer|exists:leads,id',
            'related_customer_id' => 'nullable|integer|exists:customers,id',
        ]);

        $user = $this->currentUser();
        $businessLineId = $this->resolveBusinessLineId($data['related_lead_id'] ?? null, $data['related_customer_id'] ?? null);
        $mailer = new MailService();
        $sent = $mailer->send($data['to_email'], $data['to_name'] ?? '', $data['subject'], $data['body_html'], businessLineId: $businessLineId);

        $model = new EmailMessageModel();
        $messageId = $model->insert([
            'direction' => 'outbound',
            'related_lead_id' => $data['related_lead_id'] ?? null,
            'related_customer_id' => $data['related_customer_id'] ?? null,
            'from_address' => $user['email'],
            'to_address' => $data['to_email'],
            'subject' => $data['subject'],
            'body_html' => $data['body_html'],
            'status' => $sent ? 'sent' : 'failed',
            'sent_at' => $sent ? now() : null,
        ]);

        if (!empty($data['related_lead_id'])) {
            ActivityLogger::record('lead', (int) $data['related_lead_id'], 'email_sent', "Sent email: \"{$data['subject']}\"");
        }
        if (!empty($data['related_customer_id'])) {
            ActivityLogger::record('customer', (int) $data['related_customer_id'], 'email_sent', "Sent email: \"{$data['subject']}\"");
        }

        return $sent
            ? AjaxResponse::created(['id' => $messageId], 'Email sent.')
            : AjaxResponse::error('Could not send the email — check SMTP Settings and storage/logs.', 422);
    }

    /** Looks up which business line this personal email relates to, so MailService can append that company's signature — a personal email to a Cleaner lead should never carry Homecare's footer, or vice versa. */
    private function resolveBusinessLineId(?int $relatedLeadId, ?int $relatedCustomerId): ?int
    {
        $pdo = Database::connection();

        if ($relatedLeadId !== null) {
            $stmt = $pdo->prepare('SELECT business_line_id FROM leads WHERE id = :id');
            $stmt->execute(['id' => $relatedLeadId]);
            $value = $stmt->fetchColumn();

            return $value !== false ? (int) $value : null;
        }

        if ($relatedCustomerId !== null) {
            $stmt = $pdo->prepare('SELECT business_line_id FROM customers WHERE id = :id');
            $stmt->execute(['id' => $relatedCustomerId]);
            $value = $stmt->fetchColumn();

            return $value !== false ? (int) $value : null;
        }

        return null;
    }
}
