<?php

namespace App\Tools;

use App\Models\AttendanceManagement\AbsenteeismScheduleSchema;
use App\Models\AttendanceManagement\AttendanceNotification;
use App\Models\AttendanceManagement\AttendanceNotificationSchema;
use App\Models\AttendanceManagement\ShiftSchema;
use App\Models\AttendanceManagement\WorkingAttendanceSchedule;
use App\Models\AttendanceManagement\WorkingAttendanceScheduleSchema;
use App\Models\HelpDesk\HelpDesk;
use App\Models\HelpDesk\HelpDeskCategory;
use App\Models\HelpDesk\HelpDeskCategorySchema;
use App\Models\HelpDesk\HelpDeskSchema;
use App\Models\LeaveManagement\Leave;
use App\Models\LeaveManagement\LeaveSchema;
use App\Models\LeaveManagement\LeaveSchemaUnit;
use App\Models\LeaveManagement\LeaveType;
use App\Models\LeaveManagement\LeaveTypeSchema;
use App\Models\MessageBoard\AnnouncementCategory;
use App\Models\MessageBoard\AnnouncementCategorySchema;
use App\Models\MovementResources\StaffMovement;
use App\Models\MovementResources\StaffMovementSchema;
use App\Models\MovementResources\StaffMovementSchemaUnit;
use App\Models\MovementResources\VehicleMovement;
use App\Models\MovementResources\VehicleMovementSchema;
use App\Models\MovementResources\VehicleMovementSchemaUnit;
use App\Models\Offboarding\Offboarding;
use App\Models\Offboarding\OffboardingActivity;
use App\Models\Offboarding\OffboardingActivitySchema;
use App\Models\Offboarding\OffboardingSchema;
use App\Models\Onboarding\Onboarding;
use App\Models\Onboarding\OnboardingActivity;
use App\Models\Onboarding\OnboardingActivitySchema;
use App\Models\Onboarding\OnboardingSchema;
use App\Models\Performance\AppraisalCycle;
use App\Models\Performance\AppraisalCycleSchema;
use App\Models\Performance\Competency;
use App\Models\Performance\CompetencySchema;
use App\Models\Performance\Goal;
use App\Models\Performance\GoalSchema;
use App\Models\Performance\SkillSet;
use App\Models\Performance\SkillSetSchema;
use App\Models\Recruitment\Applicant;
use App\Models\Recruitment\ApplicantSchema;
use App\Models\Recruitment\InterviewProcess;
use App\Models\Recruitment\InterviewProcessSchema;
use App\Models\Recruitment\JobApplication;
use App\Models\Recruitment\JobApplicationSchema;
use App\Models\Recruitment\Vacancy;
use App\Models\Recruitment\VacancySchema;
use App\Models\Staff\BenefitsInfoSchema;
use App\Models\Staff\ContactInfoSchema;
use App\Models\Staff\EduBackgroundInfoSchema;
use App\Models\Staff\JobInfoSchema;
use App\Models\Staff\PayrollInfoSchema;
use App\Models\Staff\PersonalInfoSchema;
use App\Models\Staff\WorkExpInfoSchema;
use App\Models\StaffEngagement\FileManagement;
use App\Models\StaffEngagement\FileManagementSchema;
use App\Models\StaffEngagement\Folder;
use App\Models\StaffEngagement\FolderSchema;
use App\Models\StaffEngagement\Grievance;
use App\Models\StaffEngagement\GrievanceCategory;
use App\Models\StaffEngagement\GrievanceCategorySchema;
use App\Models\StaffEngagement\GrievanceReview;
use App\Models\StaffEngagement\GrievanceReviewSchema;
use App\Models\StaffEngagement\GrievanceSchema;
use App\Models\StaffEngagement\KpiActivity;
use App\Models\StaffEngagement\KpiActivitySchema;
use App\Models\StaffEngagement\KpiReview;
use App\Models\StaffEngagement\KpiReviewSchema;
use App\Models\StaffEngagement\KpiSetup;
use App\Models\StaffEngagement\KpiSetupSchema;
use App\Models\StaffEngagement\PerformanceArea;
use App\Models\StaffEngagement\PerformanceAreaSchema;
use App\Models\StaffEngagement\PerformanceSubArea;
use App\Models\StaffEngagement\PerformanceSubAreaSchema;
use App\Models\StaffEngagement\Survey;
use App\Models\StaffEngagement\SurveyCategory;
use App\Models\StaffEngagement\SurveyCategorySchema;
use App\Models\StaffEngagement\SurveySchema;
use App\Models\TimeManagement\TimeLog;
use App\Models\TimeManagement\TimeLogSchema;
use App\Models\TimeManagement\TimeSheet;
use App\Models\TimeManagement\TimeSheetSchema;
use App\Models\TravelManagement\TravelExpense;
use App\Models\TravelManagement\TravelExpenseSchema;
use App\Models\TravelManagement\TravelRequest;
use App\Models\TravelManagement\TravelRequestSchema;
use Illuminate\Support\Str;

