<?php

namespace App\Livewire;

use App\Models\File;
use App\Models\Stage;
use App\Models\FileStage;
use Livewire\Component;
use Illuminate\Support\Facades\Auth;

class FileStageAssignmentController extends Component
{
    public $assignments;
    public $files;
    public $stages;
    
    // Form properties
    public $file_id = '';
    public $stage_id = '';
    public $comment = '';
    public $active = true;
    
    // Edit mode properties
    public $editMode = false;
    public $assignmentId;
    public $selectedAssignment;
    
    // Filters
    public $filterFileId = '';
    public $filterStageId = '';
    public $filterActive = '';

    protected function rules()
    {
        return [
            'file_id' => ['required', 'exists:files,id'],
            'stage_id' => ['required', 'exists:stages,id'],
            'comment' => ['nullable', 'string', 'max:500'],
            'active' => ['boolean'],
        ];
    }

    protected function messages()
    {
        return [
            'file_id.required' => 'Please select a file.',
            'file_id.exists' => 'The selected file is invalid.',
            'stage_id.required' => 'Please select a stage.',
            'stage_id.exists' => 'The selected stage is invalid.',
            'comment.max' => 'Comment cannot exceed 500 characters.',
        ];
    }

    public function mount()
    {
        $this->loadAssignments();
        $this->loadFiles();
        $this->loadStages();
    }

    public function loadAssignments()
    {
        $query = FileStage::with(['file', 'stage', 'createdBy', 'updatedBy']);
        
        if ($this->filterFileId) {
            $query->where('file_id', $this->filterFileId);
        }
        
        if ($this->filterStageId) {
            $query->where('stage_id', $this->filterStageId);
        }
        
        if ($this->filterActive !== '') {
            $query->where('active', $this->filterActive);
        }
        
        $this->assignments = $query->orderBy('created_at', 'desc')->get();
    }

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

    public function loadStages()
    {
        $this->stages = Stage::orderBy('name')->get();
    }

    public function resetForm()
    {
        $this->reset(['file_id', 'stage_id', 'comment', 'active', 'editMode', 'assignmentId']);
        $this->active = true;
    }

    public function resetFilters()
    {
        $this->reset(['filterFileId', 'filterStageId', 'filterActive']);
        $this->loadAssignments();
    }

    public function view($id)
    {
        $this->selectedAssignment = FileStage::with(['file', 'stage', 'createdBy', 'updatedBy'])
            ->findOrFail($id);
    }

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

        // Check if this file already has an active assignment to this stage
        $existingActive = FileStage::where('file_id', $this->file_id)
            ->where('stage_id', $this->stage_id)
            ->where('active', true)
            ->first();

        if ($existingActive) {
            $this->dispatch('showError', 'This file is already assigned to this stage and is active.');
            return;
        }

        $assignment = new FileStage();
        $assignment->file_id = $this->file_id;
        $assignment->stage_id = $this->stage_id;
        $assignment->comment = $this->comment;
        $assignment->active = $this->active;
        $assignment->created_by = Auth::id();
        $assignment->updated_by = Auth::id();
        $assignment->save();

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

        $this->dispatch('closeModal');
        $this->dispatch('refreshTable');
        $this->dispatch('showSuccess', 'File stage assignment created successfully!');
    }

    public function edit($id)
    {
        $assignment = FileStage::findOrFail($id);
        
        $this->assignmentId = $assignment->id;
        $this->file_id = $assignment->file_id;
        $this->stage_id = $assignment->stage_id;
        $this->comment = $assignment->comment;
        $this->active = $assignment->active;
        $this->editMode = true;
    }

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

        $assignment = FileStage::findOrFail($this->assignmentId);
        
        // Check if this update would create a duplicate active assignment
        if ($this->active) {
            $existingActive = FileStage::where('file_id', $this->file_id)
                ->where('stage_id', $this->stage_id)
                ->where('active', true)
                ->where('id', '!=', $assignment->id)
                ->first();

            if ($existingActive) {
                $this->dispatch('showError', 'This file is already assigned to this stage and is active.');
                return;
            }
        }

        $assignment->file_id = $this->file_id;
        $assignment->stage_id = $this->stage_id;
        $assignment->comment = $this->comment;
        $assignment->active = $this->active;
        $assignment->updated_by = Auth::id();
        $assignment->save();

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

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

    public function delete($id)
    {
        $assignment = FileStage::findOrFail($id);
        $file = $assignment->file->name ?? 'Unknown file';
        $stage = $assignment->stage->name ?? 'Unknown stage';
        $assignment->delete();

        $this->loadAssignments();
        
        $this->dispatch('refreshTable');
        $this->dispatch('showSuccess', "Assignment removed: {$file} - {$stage}");
    }

    public function toggleActive($id)
    {
        $assignment = FileStage::findOrFail($id);
        
        // If trying to activate, check for conflicts
        if (!$assignment->active) {
            $existingActive = FileStage::where('file_id', $assignment->file_id)
                ->where('stage_id', $assignment->stage_id)
                ->where('active', true)
                ->where('id', '!=', $assignment->id)
                ->first();

            if ($existingActive) {
                $this->dispatch('showError', 'This file already has an active assignment to this stage.');
                return;
            }
        }

        $assignment->active = !$assignment->active;
        $assignment->updated_by = Auth::id();
        $assignment->save();

        $this->loadAssignments();
        $this->dispatch('showSuccess', 'Assignment status updated!');
    }

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