<?php

namespace App\Services\Customer;

use App\Models\Customer\Customer;

/**
 * Bir müşteriye fatura kesilirken kullanılabilecek muhatap seçeneklerini üretir.
 *
 * Mimarideki kural: kişi–şirket ilişkisi çoğuldur (company_customer pivotu).
 * Bir kişi birden fazla şirkete bağlı olabilir; bu durumda faturanın hangi
 * şirkete kesileceği seçilebilmelidir. Eskiden fatura bilgisi yalnızca
 * müşterinin KENDİ kolonlarından okunuyordu; bağlı şirketin vergi bilgisi
 * ancak form üzerinden kişinin kartına kopyalandıysa kullanılabiliyordu.
 *
 * Artık tek doğruluk kaynağı burasıdır:
 *   - Şahıs profili her zaman vardır (T.C. kimlik numarasına kesilir).
 *   - Kurumsal profil, müşterinin kendi şirket bilgisinden (corporate kart)
 *     ya da bağlı olduğu şirket kartlarından üretilir.
 *   - Vergi numarası olmayan şirket profili üretilmez; bilgi eksikse
 *     fatura şahsa (TC) kesilir.
 */
class CustomerBillingService
{
    /**
     * Müşteri için tüm fatura muhatabı seçenekleri.
     *
     * @return array<int, array{
     *     key: string, type: string, label: string, sub: ?string,
     *     company_id: ?int, complete: bool, billing: array
     * }>
     */
    public function profiles(Customer $customer): array
    {
        $profiles = [];

        // 1) Müşterinin kendisi bir şirket kartıysa
        if ($customer->customer_type === 'corporate') {
            $own = $this->companyProfileFrom($customer, $customer);
            if ($own) {
                $profiles[] = $own;
            }
        }

        // 2) Bağlı olduğu şirket kartları (kişi birden fazla şirkette olabilir).
        //    Birincil işaretli şirket başa alınır: varsayılan fatura unvanı odur.
        $companies = ($customer->relationLoaded('companies')
            ? $customer->companies
            : $customer->companies()->get())
            ->sortByDesc(fn ($c) => (int) ($c->pivot->is_primary ?? 0))
            ->values();

        foreach ($companies as $company) {
            $profile = $this->companyProfileFrom($company, $customer);
            if ($profile) {
                $profile['is_primary'] = (bool) ($company->pivot->is_primary ?? false);
                $profiles[] = $profile;
            }
        }

        // 3) Şahıs profili — yalnızca kişi kartlarında anlamlıdır.
        //    Şirket kaydının şahsı yoktur; TC seçeneği gösterilmez.
        if ($customer->customer_type !== 'corporate') {
            $profiles[] = $this->individualProfile($customer);
        }

        return $profiles;
    }

    /**
     * Varsayılan seçenek: eksiksiz bir kurumsal profil varsa o, yoksa şahıs.
     * (Kullanıcı isteği: "fatura bilgilerini girmemişse direkt TC'sine kessin".)
     */
    public function suggested(Customer $customer): array
    {
        $profiles = $this->profiles($customer);

        foreach ($profiles as $profile) {
            if ($profile['type'] === 'company' && $profile['complete']) {
                return $profile;
            }
        }

        // Şirket kartında şahıs profili yoktur; eksik de olsa kurumsal profil döner
        return collect($profiles)->firstWhere('type', 'individual')
            ?? ($profiles[0] ?? $this->individualProfile($customer));
    }

    public function suggestedType(Customer $customer): string
    {
        return $this->suggested($customer)['type'];
    }

    /** Müşteri kurumsal sayılır mı? (kendi şirket kartı ya da bağlı şirketi var) */
    public function isCorporate(Customer $customer): bool
    {
        if ($customer->customer_type === 'corporate') {
            return true;
        }

        return $customer->relationLoaded('companies')
            ? $customer->companies->isNotEmpty()
            : $customer->companies()->exists();
    }

    /**
     * Şirket kartından fatura profili.
     *
     * @param  Customer  $company   Bilgisi kullanılacak şirket kartı
     * @param  Customer  $customer  Faturanın kesildiği müşteri (ilgili kişi)
     */
    private function companyProfileFrom(Customer $company, Customer $customer): ?array
    {
        $taxNumber = $company->billing_tax_number ?: $company->company_tax_number;
        $title = $company->company_name ?: $company->full_name;

        if (!$title) {
            return null;
        }

        $isOwnCard = $company->id === $customer->id;

        return [
            'key' => 'company:' . $company->id,
            'type' => 'company',
            'label' => $title,
            'sub' => $isOwnCard
                ? 'Şirket kartı'
                : 'Bağlı şirket' . ($customer->company_position ? ' · ' . $customer->company_position : ''),
            'company_id' => $company->id,
            // Vergi numarası yoksa resmi fatura kesilemez; seçenek görünür ama eksiktir
            'complete' => filled($taxNumber),
            'billing' => [
                'name' => $isOwnCard ? $company->full_name : trim($customer->first_name . ' ' . $customer->last_name),
                'company_name' => $title,
                'tax_number' => $taxNumber,
                'tax_office' => $company->billing_tax_office ?: $company->company_tax_office,
                'address' => $company->billing_address ?: $this->addressOf($company),
                'phone' => $company->phone ?: $customer->phone,
                'email' => $company->billing_email ?: $company->email,
            ],
        ];
    }

    /** Şahıs (T.C. kimlik numarası) profili. */
    private function individualProfile(Customer $customer): array
    {
        $name = trim($customer->first_name . ' ' . $customer->last_name) ?: $customer->full_name;

        return [
            'key' => 'individual',
            'type' => 'individual',
            'label' => $name,
            'sub' => 'Şahıs faturası · T.C. kimlik numarasına',
            'company_id' => null,
            'complete' => filled($customer->national_id),
            'billing' => [
                'name' => $name,
                'company_name' => null,
                'tax_number' => $customer->national_id,
                'tax_office' => null,
                'address' => $customer->billing_address ?: $this->addressOf($customer),
                'phone' => $customer->phone,
                'email' => $customer->billing_email ?: $customer->email,
            ],
        ];
    }

    private function addressOf(Customer $customer): string
    {
        return trim(implode(' ', array_filter([
            $customer->address, $customer->district, $customer->city,
        ])));
    }
}