// Add more schema classes as needed


class DynamicSchemaTool
{
    /**
     * Array of allowed schemas with their names, schema classes, and schema data classes.
     * @var array
     */
    protected $allowed_schemas = [
        [
            'name' => 'staff_personal_info',
            'schema_class' => PersonalInfoSchema::class,
        ],
        [
            'name' => 'staff_contact_info',
            'schema_class' => ContactInfoSchema::class,
        ],
        [
            'name' => 'staff_job_info',
            'schema_class' => JobInfoSchema::class,
        ],
        [
            'name' => 'staff_payroll_info',
            'schema_class' => PayrollInfoSchema::class,
        ],
        [
            'name' => 'staff_work_exp_info',
            'schema_class' => WorkExpInfoSchema::class,
        ],
        [
            'name' => 'staff_edu_background_info',
            'schema_class' => EduBackgroundInfoSchema::class,
        ],
        [
            'name' => 'staff_benefits_info',
            'schema_class' => BenefitsInfoSchema::class,
        ],
        [
            'name' => 'time_logs',
            'schema_class' => TimeLogSchema::class,
            'schema_data_class' => TimeLog::class,
        ],
        [
            'name' => 'time_sheets',
            'schema_class' => TimeSheetSchema::class,
            'schema_data_class' => TimeSheet::class,
        ],
        [
            'name' => 'shifts',
            'schema_class' => ShiftSchema::class,
        ],
        [
            'name' => 'working_attendance_schedules',
            'schema_class' => WorkingAttendanceScheduleSchema::class,
            'schema_data_class' => WorkingAttendanceSchedule::class,
        ],
        [
            'name' => 'attendance_notifications',
            'schema_class' => AttendanceNotificationSchema::class,
            'schema_data_class' => AttendanceNotification::class,
        ],
        [
            'name' => 'absenteeism_schedules',
            'schema_class' => AbsenteeismScheduleSchema::class,
        ],
        [
            'name' => 'travel_requests',
            'schema_class' => TravelRequestSchema::class,
            'schema_data_class' => TravelRequest::class,
        ],
        [
            'name' => 'travel_expenses',
            'schema_class' => TravelExpenseSchema::class,
            'schema_data_class' => TravelExpense::class,
        ],
        [
            'name' => 'leaves',
            'schema_unit_class' => LeaveSchemaUnit::class,
            'schema_class' => LeaveSchema::class,
            'schema_data_class' => Leave::class,
        ],
        [
            'name' => 'announcement_categories',
            'schema_class' => AnnouncementCategorySchema::class,
            'schema_data_class' => AnnouncementCategory::class,
        ],
        [
            'name' => 'folders',
            'schema_class' => FolderSchema::class,
            'schema_data_class' => Folder::class,
        ],
        [
            'name' => 'files',
            'schema_class' => FileManagementSchema::class,
            'schema_data_class' => FileManagement::class,
        ],
        [
            'name' => 'survey_categories',
            'schema_class' => SurveyCategorySchema::class,
            'schema_data_class' => SurveyCategory::class,
        ],
        [
            'name' => 'surveys',
            'schema_class' => SurveySchema::class,
            'schema_data_class' => Survey::class,
        ],
        [
            'name' => 'grievance_categories',
            'schema_class' => GrievanceCategorySchema::class,
            'schema_data_class' => GrievanceCategory::class,
        ],
        [
            'name' => 'grievances',
            'schema_class' => GrievanceSchema::class,
            'schema_data_class' => Grievance::class,
        ],
        [
            'name' => 'grievance_reviews',
            'schema_class' => GrievanceReviewSchema::class,
            'schema_data_class' => GrievanceReview::class,
        ],
        [
            'name' => 'performance_areas',
            'schema_class' => PerformanceAreaSchema::class,
            'schema_data_class' => PerformanceArea::class,
        ],
        [
            'name' => 'performance_sub_areas',
            'schema_class' => PerformanceSubAreaSchema::class,
            'schema_data_class' => PerformanceSubArea::class,
        ],
        [
            'name' => 'kpi_setups',
            'schema_class' => KpiSetupSchema::class,
            'schema_data_class' => KpiSetup::class,
        ],
        [
            'name' => 'kpi_activities',
            'schema_class' => KpiActivitySchema::class,
            'schema_data_class' => KpiActivity::class,
        ],
        [
            'name' => 'kpi_reviews',
            'schema_class' => KpiReviewSchema::class,
            'schema_data_class' => KpiReview::class,
        ],
        [
            'name' => 'appraisal_cycles',
            'schema_class' => AppraisalCycleSchema::class,
            'schema_data_class' => AppraisalCycle::class,
        ],
        [
            'name' => 'goals',
            'schema_class' => GoalSchema::class,
            'schema_data_class' => Goal::class,
        ],
        [
            'name' => 'competencies',
            'schema_class' => CompetencySchema::class,
            'schema_data_class' => Competency::class,
        ],
        [
            'name' => 'skill_sets',
            'schema_class' => SkillSetSchema::class,
            'schema_data_class' => SkillSet::class,
        ],
        [
            'name' => 'vacancies',
            'schema_class' => VacancySchema::class,
            'schema_data_class' => Vacancy::class,
        ],
        [
            'name' => 'applicants',
            'schema_class' => ApplicantSchema::class,
            'schema_data_class' => Applicant::class,
        ],
        [
            'name' => 'job_applications',
            'schema_class' => JobApplicationSchema::class,
            'schema_data_class' => JobApplication::class,
        ],
        [
            'name' => 'interview_processes',
            'schema_class' => InterviewProcessSchema::class,
            'schema_data_class' => InterviewProcess::class,
        ],
        [
            'name' => 'onboarding_activities',
            'schema_class' => OnboardingActivitySchema::class,
            'schema_data_class' => OnboardingActivity::class,
        ],
        [
            'name' => 'onboardings',
            'schema_class' => OnboardingSchema::class,
            'schema_data_class' => Onboarding::class,
        ],
        [
            'name' => 'offboarding_activities',
            'schema_class' => OffboardingActivitySchema::class,
            'schema_data_class' => OffboardingActivity::class,
        ],
        [
            'name' => 'offboardings',
            'schema_class' => OffboardingSchema::class,
            'schema_data_class' => Offboarding::class,
        ],
        [
            'name' => 'leave_types',
            'schema_class' => LeaveTypeSchema::class,
            'schema_data_class' => LeaveType::class,
        ],
        [
            'name' => 'help_desk_categories',
            'schema_class' => HelpDeskCategorySchema::class,
            'schema_data_class' => HelpDeskCategory::class,
        ],
        [
            'name' => 'staff_movements',
            'schema_unit_class' => StaffMovementSchemaUnit::class,
            'schema_class' => StaffMovementSchema::class,
            'schema_data_class' => StaffMovement::class,
        ],
        [
            'name' => 'vehicle_movements',
            'schema_unit_class' => VehicleMovementSchemaUnit::class,
            'schema_class' => VehicleMovementSchema::class,
            'schema_data_class' => VehicleMovement::class,
        ],
        [
            'name' => 'help_desks',
            'schema_class' => HelpDeskSchema::class,
            'schema_data_class' => HelpDesk::class,
        ],
// Add more schema types as needed
    ];

