<?php

namespace App\Models\Tenants;

use App\Models\Members\User;
use App\Traits\BelongsToTenant;
use App\Traits\ModelTrait;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

/**
 * 오늘의 이슈 모델
 *
 * CEO 대시보드용 실시간 이슈 저장
 */
class TodayIssue extends Model
{
    use BelongsToTenant, HasFactory, ModelTrait;

    protected $table = 'today_issues';

    protected $fillable = [
        'tenant_id',
        'source_type',
        'source_id',
        'target_user_id',
        'badge',
        'notification_type',
        'content',
        'path',
        'needs_approval',
        'is_read',
        'read_by',
        'read_at',
        'expires_at',
    ];

    protected $casts = [
        'needs_approval' => 'boolean',
        'is_read' => 'boolean',
        'read_at' => 'datetime',
        'expires_at' => 'datetime',
    ];

    // 소스 타입 상수
    public const SOURCE_ORDER = 'order';

    public const SOURCE_BAD_DEBT = 'bad_debt';

    public const SOURCE_STOCK = 'stock';

    public const SOURCE_EXPENSE = 'expense';

    public const SOURCE_TAX = 'tax';

    public const SOURCE_APPROVAL = 'approval';

    public const SOURCE_CLIENT = 'client';

    public const SOURCE_DEPOSIT = 'deposit';

    public const SOURCE_WITHDRAWAL = 'withdrawal';

    // 뱃지 타입 상수 (최대 4자, 띄어쓰기 없음)
    public const BADGE_ORDER_REGISTER = '수주등록';

    public const BADGE_COLLECTION_ISSUE = '추심이슈';

    public const BADGE_SAFETY_STOCK = '안전재고';

    public const BADGE_EXPENSE_PENDING = '지출승인';

    public const BADGE_TAX_REPORT = '세금신고';

    public const BADGE_APPROVAL_REQUEST = '결재요청';

    public const BADGE_NEW_CLIENT = '신규업체';

    public const BADGE_DEPOSIT = '입금';

    public const BADGE_WITHDRAWAL = '출금';

    // 기안 상태 변경 알림 뱃지
    public const BADGE_DRAFT_APPROVED = '기안승인';

    public const BADGE_DRAFT_REJECTED = '기안반려';

    public const BADGE_DRAFT_COMPLETED = '기안완료';

    // source_type → badge 매핑
    public const SOURCE_TO_BADGE = [
        self::SOURCE_ORDER => self::BADGE_ORDER_REGISTER,
        self::SOURCE_BAD_DEBT => self::BADGE_COLLECTION_ISSUE,
        self::SOURCE_STOCK => self::BADGE_SAFETY_STOCK,
        self::SOURCE_EXPENSE => self::BADGE_EXPENSE_PENDING,
        self::SOURCE_TAX => self::BADGE_TAX_REPORT,
        self::SOURCE_APPROVAL => self::BADGE_APPROVAL_REQUEST,
        self::SOURCE_CLIENT => self::BADGE_NEW_CLIENT,
        self::SOURCE_DEPOSIT => self::BADGE_DEPOSIT,
        self::SOURCE_WITHDRAWAL => self::BADGE_WITHDRAWAL,
    ];

    // 뱃지 → notification_type 매핑
    public const BADGE_TO_NOTIFICATION_TYPE = [
        self::BADGE_ORDER_REGISTER => 'sales_order',
        self::BADGE_NEW_CLIENT => 'new_vendor',
        self::BADGE_APPROVAL_REQUEST => 'approval_request',
        self::BADGE_DRAFT_APPROVED => 'approval_request',
        self::BADGE_DRAFT_REJECTED => 'approval_request',
        self::BADGE_DRAFT_COMPLETED => 'approval_request',
        self::BADGE_COLLECTION_ISSUE => 'bad_debt',
        self::BADGE_SAFETY_STOCK => 'safety_stock',
        self::BADGE_EXPENSE_PENDING => 'expected_expense',
        self::BADGE_TAX_REPORT => 'vat_report',
        self::BADGE_DEPOSIT => 'deposit',
        self::BADGE_WITHDRAWAL => 'withdrawal',
    ];

    // 중요 알림 (긴급 푸시) - 수주등록, 신규거래처, 결재요청
    // 입금, 출금, 카드 등은 일반 푸시(push_default)로 발송
    public const IMPORTANT_NOTIFICATIONS = [
        'sales_order',
        'new_vendor',
        'approval_request',
    ];

