<?php

namespace App\Models\Boards;

use App\Models\Tenants\Tenant;
use App\Models\User;
use Illuminate\Database\Eloquent\Builder;
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|null $tenant_id
 * @property int $board_id
 * @property int $user_id
 * @property string $title
 * @property string|null $content
 * @property string $editor_type
 * @property string|null $ip_address
 * @property bool $is_notice
 * @property bool $is_secret
 * @property int $views
 * @property string $status
 */
class Post extends Model
{
    use SoftDeletes;

    protected $table = 'posts';

    protected $fillable = [
        'tenant_id',
        'board_id',
        'user_id',
        'title',
        'content',
        'editor_type',
        'ip_address',
        'is_notice',
        'is_secret',
        'views',
        'status',
        'created_by',
        'updated_by',
        'deleted_by',
    ];

    protected $casts = [
        'is_notice' => 'boolean',
        'is_secret' => 'boolean',
        'views' => 'integer',
    ];

    protected $attributes = [
        'is_notice' => false,
        'is_secret' => false,
        'views' => 0,
        'status' => 'published',
        'editor_type' => 'wysiwyg',
    ];

    // =========================================================================
    // Scopes
    // =========================================================================

    /**
     * 특정 게시판의 글
     */
    public function scopeOfBoard(Builder $query, int $boardId): Builder
    {
        return $query->where('board_id', $boardId);
    }

    /**
     * 공지사항만
     */
    public function scopeNotices(Builder $query): Builder
    {
        return $query->where('is_notice', true);
    }

    /**
     * 일반 글만 (공지 제외)
     */
    public function scopeRegular(Builder $query): Builder
    {
        return $query->where('is_notice', false);
    }

    /**
     * 게시된 글만
     */
    public function scopePublished(Builder $query): Builder
    {
        return $query->where('status', 'published');
    }

    /**
     * 비밀글이 아닌 것만
     */
    public function scopePublic(Builder $query): Builder
    {
        return $query->where('is_secret', false);
    }

    // =========================================================================
    // Relationships
    // =========================================================================

    public function board(): BelongsTo
    {
        return $this->belongsTo(Board::class, 'board_id');
    }

    public function tenant(): BelongsTo
    {
        return $this->belongsTo(Tenant::class, 'tenant_id');
    }

    public function author(): BelongsTo
    {
        return $this->belongsTo(User::class, 'user_id');
    }

    public function creator(): BelongsTo
    {
        return $this->belongsTo(User::class, 'created_by');
    }

    public function customFieldValues(): HasMany
    {
        return $this->hasMany(PostCustomFieldValue::class, 'post_id');
    }

    /**
     * 첨부파일 (document_id + document_type 기반)
     */
    public function files(): HasMany
    {
        return $this->hasMany(File::class, 'document_id')
            ->where('document_type', 'post');
    }

    /**
     * 댓글 (활성 상태만)
     */
    public function comments(): HasMany
    {
        return $this->hasMany(BoardComment::class, 'post_id')
            ->where('status', 'active');
    }

    /**
     * 모든 댓글 (상태 무관)
     */
    public function allComments(): HasMany
    {
        return $this->hasMany(BoardComment::class, 'post_id');
    }

    // =========================================================================
    // Helper Methods
    // =========================================================================

    /**
     * 조회수 증가
     */
    public function incrementViews(): void
    {
        $this->increment('views');
    }

    /**
     * 커스텀 필드 값 가져오기
     */
    public function getCustomFieldValue(string $fieldKey): ?string
    {
        $fieldValue = $this->customFieldValues()
            ->whereHas('field', fn ($q) => $q->where('field_key', $fieldKey))
            ->first();

        return $fieldValue?->value;
    }

    /**
     * 커스텀 필드 값들을 배열로 가져오기
     */
    public function getCustomFieldsArray(): array
    {
        return $this->customFieldValues()
            ->with('field')
            ->get()
            ->mapWithKeys(fn ($v) => [$v->field->field_key => $v->value])
            ->toArray();
    }

    /**
     * 비밀글 접근 가능 여부
     */
    public function canAccess(?User $user): bool
    {
        // 비밀글이 아니면 모두 접근 가능
        if (! $this->is_secret) {
            return true;
        }

        // 비로그인이면 접근 불가
        if (! $user) {
            return false;
        }

        // 작성자 본인이면 접근 가능
        if ($this->user_id === $user->id) {
            return true;
        }

        // 관리자면 접근 가능
        if ($user->hasRole(['admin', 'super-admin'])) {
            return true;
        }

        return false;
    }

    /**
     * 안전한 HTML 콘텐츠 반환 (XSS 방지)
     * - 허용된 태그만 남기고 나머지 제거
     * - 위험한 속성 (onclick, onerror 등) 제거
     */
    public function getSafeHtmlContent(): string
    {
        $content = $this->content ?? '';

        // 허용할 HTML 태그
        $allowedTags = '<p><br><strong><b><em><i><u><s><del><h1><h2><h3><h4><h5><h6>'
            .'<ul><ol><li><blockquote><pre><code><a><img><span><div><table><thead><tbody><tr><th><td>';

        // 허용된 태그만 남기기
        $content = strip_tags($content, $allowedTags);

        // 위험한 이벤트 핸들러 속성 제거 (onclick, onerror, onload 등)
        $content = preg_replace('/\s*on\w+\s*=\s*["\'][^"\']*["\']/i', '', $content);
        $content = preg_replace('/\s*on\w+\s*=\s*[^\s>]*/i', '', $content);

        // javascript: 프로토콜 제거
        $content = preg_replace('/href\s*=\s*["\']javascript:[^"\']*["\']/i', 'href="#"', $content);

        return $content;
    }
}
