<?php

namespace FluentCart\App\Models;

use FluentCart\App\Helpers\AddressHelper;
use FluentCart\App\Services\Localization\LocalizationManager;
use FluentCart\Framework\Support\Collection;
use FluentCart\Framework\Support\Arr;

/**
 *  OrderItem Model - DB Model for Order Items
 *
 *  Database Model
 *
 * @package FluentCart\App\Models
 *
 * @version 1.0.0
 */
class OrderAddress extends Model
{
    protected $table = 'fct_order_addresses';

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'id',
        'order_id',
        'type',
        'name',
        'address_1',
        'address_2',
        'city',
        'state',
        'postcode',
        'country',
        'meta',
    ];
    protected $appends = [
        'email',
        'first_name',
        'last_name',
        'full_name',
        'formatted_address',
        'company_name',
        'vat_number',
        'legal_registration_id',
        'phone',
        'label'
    ];

    public function setMetaAttribute($value)
    {
        if ($value) {
            $decoded = \json_encode($value, true);
            if (!($decoded)) {
                $decoded = '[]';
            }
        } else {
            $decoded = '[]';
        }

        $this->attributes['meta'] = $decoded;
    }

    public function getMetaAttribute($value)
    {
        if (!$value) {
            return [];
        }

        return \json_decode($value, true);
    }

    public function getFullNameAttribute(): ?string
    {
        return $this->name;
    }

    public function getFirstNameAttribute(): ?string
    {
        return explode(" ", $this->name ?? '')[0];
    }

    public function getLastNameAttribute(): ?string
    {
        $nameParts = explode(" ", $this->name ?? '');
        return end($nameParts);
    }

    public function order(): \FluentCart\Framework\Database\Orm\Relations\BelongsTo
    {
        return $this->belongsTo(Order::class, 'order_id', 'id');
    }

    public function getEmailAttribute(): ?string
    {
        $order = $this->order;
        if ($order && $order->customer) {
            return $order->customer->email ?? null;
        }
        return null;
    }

    public function getFormattedAddressAttribute(): array
    {
        return $this->getFormattedAddress();
    }

    public function getFormattedAddress($filtered = false): array
    {
        $address = [
            'country' => AddressHelper::getCountryNameByCode($this->country),
            'state' => AddressHelper::getStateNameByCode($this->state, $this->country),
            'city' => $this->city,
            'postcode' => $this->postcode,
            'address_1' => $this->address_1,
            'address_2' => $this->address_2,
            'type' => $this->type,
            'name' => $this->name,
            'first_name' => $this->first_name,
            'last_name' => $this->last_name,
            'full_name' => $this->full_name,
            'email' => $this->email,
            'company_name' => $this->company_name,
            'label' => $this->label
        ];

        if ($filtered) {
            $address = array_filter($address);
        }

        $addressParts = [
            trim(Arr::get($address, 'address_1') ?? ''),
            trim(Arr::get($address, 'address_2') ?? ''),
            trim(Arr::get($address, 'city') ?? ''),
            trim(Arr::get($address, 'state') ?? ''),
            trim(Arr::get($address, 'country') ?? ''),
        ];

        $addressParts = array_filter($addressParts, function ($part) {
            return $part !== '';
        });
        $address['full_address'] = implode(', ', $addressParts);


        return $address;
    }


    public function getAddressAsText($isHtml = false, $includeName = true, $separator = ', '): string
    {
        $address = $this->formatted_address;

        $formatted = array_filter([
            $includeName ? $address['name'] : '',
            $address['address_1'],
            $address['address_2'],
            $address['city'],
            $address['state'],
            $address['postcode'],
            $address['country']
        ]);

        return implode($separator, $formatted);
    }

    public function getFormattedDataForCheckout($prefix = 'billing_')
    {
        $data = [
            '' . $prefix . 'address_id' => $this->id,
            '' . $prefix . 'full_name' => $this->name,
            '' . $prefix . 'address_1' => $this->address_1,
            '' . $prefix . 'address_2' => $this->address_2,
            '' . $prefix . 'city' => $this->city,
            '' . $prefix . 'state' => $this->state,
            '' . $prefix . 'phone' => $this->phone,
            '' . $prefix . 'postcode' => $this->postcode,
            '' . $prefix . 'country' => $this->country,
            '' . $prefix . 'company_name'          => $this->company_name,
            '' . $prefix . 'vat_number'            => $this->vat_number,
            '' . $prefix . 'legal_registration_id' => $this->legal_registration_id,
        ];

        if ($prefix === 'billing_') {
            unset($data['billing_full_name']);
        }

        return $data;
    }

    public function setCompanyNameAttribute($value)
    {
        if (!$value) {
            return;
        }

        $meta = $this->meta;

        if (!is_array($meta)) {
            $meta = [];
        }

        Arr::set($meta, 'other_data.company_name', $value);

        $this->attributes['meta'] = json_encode($meta);
    }

    public function getCompanyNameAttribute()
    {
        return Arr::get($this->meta, 'other_data.company_name', '');
    }

    public function setVatNumberAttribute($value)
    {
        $meta = is_array($this->meta) ? $this->meta : [];

        if ($value) {
            Arr::set($meta, 'other_data.vat_number', $value);
        } else {
            unset($meta['other_data']['vat_number']);
        }

        $this->attributes['meta'] = json_encode($meta);
    }

    public function getVatNumberAttribute()
    {
        return Arr::get($this->meta, 'other_data.vat_number', '');
    }

    public function setLegalRegistrationIdAttribute($value)
    {
        $meta = is_array($this->meta) ? $this->meta : [];

        if ($value) {
            Arr::set($meta, 'other_data.legal_registration_id', $value);
        } else {
            unset($meta['other_data']['legal_registration_id']);
        }

        $this->attributes['meta'] = json_encode($meta);
    }

    public function getLegalRegistrationIdAttribute()
    {
        return Arr::get($this->meta, 'other_data.legal_registration_id', '');
    }

    public function setLabelAttribute($value)
    {
        if (!$value) {
            return;
        }

        $meta = $this->meta;

        if (!is_array($meta)) {
            $meta = [];
        }

        Arr::set($meta, 'other_data.label', $value);

        $this->attributes['meta'] = json_encode($meta);
    }

    public function getLabelAttribute()
    {
        return Arr::get($this->meta, 'other_data.label', '');
    }

    public function setPhoneAttribute($value)
    {
        if (!$value) {
            return;
        }

        $meta = $this->meta;

        if (!is_array($meta)) {
            $meta = [];
        }

        Arr::set($meta, 'other_data.phone', $value);

        $this->attributes['meta'] = json_encode($meta);
    }

    public function getPhoneAttribute()
    {
        return Arr::get($this->meta, 'other_data.phone', '');
    }

}
