<?php

namespace App\Observers;

use App\Models\Document;
use App\Services\DocumentSearchService;

/**
 * 文档观察者
 * 监听文档模型事件，自动管理 Meilisearch 索引
 */
class DocumentObserver
{
    protected DocumentSearchService $searchService;

    public function __construct(DocumentSearchService $searchService)
    {
        $this->searchService = $searchService;
    }

    /**
     * 处理文档 "created" 事件
     * 注意：文档创建时不立即索引，等待转换完成后再索引
     */
    public function created(Document $document): void
    {
        // 文档创建时不立即索引，因为 Markdown 内容还未生成
        // 索引将在转换完成后通过 updated 事件触发
    }

    /**
     * 处理文档 "updated" 事件
     * 当文档更新时，检查转换状态并更新索引
     */
    public function updated(Document $document): void
    {
        // 检查转换状态是否变为 completed
        if ($document->wasChanged('conversion_status') && $document->conversion_status === 'completed') {
            // 转换完成，创建或更新索引
            $this->searchService->indexDocument($document);
        } elseif ($document->wasChanged(['title', 'description', 'markdown_path', 'knowledge_base_id'])) {
            // 其他重要字段更新时，也更新索引
            $this->searchService->updateDocumentIndex($document);
        }
    }

    /**
     * 处理文档 "deleting" 事件
     * 在删除前清理相关文件
     */
    public function deleting(Document $document): void
    {
        $this->cleanupDocumentFiles($document);
    }

    /**
     * 处理文档 "deleted" 事件
     * 从 Meilisearch 中移除文档索引
     */
    public function deleted(Document $document): void
    {
        $this->searchService->removeDocumentFromIndex($document);
    }

    /**
     * 处理文档 "restored" 事件
     * 恢复文档时重新索引
     */
    public function restored(Document $document): void
    {
        if ($document->shouldBeSearchable()) {
            $this->searchService->indexDocument($document);
        }
    }

    /**
     * 处理文档 "force deleting" 事件
     * 在强制删除前清理相关文件
     */
    public function forceDeleting(Document $document): void
    {
        $this->cleanupDocumentFiles($document);
    }

    /**
     * 处理文档 "force deleted" 事件
     * 强制删除时也要移除索引
     */
    public function forceDeleted(Document $document): void
    {
        $this->searchService->removeDocumentFromIndex($document);
    }

    /**
     * 清理文档相关的所有文件
     * 包括原始文档文件、Markdown 文件和媒体文件
     *
     * @param Document $document
     * @return void
     */
    protected function cleanupDocumentFiles(Document $document): void
    {
        try {
            // 删除原始文档文件
            if ($document->file_path && \Storage::disk('local')->exists($document->file_path)) {
                \Storage::disk('local')->delete($document->file_path);
                \Log::info('已删除原始文档文件', [
                    'document_id' => $document->id,
                    'file_path' => $document->file_path,
                ]);
            }

            // 删除 Markdown 文件和整个文档目录（包括 media）
            if ($document->markdown_path) {
                // 获取文档目录（例如：2025/12/04/{uuid}）
                $documentDir = dirname($document->markdown_path);
                
                // 删除整个文档目录（包括 Markdown 文件和 media 目录）
                if (\Storage::disk('markdown')->exists($documentDir)) {
                    \Storage::disk('markdown')->deleteDirectory($documentDir);
                    \Log::info('已删除文档目录', [
                        'document_id' => $document->id,
                        'directory' => $documentDir,
                    ]);
                }
            }
        } catch (\Exception $e) {
            \Log::error('清理文档文件失败', [
                'document_id' => $document->id,
                'error' => $e->getMessage(),
            ]);
            // 不抛出异常，避免影响删除操作
        }
    }
}
