<?php

namespace App\Models\Barobill;

use App\Models\Tenants\Tenant;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;

/**
 * 홈택스 세금계산서 모델
 *
 * @property int $id
 * @property int $tenant_id
 * @property string $nts_confirm_num 국세청승인번호
 * @property string $invoice_type 매출/매입 (sales/purchase)
 * @property \Carbon\Carbon $write_date 작성일자
 * @property \Carbon\Carbon|null $issue_date 발급일자
 * @property \Carbon\Carbon|null $send_date 전송일자
 * @property string $invoicer_corp_num 공급자 사업자번호
 * @property string $invoicer_corp_name 공급자 상호
 * @property string|null $invoicer_ceo_name 공급자 대표자
 * @property string $invoicee_corp_num 공급받는자 사업자번호
 * @property string $invoicee_corp_name 공급받는자 상호
 * @property string|null $invoicee_ceo_name 공급받는자 대표자
 * @property int $supply_amount 공급가액
 * @property int $tax_amount 세액
 * @property int $total_amount 합계
 * @property int $tax_type 과세유형 (1:과세, 2:영세, 3:면세)
 * @property int $purpose_type 영수/청구 (1:영수, 2:청구)
 * @property int $issue_type 발급유형 (1:정발행, 2:역발행)
 * @property string|null $item_name 품목명
 * @property string|null $remark 비고
 * @property string|null $memo 내부 메모
 * @property string|null $category 분류 태그
 * @property bool $is_checked 확인 여부
 * @property \Carbon\Carbon|null $synced_at 마지막 동기화 시간
 */
class HometaxInvoice extends Model
{
    use SoftDeletes;

    protected $table = 'hometax_invoices';

    protected $fillable = [
        'tenant_id',
        'nts_confirm_num',
        'invoice_type',
        'write_date',
        'issue_date',
        'send_date',
        'invoicer_corp_num',
        'invoicer_corp_name',
        'invoicer_ceo_name',
        'invoicer_branch_num',
        'invoicer_address',
        'invoicer_biz_type',
        'invoicer_biz_class',
        'invoicer_email',
        'invoicer_email2',
        'invoicee_corp_num',
        'invoicee_corp_name',
        'invoicee_ceo_name',
        'invoicee_branch_num',
        'invoicee_address',
        'invoicee_biz_type',
        'invoicee_biz_class',
        'invoicee_email',
        'invoicee_email2',
        'supply_amount',
        'tax_amount',
        'total_amount',
        'tax_type',
        'purpose_type',
        'issue_type',
        'item_name',
        'remark',
        'memo',
        'category',
        'is_checked',
        'synced_at',
    ];

    protected $casts = [
        'tenant_id' => 'integer',
        'write_date' => 'date',
        'issue_date' => 'date',
        'send_date' => 'date',
        'supply_amount' => 'integer',
        'tax_amount' => 'integer',
        'total_amount' => 'integer',
        'tax_type' => 'integer',
        'purpose_type' => 'integer',
        'issue_type' => 'integer',
        'is_checked' => 'boolean',
        'synced_at' => 'datetime',
    ];

    // 과세유형 상수
    public const TAX_TYPE_TAXABLE = 1;      // 과세

    public const TAX_TYPE_ZERO_RATE = 2;    // 영세

    public const TAX_TYPE_EXEMPT = 3;       // 면세

    // 영수/청구 상수
    public const PURPOSE_TYPE_RECEIPT = 1;  // 영수

    public const PURPOSE_TYPE_CLAIM = 2;    // 청구

    // 발급유형 상수
    public const ISSUE_TYPE_NORMAL = 1;     // 정발행

    public const ISSUE_TYPE_REVERSE = 2;    // 역발행

    /**
     * 테넌트 관계
     */
    public function tenant(): BelongsTo
    {
        return $this->belongsTo(Tenant::class);
    }

    /**
     * 분개 관계
     */
    public function journals(): HasMany
    {
        return $this->hasMany(HometaxInvoiceJournal::class);
    }

    /**
     * 매출 스코프
     */
    public function scopeSales($query)
    {
        return $query->where('invoice_type', 'sales');
    }

    /**
     * 매입 스코프
     */
    public function scopePurchase($query)
    {
        return $query->where('invoice_type', 'purchase');
    }

    /**
     * 기간 스코프
     */
    public function scopePeriod($query, string $startDate, string $endDate, string $dateType = 'write')
    {
        $column = match ($dateType) {
            'issue' => 'issue_date',
            'send' => 'send_date',
            default => 'write_date',
        };

        return $query->whereBetween($column, [$startDate, $endDate]);
    }

