<?php

namespace App\Services\MicrosoftGraph;

use App\Models\Committee;
use App\Models\WorkGroup;
use App\Services\MicrosoftGraph\MsgraphModelChangeService;
use Illuminate\Support\Facades\Log;

/**
 * Service for tracking Committee and WorkGroup model changes
 */
class ModelChangeTrackingService
{
    protected $modelChangeService;

    public function __construct(MsgraphModelChangeService $modelChangeService)
    {
        $this->modelChangeService = $modelChangeService;
    }

    /**
     * Track when a Committee is created
     */
    public function trackCommitteeCreated(Committee $committee): void
    {
        if (!$this->shouldTrackCommittee($committee)) {
            return;
        }

        $this->modelChangeService->trackModelCreated($committee, [
            'committee_type' => $committee->type,
            'has_workgroups' => $committee->workGroups()->count() > 0
        ]);
    }

    /**
     * Track when a WorkGroup is created
     */
    public function trackWorkGroupCreated(WorkGroup $workGroup): void
    {
        if (!$this->shouldTrackWorkGroup($workGroup)) {
            return;
        }

        $this->modelChangeService->trackModelCreated($workGroup, [
            'committee_id' => $workGroup->committee_id,
            'committee_title' => $workGroup->committee ? $workGroup->committee->title : null
        ]);
    }

    /**
     * Track when a Committee is deleted
     */
    public function trackCommitteeDeleted(Committee $committee): void
    {
        // Get Microsoft Graph folder IDs before deletion
        $msIds = $committee->contactFolders()
            ->whereNotNull('ms_folder_id')
            ->pluck('ms_folder_id')
            ->toArray();

        $this->modelChangeService->trackModelDeleted($committee, [
            'committee_type' => $committee->type,
            'had_workgroups' => $committee->workGroups()->count() > 0,
            'had_users' => $committee->users()->count() > 0,
            'ms_folder_ids' => $msIds, // Store all folder IDs for incremental sync
        ]);
    }

    /**
     * Track when a WorkGroup is deleted
     */
    public function trackWorkGroupDeleted(WorkGroup $workGroup): void
    {
        // Get Microsoft Graph folder IDs before deletion
        $msIds = $workGroup->contactFolders()
            ->whereNotNull('ms_folder_id')
            ->pluck('ms_folder_id')
            ->toArray();

        $this->modelChangeService->trackModelDeleted($workGroup, [
            'committee_id' => $workGroup->committee_id,
            'committee_title' => $workGroup->committee ? $workGroup->committee->title : null,
            'had_users' => $workGroup->users()->count() > 0,
            'ms_folder_ids' => $msIds, // Store all folder IDs for incremental sync
        ]);
    }

    /**
     * Track when a Committee's status changes
     */
    public function trackCommitteeStatusChanged(Committee $committee, string $oldStatus, string $newStatus): void
    {
        if (!$this->shouldTrackCommittee($committee)) {
            return;
        }

        $this->modelChangeService->trackStatusChanged($committee, $oldStatus, $newStatus, [
            'committee_type' => $committee->type,
            'users_count' => $committee->users()->count(),
            'workgroups_count' => $committee->workGroups()->count()
        ]);
    }

    /**
     * Track when a WorkGroup's status changes
     */
    public function trackWorkGroupStatusChanged(WorkGroup $workGroup, string $oldStatus, string $newStatus): void
    {
        if (!$this->shouldTrackWorkGroup($workGroup)) {
            return;
        }

        $this->modelChangeService->trackStatusChanged($workGroup, $oldStatus, $newStatus, [
            'committee_id' => $workGroup->committee_id,
            'committee_title' => $workGroup->committee ? $workGroup->committee->title : null,
            'users_count' => $workGroup->users()->count()
        ]);
    }

    /**
     * Track when a Committee's title changes
     */
    public function trackCommitteeTitleChanged(Committee $committee, string $oldTitle, string $newTitle, string $language = 'en'): void
    {
        if (!$this->shouldTrackCommittee($committee)) {
            return;
        }

        $this->modelChangeService->trackTitleChanged($committee, $oldTitle, $newTitle, $language, [
            'committee_type' => $committee->type,
            'users_count' => $committee->users()->count(),
            'workgroups_count' => $committee->workGroups()->count()
        ]);
    }

    /**
     * Track when a WorkGroup's title changes
     */
    public function trackWorkGroupTitleChanged(WorkGroup $workGroup, string $oldTitle, string $newTitle, string $language = 'en'): void
    {
        if (!$this->shouldTrackWorkGroup($workGroup)) {
            return;
        }

        $this->modelChangeService->trackTitleChanged($workGroup, $oldTitle, $newTitle, $language, [
            'committee_id' => $workGroup->committee_id,
            'committee_title' => $workGroup->committee ? $workGroup->committee->title : null,
            'users_count' => $workGroup->users()->count()
        ]);
    }

    /**
     * Check if we should track changes for this committee
     */
    private function shouldTrackCommittee(Committee $committee): bool
    {
        // Don't track legal committees and legal opinions as they are special
        if (in_array($committee->type, ['legalCommittee', 'legalOpinions'])) {
            return false;
        }

        return true;
    }

    /**
     * Check if we should track changes for this workgroup
     */
    private function shouldTrackWorkGroup(WorkGroup $workGroup): bool
    {
        // Don't track workgroups that belong to legal committees
        if ($workGroup->committee &&
            in_array($workGroup->committee->type, ['legalCommittee', 'legalOpinions'])) {
            return false;
        }

        return true;
    }
}
