<?php

namespace App\Models;

use App\Support\PhoneNumber;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Carbon;

class Serenata extends Model
{
    protected $fillable = [
        'organization_id',
        'created_by_user_id',
        'customer_id',
        'mariachi_group_id',
        'serenata_package_id',
        'sequence',
        'code',
        'external_reference',
        'payer_name',
        'payer_email',
        'service_address',
        'address_additional',
        'service_country',
        'service_department',
        'neighborhood',
        'locality',
        'service_locality',
        'service_sector',
        'contact_phone_1',
        'contact_phone_2',
        'reason',
        'from_name',
        'to_name',
        'event_date',
        'event_time',
        'internal_notes',
        'client_notes',
        'service_private_note',
        'base_price',
        'gift_amount',
        'gift_items',
        'artist_amount',
        'artist_items',
        'other_cost_amount',
        'other_cost_items',
        'discount_amount',
        'base_cost',
        'total_charged',
        'actual_customer_charge',
        'actual_customer_charge_recorded_at',
        'actual_customer_charge_notes',
        'profit_amount',
        'commission_rate',
        'commission_amount',
        'payment_status',
        'service_status',
        'payment_method',
        'cancellation_reason',
        'ceded_amount',
        'is_ceded',
        'external_partner_id',
        'ceded_total_cost',
        'ceded_artist_amount',
        'ceded_gift_amount',
        'ceded_transport_amount',
        'ceded_other_cost_amount',
        'ceded_excess_amount',
        'ceded_excess_status',
        'ceded_settled_at',
        'ceded_notes',
        'ceded_cost_breakdown',
    ];

    protected $casts = [
        'organization_id' => 'integer',
        'created_by_user_id' => 'integer',
        'customer_id' => 'integer',
        'mariachi_group_id' => 'integer',
        'serenata_package_id' => 'integer',
        'sequence' => 'integer',
        'event_date' => 'date',
        'gift_items' => 'array',
        'artist_items' => 'array',
        'other_cost_items' => 'array',
        'base_price' => 'float',
        'gift_amount' => 'float',
        'artist_amount' => 'float',
        'other_cost_amount' => 'float',
        'discount_amount' => 'float',
        'base_cost' => 'float',
        'total_charged' => 'float',
        'actual_customer_charge' => 'float',
        'actual_customer_charge_recorded_at' => 'datetime',
        'profit_amount' => 'float',
        'commission_rate' => 'float',
        'commission_amount' => 'float',
        'ceded_amount' => 'float',
        'is_ceded' => 'boolean',
        'external_partner_id' => 'integer',
        'ceded_total_cost' => 'float',
        'ceded_artist_amount' => 'float',
        'ceded_gift_amount' => 'float',
        'ceded_transport_amount' => 'float',
        'ceded_other_cost_amount' => 'float',
        'ceded_excess_amount' => 'float',
        'ceded_settled_at' => 'datetime',
        'ceded_cost_breakdown' => 'array',
    ];

    public function customer()
    {
        return $this->belongsTo(Customer::class);
    }

    public function mariachiGroup()
    {
        return $this->belongsTo(MariachiGroup::class);
    }

    public function serenataPackage()
    {
        return $this->belongsTo(SerenataPackage::class);
    }

    public function statusHistories()
    {
        return $this->hasMany(SerenataStatusHistory::class);
    }

    public function payments()
    {
        return $this->hasMany(SerenataPayment::class);
    }

    public function externalPartner()
    {
        return $this->belongsTo(ExternalPartner::class);
    }

    public function externalPartnerMovements()
    {
        return $this->hasMany(ExternalPartnerMovement::class);
    }

    public function eventWindowStart(): ?Carbon
    {
        $time = trim((string) ($this->event_time ?? ''));
        if ($time === '') {
            return null;
        }

        try {
            return Carbon::createFromFormat('H:i', $time);
        } catch (\Throwable $e) {
            return null;
        }
    }

    public function eventWindowEnd(): ?Carbon
    {
        $start = $this->eventWindowStart();

        return $start ? $start->copy()->addHour() : null;
    }

    public function eventWindowLabel(): string
    {
        $start = $this->eventWindowStart();
        $end = $this->eventWindowEnd();

        if (! $start || ! $end) {
            return trim((string) ($this->event_time ?? ''));
        }

        return mb_strtoupper($start->format('h:i A').' - '.$end->format('h:i A'), 'UTF-8');
    }

    public function getFormattedContactPhone1Attribute(): string
    {
        return PhoneNumber::display($this->contact_phone_1);
    }

    public function getFormattedContactPhone2Attribute(): string
    {
        return PhoneNumber::display($this->contact_phone_2);
    }

    public function getContactPhone1WhatsappDigitsAttribute(): string
    {
        return PhoneNumber::whatsappDigits($this->contact_phone_1);
    }

    public function setContactPhone1Attribute($value): void
    {
        $this->attributes['contact_phone_1'] = PhoneNumber::normalize(is_scalar($value) ? (string) $value : '') ?: null;
    }

    public function setContactPhone2Attribute($value): void
    {
        $this->attributes['contact_phone_2'] = PhoneNumber::normalize(is_scalar($value) ? (string) $value : '') ?: null;
    }
}
