<?php
// app/Livewire/FileAttachmentManager.php
namespace App\Livewire;

use App\Models\File;
use App\Models\FileAttachment;
use App\Models\NoticeUpdate;
use App\Models\AttachmentType;
use Livewire\Component;
use Livewire\WithFileUploads;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;

class FileAttachmentController extends Component
{
    use WithFileUploads;

    // Properties
    public $attachments;
    public $file_id;
    public $notice_update_id;
    public $file_name;
    public $doc_name;
    public $doc_type;
    public $doc_size;
    public $active = true;
    public $editMode = false;
    public $attachmentId;
    public $selectedFile;
    public $files; // For dropdown
    public $noticeUpdates; // For dropdown
    public $attachmentTypes; // For dropdown
    public $attachment_type_id; // Selected attachment type

    // Upload properties
    public $upload;

    protected function rules()
    {
        return [
            'file_id' => ['nullable', 'exists:files,id'],
            'notice_update_id' => ['nullable', 'exists:notice_updates,id'],
            'attachment_type_id' => ['nullable', 'exists:attachment_types,id'],
            'doc_name' => ['required', 'string', 'max:255'],
            'active' => ['boolean'],
            'upload' => ['nullable', 'file', 'max:10240'], // Max 10MB
        ];
    }

    protected function messages()
    {
        return [
            'file_id.exists' => 'Please select a valid file.',
            'notice_update_id.exists' => 'Please select a valid notice update.',
            'attachment_type_id.exists' => 'Please select a valid attachment type.',
            'doc_name.required' => 'Document name is required.',
            'doc_name.max' => 'Document name cannot exceed 255 characters.',
            'upload.max' => 'File size cannot exceed 10MB.',
        ];
    }

    public function mount($fileId = null, $noticeUpdateId = null)
    {
        $this->file_id = $fileId;
        $this->notice_update_id = $noticeUpdateId;
        $this->loadAttachments();
        $this->loadFiles();
        $this->loadNoticeUpdates();
        $this->loadAttachmentTypes();
        
        // Set default attachment type if exists
        $defaultType = AttachmentType::where('active', true)->first();
        if ($defaultType) {
            $this->attachment_type_id = $defaultType->id;
        }
    }

    public function loadAttachments()
    {
        $query = FileAttachment::with(['file', 'noticeUpdate', 'createdBy', 'updatedBy', 'attachmentType']);
        
        if ($this->file_id) {
            $query->where('file_id', $this->file_id);
        }
        
        if ($this->notice_update_id) {
            $query->where('notice_update_id', $this->notice_update_id);
        }
        
        $this->attachments = $query->orderBy('id', 'desc')->get();
    }

    public function loadFiles()
    {
        $this->files = File::orderBy('name')->get();
    }

    public function loadNoticeUpdates()
    {
        $this->noticeUpdates = NoticeUpdate::orderBy('id', 'desc')->get();
    }

    public function loadAttachmentTypes()
    {
        $this->attachmentTypes = AttachmentType::where('active', true)
            ->orderBy('name')
            ->get();
    }

    public function resetForm()
    {
        $this->reset([
            'attachmentId', 'doc_name', 'doc_type', 'doc_size', 
            'active', 'editMode', 'upload', 'attachment_type_id'
        ]);
        
        // Keep the file_id and notice_update_id if they were set in mount
        if (!$this->file_id) {
            $this->file_id = null;
        }
        if (!$this->notice_update_id) {
            $this->notice_update_id = null;
        }
        
        // Set default attachment type
        $defaultType = AttachmentType::where('active', true)->first();
        if ($defaultType) {
            $this->attachment_type_id = $defaultType->id;
        }
        
        $this->active = true;
    }

    public function view($id)
    {
        $this->selectedFile = FileAttachment::with(['file', 'noticeUpdate', 'createdBy', 'updatedBy', 'attachmentType'])
            ->findOrFail($id);
    }

