<?php

declare(strict_types=1);

namespace App\Domain\Email\Exceptions;

use App\Domain\Email\Models\EmailAccount;
use App\Domain\Sysapi\Contracts\SysapiResult;
use RuntimeException;
use Throwable;

/**
 * MailboxProvisioner servisinde sysapi köprü hatalarını sarmalar.
 *
 * AccountException ile aynı tasarım: orijinal SysapiResult ve hedef
 * model referansı tutulur, böylece üst katman (controller / job) hata
 * detaylarını audit'e veya kullanıcıya gönderebilir.
 */
class MailboxProvisioningException extends RuntimeException
{
    public function __construct(
        string $message,
        public readonly ?EmailAccount $account = null,
        public readonly ?SysapiResult $sysapiResult = null,
        public readonly ?string $operation = null,
        int $code = 0,
        ?Throwable $previous = null,
    ) {
        parent::__construct($message, $code, $previous);
    }

    public static function fromCreateFailure(EmailAccount $account, SysapiResult $result): self
    {
        return new self(
            message: "Mailbox oluşturulamadı ({$account->email}, exit: {$result->exitCode}): {$result->stderr}",
            account: $account,
            sysapiResult: $result,
            operation: 'create',
        );
    }

    public static function fromTerminateFailure(EmailAccount $account, SysapiResult $result): self
    {
        return new self(
            message: "Mailbox silinemedi ({$account->email}, exit: {$result->exitCode}): {$result->stderr}",
            account: $account,
            sysapiResult: $result,
            operation: 'terminate',
        );
    }

    public static function fromPasswordUpdateFailure(EmailAccount $account, SysapiResult $result): self
    {
        return new self(
            message: "Mailbox parolası güncellenemedi ({$account->email}, exit: {$result->exitCode}): {$result->stderr}",
            account: $account,
            sysapiResult: $result,
            operation: 'password',
        );
    }

    public static function fromQuotaUpdateFailure(EmailAccount $account, SysapiResult $result): self
    {
        return new self(
            message: "Mailbox kotası güncellenemedi ({$account->email}, exit: {$result->exitCode}): {$result->stderr}",
            account: $account,
            sysapiResult: $result,
            operation: 'quota',
        );
    }

    public static function fromDiskUsageFailure(EmailAccount $account, SysapiResult $result): self
    {
        return new self(
            message: "Mailbox disk kullanımı okunamadı ({$account->email}, exit: {$result->exitCode}): {$result->stderr}",
            account: $account,
            sysapiResult: $result,
            operation: 'disk-usage',
        );
    }

    public static function fromListFailure(?string $domain, SysapiResult $result): self
    {
        $scope = $domain ?? 'tüm domainler';

        return new self(
            message: "Mailbox listesi alınamadı ({$scope}, exit: {$result->exitCode}): {$result->stderr}",
            sysapiResult: $result,
            operation: 'list',
        );
    }
}
