<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Facades\Storage;
use Laravel\Scout\Searchable;

class Document extends Model
{
    use HasFactory, Searchable;
    /**
     * 可批量赋值的属性
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'title',
        'file_path',
        'file_name',
        'file_size',
        'mime_type',
        'type',
        'group_id',
        'uploaded_by',
        'description',
        'markdown_path',
        'markdown_preview',
        'conversion_status',
        'conversion_error',
    ];

    /**
     * 获取文档所属的分组
     */
    public function group(): BelongsTo
    {
        return $this->belongsTo(Group::class);
    }

    /**
     * 获取文档的上传者
     */
    public function uploader(): BelongsTo
    {
        return $this->belongsTo(User::class, 'uploaded_by');
    }

    /**
     * 获取文档的所有下载日志
     */
    public function downloadLogs(): HasMany
    {
        return $this->hasMany(DownloadLog::class);
    }

    /**
     * 查询作用域：获取用户可访问的文档
     * 包含全局文档和用户分组的专用文档，排除其他分组的专用文档
     *
     * @param Builder $query
     * @param User $user
     * @return Builder
     */
    public function scopeAccessibleBy(Builder $query, User $user): Builder
    {
        // 获取用户所属的所有分组 ID
        $userGroupIds = $user->groups()->pluck('groups.id')->toArray();

        return $query->where(function (Builder $query) use ($userGroupIds) {
            // 包含所有全局文档
            $query->where('type', 'global')
                // 或者包含用户所属分组的专用文档
                ->orWhere(function (Builder $query) use ($userGroupIds) {
                    $query->where('type', 'dedicated')
                        ->whereIn('group_id', $userGroupIds);
                });
        });
    }

    /**
     * 查询作用域：仅获取全局文档
     *
     * @param Builder $query
     * @return Builder
     */
    public function scopeGlobal(Builder $query): Builder
    {
        return $query->where('type', 'global');
    }

    /**
     * 查询作用域：仅获取专用文档
     *
     * @param Builder $query
     * @return Builder
     */
    public function scopeDedicated(Builder $query): Builder
    {
        return $query->where('type', 'dedicated');
    }

    /**
     * 获取可搜索的数组数据
     * 用于 Meilisearch 索引
     *
     * @return array
     */
    public function toSearchableArray(): array
    {
        return [
            'id' => $this->id,
            'title' => $this->title,
            'file_name' => $this->file_name,
            'description' => $this->description,
            'markdown_content' => $this->getMarkdownContent(),
            'type' => $this->type,
            'group_id' => $this->group_id,
            'uploaded_by' => $this->uploaded_by,
            'created_at' => $this->created_at?->timestamp,
        ];
    }

    /**
     * 判断文档是否应该被索引
     * 只有转换完成的文档才会被索引
     *
     * @return bool
     */
    public function shouldBeSearchable(): bool
    {
        return $this->conversion_status === 'completed';
    }

    /**
     * 获取完整的 Markdown 内容
     * 从文件系统读取 Markdown 文件
     *
     * @return string|null
     */
    public function getMarkdownContent(): ?string
    {
        if (!$this->markdown_path) {
            return null;
        }

        try {
            if (Storage::disk('markdown')->exists($this->markdown_path)) {
                return Storage::disk('markdown')->get($this->markdown_path);
            }
        } catch (\Exception $e) {
            // 记录错误但不抛出异常
            \Log::warning('Failed to read markdown content', [
                'document_id' => $this->id,
                'markdown_path' => $this->markdown_path,
                'error' => $e->getMessage()
            ]);
        }

        return null;
    }

    /**
     * 检查文档是否已转换为 Markdown
     *
     * @return bool
     */
    public function hasMarkdown(): bool
    {
        return !empty($this->markdown_path) && $this->conversion_status === 'completed';
    }
}