    public function store()
    {
        $this->validate();

        // Handle file upload
        $filePath = null;
        $originalFileName = null;
        $fileSize = null;
        $fileType = null;

        if ($this->upload) {
            $originalFileName = $this->upload->getClientOriginalName();
            $fileSize = $this->upload->getSize();
            $fileType = $this->upload->getMimeType();
            
            // Store in a directory structure: attachments/files/YYYY/MM/
            $filePath = $this->upload->store('attachments/files/' . date('Y/m'), 'public');
        }

        $attachment = new FileAttachment();
        $attachment->file_id = $this->file_id;
        $attachment->notice_update_id = $this->notice_update_id;
        $attachment->attachment_type_id = $this->attachment_type_id;
        $attachment->doc_name = $this->doc_name;
        $attachment->file_name = $filePath;
        $attachment->doc_type = $fileType;
        $attachment->doc_size = $fileSize;
        $attachment->active = $this->active;
        $attachment->created_by = Auth::id();
        $attachment->updated_by = Auth::id();
        $attachment->save();

        $this->loadAttachments();
        $this->resetForm();

        $this->dispatch('closeModal');
        $this->dispatch('refreshTable');
        $this->dispatch('showSuccess', 'Attachment added successfully!');
    }

    public function edit($id)
    {
        $attachment = FileAttachment::findOrFail($id);
        
        $this->attachmentId = $attachment->id;
        $this->file_id = $attachment->file_id;
        $this->notice_update_id = $attachment->notice_update_id;
        $this->attachment_type_id = $attachment->attachment_type_id;
        $this->doc_name = $attachment->doc_name;
        $this->active = $attachment->active;
        $this->editMode = true;
        
        // Note: We don't set the upload field as it's a file input
    }

    public function update()
    {
        $this->validate([
            'file_id' => ['nullable', 'exists:files,id'],
            'notice_update_id' => ['nullable', 'exists:notice_updates,id'],
            'attachment_type_id' => ['nullable', 'exists:attachment_types,id'],
            'doc_name' => ['required', 'string', 'max:255'],
            'active' => ['boolean'],
        ]);

        $attachment = FileAttachment::findOrFail($this->attachmentId);
        
        // Handle new file upload if provided
        if ($this->upload) {
            // Delete old file
            if ($attachment->file_name) {
                Storage::disk('public')->delete($attachment->file_name);
            }
            
            $originalFileName = $this->upload->getClientOriginalName();
            $fileSize = $this->upload->getSize();
            $fileType = $this->upload->getMimeType();
            
            // Store new file
            $filePath = $this->upload->store('attachments/files/' . date('Y/m'), 'public');
            
            $attachment->file_name = $filePath;
            $attachment->doc_type = $fileType;
            $attachment->doc_size = $fileSize;
        }

        $attachment->file_id = $this->file_id;
        $attachment->notice_update_id = $this->notice_update_id;
        $attachment->attachment_type_id = $this->attachment_type_id;
        $attachment->doc_name = $this->doc_name;
        $attachment->active = $this->active;
        $attachment->updated_by = Auth::id();
        $attachment->save();
        
        $this->loadAttachments();
        $this->resetForm();

        $this->dispatch('closeModal');
        $this->dispatch('refreshTable');
        $this->dispatch('showSuccess', 'Attachment updated successfully!');
    }

    public function delete($id)
    {
        $attachment = FileAttachment::findOrFail($id);
        
        // Delete the physical file
        if ($attachment->file_name) {
            Storage::disk('public')->delete($attachment->file_name);
        }
        
        $attachment->delete();

        $this->loadAttachments();
        
        $this->dispatch('refreshTable');
        $this->dispatch('showSuccess', 'Attachment deleted successfully!');
    }

    public function download($id)
    {
        $attachment = FileAttachment::findOrFail($id);
        
        if (!$attachment->file_name || !Storage::disk('public')->exists($attachment->file_name)) {
            $this->dispatch('showError', 'File not found!');
            return;
        }
        
        return response()->download(
            storage_path('app/public/' . $attachment->file_name),
            $attachment->doc_name . '.' . pathinfo($attachment->file_name, PATHINFO_EXTENSION)
        );
    }

    public function render()
    {
        return view('livewire.file-attachment-controller');
    }
}