    /**
     * Get an array of names of all the allowed schemas, with schema and data handling flags.
     * @return array
     */
    public function getAllowedSchemaNames()
    {
        return collect($this->allowed_schemas)->map(function ($schema) {
            $name = $schema['name'];
            $handles_schema = isset ($schema['schema_class']);
            $handles_data = isset ($schema['schema_data_class']);

            return [
                'name' => $name,
                'schema' => $handles_schema,
                'data' => $handles_data,
            ];
        })->toArray();
    }

    /**
     * Get the schema class based on the requested schema name.
     * @return mixed
     */
    public function getSchemaClass()
    {
        $requested_schema = request('schema') ?? Str::plural(request('smart_form_key')) ?? null;
        $schema = $this->findSchemaByName($requested_schema);

        return $schema['schema_class'];
    }

    public function getSchemaUnitClass()
    {
        $requested_schema = request('schema') ?? Str::plural(request('smart_form_key')) ?? null;
        $schema = $this->findSchemaByName($requested_schema);

        return $schema['schema_unit_class'] ?? null;
    }

    /**
     * Get the schema data class based on the requested schema name.
     * @return mixed
     */
    public function getSchemaDataClass()
    {
        $requested_schema = request('schema');
        $schema = $this->findSchemaByName($requested_schema);

        if (isset($schema['schema_data_class'])) {
            return $schema['schema_data_class'];
        } else {
            abort(403, 'This action is not allowed for this schema');
        }
    }


    /**
     * Find a schema by its name within the allowed schemas array.
     * @param $name
     * @return mixed
     */
    protected function findSchemaByName($name)
    {
        $schema = collect($this->allowed_schemas)->first(function ($schema) use ($name) {
            return $schema['name'] === $name;
        });

        if (!$schema) {
            abort(404, 'Schema not found');
        }

        return $schema;
    }
}