    /**
     * 거래처 검색 스코프
     */
    public function scopeSearchCorp($query, string $keyword, string $invoiceType = 'sales')
    {
        if (empty($keyword)) {
            return $query;
        }

        // 매출이면 공급받는자, 매입이면 공급자 검색
        if ($invoiceType === 'sales') {
            return $query->where(function ($q) use ($keyword) {
                $q->where('invoicee_corp_name', 'like', "%{$keyword}%")
                    ->orWhere('invoicee_corp_num', 'like', "%{$keyword}%");
            });
        } else {
            return $query->where(function ($q) use ($keyword) {
                $q->where('invoicer_corp_name', 'like', "%{$keyword}%")
                    ->orWhere('invoicer_corp_num', 'like', "%{$keyword}%");
            });
        }
    }

    /**
     * 과세유형 라벨
     */
    public function getTaxTypeNameAttribute(): string
    {
        return match ($this->tax_type) {
            self::TAX_TYPE_TAXABLE => '과세',
            self::TAX_TYPE_ZERO_RATE => '영세',
            self::TAX_TYPE_EXEMPT => '면세',
            default => '-',
        };
    }

    /**
     * 영수/청구 라벨
     */
    public function getPurposeTypeNameAttribute(): string
    {
        return match ($this->purpose_type) {
            self::PURPOSE_TYPE_RECEIPT => '영수',
            self::PURPOSE_TYPE_CLAIM => '청구',
            default => '-',
        };
    }

    /**
     * 발급유형 라벨
     */
    public function getIssueTypeNameAttribute(): string
    {
        return match ($this->issue_type) {
            self::ISSUE_TYPE_NORMAL => '정발급',
            self::ISSUE_TYPE_REVERSE => '역발급',
            default => '-',
        };
    }

    /**
     * 포맷된 공급가액
     */
    public function getFormattedSupplyAmountAttribute(): string
    {
        return number_format($this->supply_amount);
    }

    /**
     * 포맷된 세액
     */
    public function getFormattedTaxAmountAttribute(): string
    {
        return number_format($this->tax_amount);
    }

    /**
     * 포맷된 합계
     */
    public function getFormattedTotalAmountAttribute(): string
    {
        return number_format($this->total_amount);
    }

    /**
     * API 응답 데이터를 모델 데이터로 변환
     */
    public static function fromApiData(array $apiData, int $tenantId, string $invoiceType): array
    {
        // 작성일자 파싱
        $writeDate = null;
        if (! empty($apiData['writeDate']) && strlen($apiData['writeDate']) >= 8) {
            $writeDate = substr($apiData['writeDate'], 0, 4).'-'.
                         substr($apiData['writeDate'], 4, 2).'-'.
                         substr($apiData['writeDate'], 6, 2);
        }

        // 발급일자 파싱
        $issueDate = null;
        if (! empty($apiData['issueDT']) && strlen($apiData['issueDT']) >= 8) {
            $issueDate = substr($apiData['issueDT'], 0, 4).'-'.
                         substr($apiData['issueDT'], 4, 2).'-'.
                         substr($apiData['issueDT'], 6, 2);
        }

        return [
            'tenant_id' => $tenantId,
            'nts_confirm_num' => $apiData['ntsConfirmNum'] ?? '',
            'invoice_type' => $invoiceType,
            'write_date' => $writeDate,
            'issue_date' => $issueDate,
            'invoicer_corp_num' => $apiData['invoicerCorpNum'] ?? '',
            'invoicer_corp_name' => $apiData['invoicerCorpName'] ?? '',
            'invoicer_ceo_name' => $apiData['invoicerCEOName'] ?? null,
            'invoicee_corp_num' => $apiData['invoiceeCorpNum'] ?? '',
            'invoicee_corp_name' => $apiData['invoiceeCorpName'] ?? '',
            'invoicee_ceo_name' => $apiData['invoiceeCEOName'] ?? null,
            'supply_amount' => (int) ($apiData['supplyAmount'] ?? 0),
            'tax_amount' => (int) ($apiData['taxAmount'] ?? 0),
            'total_amount' => (int) ($apiData['totalAmount'] ?? 0),
            'tax_type' => (int) ($apiData['taxType'] ?? 1),
            'purpose_type' => (int) ($apiData['purposeType'] ?? 1),
            'issue_type' => 1, // 기본값: 정발행
            'item_name' => $apiData['itemName'] ?? null,
            'remark' => $apiData['remark'] ?? null,
            'synced_at' => now(),
        ];
    }
}
