<?php

namespace App\Trait;

use Illuminate\Database\Eloquent\Casts\Attribute;

trait HasAddress {

    /**
     * Returns the full address as a string using HTML line breaks (<br>).
     *
     * @return string
     */
    public function asHtml(): string {
        return $this->getFullAddress('<br>');
    }

    /**
     * Returns the full address as a string, using a custom separator.
     *
     * @param string $separator The string to use between address lines. Defaults to ', '.
     * @return string
     */
    public function getFullAddress(string $separator = ', '): string {
        return implode($separator, $this->getAddressLines($this->attributes));
    }

    /**
     * Retrieves the address lines as an array, filtering out any empty values.
     * @param array $attributes The model's attributes array (passed as $this->attributes).
     * @return array
     */
    protected function getAddressLines(array $attributes): array {
        // Collect all parts and filter out null/empty strings
        return array_filter([
            $attributes['line_1'] ?? null,
            $attributes['line_2'] ?? null,
            $attributes['line_3'] ?? null,
            $attributes['line_4'] ?? null,
            $attributes['line_5'] ?? null,
            $attributes['line_6'] ?? null,
            $attributes['postcode'] ?? null,
        ]);
    }

    /**
     * Returns the full address as a clean array of strings, without any separator.
     *
     * @return array
     */
    public function asArray(): array {
        return $this->getAddressLines($this->attributes);
    }

    protected function fullAddress(): Attribute {
        return Attribute::make(
            get: fn(mixed $value, array $attributes) => $this->addressAsString(),
        )->shouldCache();
    }

    /**
     * Returns the full address as a single string using a comma and space separator.
     *
     * @return string
     */
    public function asString(): string {
        return $this->getFullAddress(', ');
    }
}