    /**
     * 확인한 사용자
     */
    public function reader(): BelongsTo
    {
        return $this->belongsTo(User::class, 'read_by');
    }

    /**
     * 대상 사용자 (특정 사용자에게만 발송할 경우)
     */
    public function targetUser(): BelongsTo
    {
        return $this->belongsTo(User::class, 'target_user_id');
    }

    /**
     * 읽지 않은 이슈 스코프
     */
    public function scopeUnread($query)
    {
        return $query->where('is_read', false);
    }

    /**
     * 만료되지 않은 이슈 스코프
     */
    public function scopeActive($query)
    {
        return $query->where(function ($q) {
            $q->whereNull('expires_at')
                ->orWhere('expires_at', '>', now());
        });
    }

    /**
     * 오늘 날짜 이슈 스코프
     */
    public function scopeToday($query)
    {
        return $query->whereDate('created_at', today());
    }

    /**
     * 뱃지별 필터 스코프
     */
    public function scopeByBadge($query, string $badge)
    {
        return $query->where('badge', $badge);
    }

    /**
     * 소스별 필터 스코프
     */
    public function scopeBySource($query, string $sourceType, ?int $sourceId = null)
    {
        $query->where('source_type', $sourceType);

        if ($sourceId !== null) {
            $query->where('source_id', $sourceId);
        }

        return $query;
    }

    /**
     * 특정 사용자 대상 이슈 스코프
     * target_user_id가 null이거나 지정된 사용자인 경우
     */
    public function scopeForUser($query, int $userId)
    {
        return $query->where(function ($q) use ($userId) {
            $q->whereNull('target_user_id')
                ->orWhere('target_user_id', $userId);
        });
    }

    /**
     * 특정 사용자만 대상인 이슈 스코프
     */
    public function scopeTargetedTo($query, int $userId)
    {
        return $query->where('target_user_id', $userId);
    }

    /**
     * 이슈 확인 처리
     */
    public function markAsRead(int $userId): bool
    {
        return $this->update([
            'is_read' => true,
            'read_by' => $userId,
            'read_at' => now(),
        ]);
    }

    /**
     * 이슈 생성 헬퍼 (정적 메서드)
     *
     * @param  int  $tenantId  테넌트 ID
     * @param  string  $sourceType  소스 타입 (order, approval, etc.)
     * @param  int|null  $sourceId  소스 ID
     * @param  string  $badge  뱃지 타입
     * @param  string  $content  알림 내용
     * @param  string|null  $path  이동 경로
     * @param  bool  $needsApproval  승인 필요 여부
     * @param  \DateTime|null  $expiresAt  만료 시간
     * @param  int|null  $targetUserId  특정 대상 사용자 ID (null이면 테넌트 전체)
     */
    public static function createIssue(
        int $tenantId,
        string $sourceType,
        ?int $sourceId,
        string $badge,
        string $content,
        ?string $path = null,
        bool $needsApproval = false,
        ?\DateTime $expiresAt = null,
        ?int $targetUserId = null
    ): self {
        // badge에서 notification_type 자동 매핑
        $notificationType = self::BADGE_TO_NOTIFICATION_TYPE[$badge] ?? null;

        return self::updateOrCreate(
            [
                'tenant_id' => $tenantId,
                'source_type' => $sourceType,
                'source_id' => $sourceId,
                'target_user_id' => $targetUserId,
            ],
            [
                'badge' => $badge,
                'notification_type' => $notificationType,
                'content' => $content,
                'path' => $path,
                'needs_approval' => $needsApproval,
                'expires_at' => $expiresAt,
                'is_read' => false,
                'read_by' => null,
                'read_at' => null,
            ]
        );
    }

    /**
     * 중요 알림 여부 확인
     */
    public function isImportantNotification(): bool
    {
        return in_array($this->notification_type, self::IMPORTANT_NOTIFICATIONS, true);
    }

    /**
     * 소스 기준 이슈 삭제 헬퍼 (정적 메서드)
     */
    public static function removeBySource(int $tenantId, string $sourceType, int $sourceId): bool
    {
        return self::where('tenant_id', $tenantId)
            ->where('source_type', $sourceType)
            ->where('source_id', $sourceId)
            ->delete() > 0;
    }
}
