<?php

namespace Tests\Traits;

use Modules\PMCore\App\Enums\ProjectPriority;
use Modules\PMCore\App\Enums\ProjectStatus;
use Modules\PMCore\App\Enums\ProjectType;
use Modules\PMCore\App\Enums\TimesheetStatus;
use Modules\PMCore\App\Models\Project;
use Modules\PMCore\App\Models\ProjectMember;
use Modules\PMCore\App\Models\Timesheet;

/**
 * Helper trait for creating PMCore test entities.
 */
trait CreatesPMCoreEntities
{
    // ==========================================
    // Project Methods
    // ==========================================

    protected function createProject(array $attributes = []): Project
    {
        return Project::create(array_merge([
            'name' => 'Test Project '.uniqid(),
            'description' => 'Test project description',
            'status' => ProjectStatus::PLANNING,
            'type' => ProjectType::CLIENT,
            'priority' => ProjectPriority::MEDIUM,
            'start_date' => now(),
            'end_date' => now()->addMonths(3),
            'budget' => 50000.00,
            'actual_cost' => 0,
            'actual_revenue' => 0,
            'completion_percentage' => 0,
            'is_billable' => true,
            'hourly_rate' => 100.00,
            'is_archived' => false,
        ], $attributes));
    }

    protected function createProjectInProgress(array $attributes = []): Project
    {
        return $this->createProject(array_merge([
            'status' => ProjectStatus::IN_PROGRESS,
            'completion_percentage' => 25,
        ], $attributes));
    }

    protected function createCompletedProject(array $attributes = []): Project
    {
        return $this->createProject(array_merge([
            'status' => ProjectStatus::COMPLETED,
            'completion_percentage' => 100,
            'completed_at' => now(),
        ], $attributes));
    }

    protected function createOnHoldProject(array $attributes = []): Project
    {
        return $this->createProject(array_merge([
            'status' => ProjectStatus::ON_HOLD,
        ], $attributes));
    }

    protected function createOverdueProject(array $attributes = []): Project
    {
        return $this->createProject(array_merge([
            'status' => ProjectStatus::IN_PROGRESS,
            'start_date' => now()->subMonths(3),
            'end_date' => now()->subWeek(),
            'completion_percentage' => 50,
        ], $attributes));
    }

    protected function createOverBudgetProject(array $attributes = []): Project
    {
        return $this->createProject(array_merge([
            'status' => ProjectStatus::IN_PROGRESS,
            'budget' => 10000.00,
            'actual_cost' => 15000.00,
        ], $attributes));
    }

    protected function createArchivedProject(array $attributes = []): Project
    {
        return $this->createProject(array_merge([
            'is_archived' => true,
        ], $attributes));
    }

    // ==========================================
    // Project Member Methods
    // ==========================================

    protected function addProjectMember(Project $project, $userId, array $attributes = []): ProjectMember
    {
        return ProjectMember::create(array_merge([
            'project_id' => $project->id,
            'user_id' => $userId,
            'role' => 'developer',
            'allocation_percentage' => 100,
            'hourly_rate' => 75.00,
            'joined_at' => now(),
            'left_at' => null,
        ], $attributes));
    }

    // ==========================================
    // Timesheet Methods
    // ==========================================

    protected function createTimesheet(array $attributes = []): Timesheet
    {
        // user_id and project_id are required, should be passed in attributes
        return Timesheet::create(array_merge([
            'date' => now(),
            'hours' => 8.0,
            'description' => 'Test work done',
            'is_billable' => true,
            'billing_rate' => 100.00,
            'cost_rate' => 75.00,
            'cost_amount' => 0,
            'billable_amount' => 0,
            'status' => TimesheetStatus::DRAFT,
        ], $attributes));
    }

    protected function createDraftTimesheet(array $attributes = []): Timesheet
    {
        return $this->createTimesheet(array_merge([
            'status' => TimesheetStatus::DRAFT,
        ], $attributes));
    }

    protected function createSubmittedTimesheet(array $attributes = []): Timesheet
    {
        return $this->createTimesheet(array_merge([
            'status' => TimesheetStatus::SUBMITTED,
        ], $attributes));
    }

    protected function createApprovedTimesheet(array $attributes = []): Timesheet
    {
        return $this->createTimesheet(array_merge([
            'status' => TimesheetStatus::APPROVED,
            'approved_at' => now(),
        ], $attributes));
    }

    protected function createRejectedTimesheet(array $attributes = []): Timesheet
    {
        return $this->createTimesheet(array_merge([
            'status' => TimesheetStatus::REJECTED,
        ], $attributes));
    }

    protected function createBillableTimesheet(array $attributes = []): Timesheet
    {
        return $this->createTimesheet(array_merge([
            'is_billable' => true,
            'billing_rate' => 150.00,
        ], $attributes));
    }

    protected function createNonBillableTimesheet(array $attributes = []): Timesheet
    {
        return $this->createTimesheet(array_merge([
            'is_billable' => false,
            'billing_rate' => 0,
        ], $attributes));
    }
}
