<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Http\Requests\StoreMailProfileRequest;
use App\Http\Requests\UpdateMailProfileRequest;
use App\Models\MailProfile;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;
use Symfony\Component\Mailer\Mailer as SymfonyMailer;
use Symfony\Component\Mailer\Transport;
use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Email;

class MailProfileController extends Controller
{
    use AuthorizesRequests;

    public function index(): Response
    {
        $this->authorize('viewAny', MailProfile::class);
        $profiles = MailProfile::query()
            ->orderBy('priority')
            ->orderBy('id')
            ->get([
                'id', 'name', 'active', 'auto_mailer', 'host', 'port', 'username', 'from_name', 'encryption', 'from_address', 'priority', 'signature', 'last_success_at', 'last_error_at', 'last_error_message', 'test_status', 'test_checked_at',
            ]);

        return Inertia::render('Admin/MailProfiles/Index', [
            'profiles' => $profiles,
        ]);
    }

    public function store(StoreMailProfileRequest $request)
    {
        $data = $request->validated();
        $profile = new MailProfile;
        foreach ($data as $key => $val) {
            if ($key === 'password') {
                $profile->password = $val; // triggers mutator to encrypt
            } else {
                $profile->{$key} = $val;
            }
        }
        $profile->save();

        return back()->with('success', 'Mail profile created');
    }

    public function update(UpdateMailProfileRequest $request, MailProfile $mailProfile)
    {
        $data = $request->validated();
        foreach ($data as $key => $val) {
            if ($key === 'password') {
                if ($val !== null && $val !== '') {
                    $mailProfile->password = $val;
                }
            } else {
                $mailProfile->{$key} = $val;
            }
        }
        $mailProfile->save();

        return back()->with('success', 'Mail profile updated');
    }

    public function toggle(Request $request, MailProfile $mailProfile)
    {
        $this->authorize('update', $mailProfile);
        $mailProfile->active = ! $mailProfile->active;
        $mailProfile->save();

        return back()->with('success', 'Status updated');
    }

    public function toggleAutoMailer(Request $request, MailProfile $mailProfile)
    {
        $this->authorize('update', $mailProfile);
        $mailProfile->auto_mailer = ! $mailProfile->auto_mailer;
        $mailProfile->save();

        return back()->with('success', 'Auto-mailer updated');
    }

    public function test(Request $request, MailProfile $mailProfile)
    {
        $this->authorize('test', $mailProfile);
        $mailProfile->forceFill([
            'test_status' => 'queued',
            'test_checked_at' => now(),
        ])->save();

        \App\Jobs\TestMailProfileConnection::dispatch($mailProfile->id);

        return back()->with('success', 'Test queued');
    }

    public function destroy(MailProfile $mailProfile)
    {
        $this->authorize('delete', $mailProfile);
        $mailProfile->delete();

        return back()->with('success', 'Mail profile deleted');
    }

    public function sendTest(Request $request, MailProfile $mailProfile)
    {
        $this->authorize('test', $mailProfile);

        $to = (string) ($request->input('to') ?: $mailProfile->from_address);
        if ($to === '' || ! filter_var($to, FILTER_VALIDATE_EMAIL)) {
            return back()->with('error', 'Missing or invalid target email address');
        }

        // Build DSN for Symfony Mailer transport based on profile
        $host = $mailProfile->host;
        $port = (int) ($mailProfile->port ?: 587);
        $encryption = $mailProfile->encryption ?: 'tls';
        $username = $mailProfile->username ?: '';
        $password = (string) ($mailProfile->decryptPassword() ?? '');

        // Map encryption to Symfony DSN
        $scheme = $encryption === 'ssl' ? 'smtps' : 'smtp';
        $query = '';
        if ($encryption === 'tls') {
            $query = '?encryption=tls';
        }
        $dsn = sprintf('%s://%s:%s@%s:%d%s', $scheme, rawurlencode($username), rawurlencode($password), $host, $port, $query);

        try {
            $transport = Transport::fromDsn($dsn);
            $mailer = new SymfonyMailer($transport);

            $fromAddr = $mailProfile->from_address ?: $username;
            $fromName = (string) ($mailProfile->from_name ?: (config('mail.from.name') ?? config('app.name') ?? ''));

            $html = '<p>This is a <strong>test email</strong> from profile <code>'.e($mailProfile->name).'</code> at '.e(now()->toDateTimeString()).'.</p>';
            $text = 'This is a test email from profile "'.$mailProfile->name.'" at '.now()->toDateTimeString().'.';

            // Build email
            $fromAddress = $fromName !== '' ? new Address($fromAddr, $fromName) : new Address($fromAddr);
            $email = (new Email)
                ->from($fromAddress)
                ->to($to)
                ->subject('Test email - '.$mailProfile->name)
                ->text($text)
                ->html($html);

            $mailer->send($email);

            $mailProfile->forceFill([
                'last_success_at' => now(),
                'last_error_at' => null,
                'last_error_message' => null,
            ])->save();

            return back()->with('success', 'Test email sent to '.$to);
        } catch (\Throwable $e) {
            $mailProfile->forceFill([
                'last_error_at' => now(),
                'last_error_message' => $e->getMessage(),
            ])->save();

            return back()->with('error', 'Failed to send test: '.$e->getMessage());
        }
    }
}
