<?php

namespace App\Models\Solicitor;

use App\Casts\EmailAddress;
use App\Casts\PhoneNumber;
use App\Interface\AddressOwner;
use App\Interface\DocumentOwner;
use App\Interface\HistoryOwner;
use App\Interface\NoteOwner;
use App\Models\Communication\SolicitorPhoneNumber;
use App\Models\User\User;
use App\Trait\HasAddresses;
use App\Trait\HasDocuments;
use App\Trait\HasHistory;
use App\Trait\HasNotes;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\HasMany;

class Solicitor extends Model implements AddressOwner, DocumentOwner, NoteOwner, HistoryOwner {

    protected $fillable = [
        'name',
        'domain',
        'email_address',
        'phone_number',
        'help_contact_first_name',
        'help_contact_last_name',
        'logo_path',
        'company_number',
        'sra_number',
        'signature',
        'signature_text',
        'esign_api_key',
        'esign_base_url',
    ];

    protected $casts = [
        'email_address' => EmailAddress::class,
        'phone_number' => PhoneNumber::class,
        'esign_api_key' => 'encrypted',
    ];

    use HasAddresses, HasNotes, HasDocuments, HasHistory, HasFactory;


    public function users() {
        return $this->hasMany(User::class);
    }

    public function phoneNumbers(): HasMany {
        return $this->hasMany(SolicitorPhoneNumber::class);
    }

    public function emailSenders() {
        return $this->hasMany(SolicitorEmailSender::class);
    }

    public function smsSenders() {
        return $this->hasMany(SolicitorSmsSender::class);
    }

    /**
     * Whether this solicitor has Fintrixor eSign credentials configured.
     */
    public function esignReady(): bool {
        return filled($this->esign_api_key);
    }

    /**
     * Return the preferred sending address for a given purpose (e.g. 'dsar', 'client').
     * Prefers an explicit default for that purpose, then any sender for that purpose,
     * then falls back to the general default, then any sender at all.
     */
    public function emailSenderFor(string $purpose): ?SolicitorEmailSender {
        return $this->emailSenders()->where('purpose', $purpose)->orderByDesc('is_default')->first()
            ?? $this->emailSenders()->where('purpose', 'general')->orderByDesc('is_default')->first()
            ?? $this->emailSenders()->orderByDesc('is_default')->first();
    }

    /**
     * The firm's primary active phone number as a display string, sourced from the
     * phone-numbers subsystem (replaces the deprecated phone_number column).
     * Collection-based so it reuses an eager-loaded `phoneNumbers` relation.
     */
    public function primaryPhoneNumber(): ?string
    {
        return $this->phoneNumbers
            ->firstWhere(fn (SolicitorPhoneNumber $p) => $p->is_active && $p->is_primary)
            ?->phone_number;
    }

    /**
     * The firm's default sending email address as a display string, sourced from the
     * email-senders subsystem (replaces the deprecated email_address column). Mirrors
     * {@see emailSenderFor()}'s general-purpose preference but over the loaded
     * relation, so it reuses an eager-loaded `emailSenders` relation.
     */
    public function defaultEmailAddress(): ?string
    {
        $senders = $this->emailSenders;

        $sender = $senders->where('purpose', 'general')->sortByDesc('is_default')->first()
            ?? $senders->sortByDesc('is_default')->first();

        return $sender?->email_address;
    }

    /**
     * Firm-wide signature (HTML).  Used as the fallback when a SolicitorEmailSender
     * has no signature of its own.  Returns null if neither is set.
     */
    public function signatureHtml(): ?string
    {
        return $this->signature ?: null;
    }

    /**
     * Firm-wide signature (plain text).  Falls back to a stripped form of the HTML
     * signature when no explicit text version has been authored.
     */
    public function signatureText(): ?string
    {
        if ($this->signature_text) {
            return $this->signature_text;
        }
        if (!$this->signature) {
            return null;
        }
        $html = preg_replace('/<br\s*\/?>/i', "\n", $this->signature);
        $html = preg_replace('/<\/p>/i', "\n\n", $html);
        return trim(strip_tags($html));
    }

    public function getDocumentStoragePath(): string {
        return "solicitors/" . $this->id . "/";
    }
}
