<?php

namespace App\Http\Controllers;

use App\Models\Account;
use App\Models\Activity;
use App\Models\Campaign;
use App\Models\Company;
use App\Models\Contact;
use App\Models\CrmCase;
use App\Models\Country;
use App\Models\Deal;
use App\Models\DealStage;
use App\Models\EmailTemplate;
use App\Models\Lead;
use App\Models\MeetingThirdPartyIntegration;
use App\Models\Note;
use App\Models\Priority;
use App\Models\Project;
use App\Models\Repeat;
use App\Models\Status;
use App\Models\Ticket;
use App\Models\User;
use App\Models\UserAccess;
use App\Models\AccessType;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Str;

class MyActivitiesController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth');
        $this->middleware('permission:list_my_activities')->only(['index']);
    }

    public function index()
    {
        $userId = auth()->id();
        $user = auth()->user();
        $businessId = $user->business_id;

        // $activities = Activity::where('owner_id', $userId)->get();
        $activities = $this->getAccessibleActivities($user->id, 250);

        $todayactivities = $activities->filter(function ($activity) {
            $displayDate = $activity->start_date ??
                ($activity->due_date ?? ($activity->received_on ?? $activity->created_at));
            return \Carbon\Carbon::parse($displayDate)->isToday();
        });

        // $todayMeetings = Activity::where('owner_id', $userId)
        //     ->whereDate('start_date', Carbon::today())
        //     ->where('activity_type_id', 2)
        //     ->get();

        $todayMeetings = $this->getAccessibleTodayMeetings($user->id);
        
        // $monthLeads = Lead::where('contact_owner_id', $userId)
        //     ->whereMonth('created_at', Carbon::now()->month)
        //     ->whereYear('created_at', Carbon::now()->year)
        //     ->get();
        
        $monthLeads = $this->getAccessibleMonthLeads($user->id);
        $monthLeadsCount = $monthLeads->count();

        // $monthDeals = Deal::where('owner_id', $userId)
        //     ->whereMonth('created_at', Carbon::now()->month)
        //     ->whereYear('created_at', Carbon::now()->year)
        //     ->get();
        $monthDeals = $this->getAccessibleMonthDeals($user->id);

        // $monthOpenDeals = Deal::where('owner_id', $userId)
        //     ->whereMonth('created_at', Carbon::now()->month)
        //     ->whereYear('created_at', Carbon::now()->year)
        //     ->where('stage_id', '<', 10)
        //     ->count();
        $monthOpenDeals = $this->getAccessibleMonthOpenDeals($user->id);

        // $monthClosedDeals = Deal::where('owner_id', $userId)
        //     ->whereMonth('created_at', Carbon::now()->month)
        //     ->whereYear('created_at', Carbon::now()->year)
        //     ->where('stage_id', '=', 10)
        //     ->get();
        $monthClosedDeals = $this->getAccessibleMonthClosedDeals($user->id);
        $monthClosedDealsCount = $monthClosedDeals->count();

        // $monthTickets = Ticket::where('contact_owner_id', $userId)
        //     ->whereMonth('created_at', Carbon::now()->month)
        //     ->whereYear('created_at', Carbon::now()->year)
        //     ->get();
        $monthTickets = $this->getAccessibleMonthTickets($user->id);

        $allItems = collect()
            ->merge($monthLeads)
            ->merge($monthDeals)
            ->merge($monthTickets)
            ->sortByDesc('created_at');

        // $accounts = Account::where('contact_owner_id', auth()->id())->get();
        // $contacts = Contact::where('contact_owner_id', $userId)->get();

        // $leads = Lead::where('contact_owner_id', auth()->id())->get();
        // $deals = Deal::where('owner_id', auth()->id())->get();

        $leads = $this->getAccessibleLeads($user->id, 75);
        $deals = $this->getAccessibleDeals($user->id, 75);
        $tickets = $this->getAccessibleTickets($user->id, 75);
        $accounts = $this->getAccessibleAccounts($user->id, 100);
        $contacts = $this->getAccessibleContacts($user->id, 100);
        $contacts->loadMissing(['contactPhones', 'contactEmails', 'assignedUser']);
        $leads->loadMissing(['contactPhones', 'contactEmails', 'assignedUser']);
        $deals->loadMissing(['contactPhones', 'contact.contactPhones', 'contact.contactEmails', 'assignedUser']);
        $accounts->loadMissing(['contactPhones', 'contactEmails', 'primaryContact.contactPhones', 'primaryContact.contactEmails', 'assignedUser']);
        $cases = CrmCase::where('business_id', $businessId)
            ->with(['contact.contactPhones','lead.contactPhones','deal.contact.contactPhones','account.primaryContact.contactPhones','assignee'])
            ->orderByDesc('id')->limit(100)->get();
        $projects = Project::where('business_id', $businessId)->with(['owner','account.primaryContact.contactPhones'])
            ->orderBy('name')->limit(100)->get();

        // The employee landing-page preview must include every current record
        // assigned directly to them, not only records created this month.
        $allItems = collect()
            ->merge($leads->whereNull('moved_at'))
            ->merge($deals)
            ->merge($tickets->whereNull('moved_at'))
            ->sortByDesc('updated_at')->take(30)->values();

        $activityTypes = [
            1 => 'Call',
            2 => 'Meeting',
            3 => 'Task',
            4 => 'Event',
            5 => 'Deadline',
            6 => 'Other Activity',
            7 => 'Letter',
            8 => 'Fax',
            9 => 'Email',
            10 => 'Campaign',
        ];

        $futureActivities = $activities->filter(function ($activity) {
            $displayDate = $activity->start_date
                ?? ($activity->due_date
                    ?? ($activity->received_on
                        ?? $activity->created_at));

            $parsedDate = Carbon::parse($displayDate);

            return $parsedDate->isToday() || $parsedDate->isFuture();
        });

        $todayCalls = $activities->filter(function ($activity) {
            $displayDate = $activity->start_date ??
                ($activity->due_date ?? ($activity->received_on ?? $activity->created_at));
            return \Carbon\Carbon::parse($displayDate)->isToday() && $activity->activity_type_id == 1;
        });

        $callCount = $futureActivities->where('activity_type_id', 1)->count();

        // $recentContacts = Contact::where('contact_owner_id', $userId)
        //     ->where('status', 'active')
        //     ->orderBy('created_at', 'desc')
        //     ->take(5)
        //     ->get();
        $recentContacts = $this->getAccessibleRecentContacts($user->id);

        $priorities = Priority::all();
        $countries = Country::all();
        $meetings = MeetingThirdPartyIntegration::all();
        $eventStatuses = Status::all();
        $companies = Company::all();
        $repeats = Repeat::all();
        $users = $this->getAccessibleUsers();
        $emailTemplates = EmailTemplate::where('active', true)->orderBy('name')->get();
        $submissionToken = (string) Str::uuid();
        session()->put("activity_submission_tokens.$submissionToken", true);
        return view('dashboard.myactivities', compact('allItems', 'activities', 'todayactivities', 'monthLeads', 'monthLeadsCount', 'monthTickets', 'monthDeals', 'activityTypes', 'monthOpenDeals', 'monthClosedDeals', 'monthClosedDealsCount', 'futureActivities', 'callCount',   'todayCalls', 'todayMeetings', 'recentContacts', 'priorities', 'countries', 'meetings', 'eventStatuses', 'companies', 'repeats', 'users', 'contacts', 'accounts', 'deals', 'leads', 'cases', 'projects', 'emailTemplates', 'submissionToken'));
    }

    public function saleindex()
    {
        $userId = auth()->id();
        // dd($userId);
        $user = auth()->user();
        $businessId = $user->business_id;

        $activities = $this->getAccessibleActivities($user->id);
        $leads = $this->getAccessibleLeads($user->id);
        $deals = $this->getAccessibleDeals($user->id);
        $deals->loadMissing('assignedUser');
        $dealStages = DealStage::whereBetween('id', [1, 8])->orderBy('id')->get(['id', 'name']);
        $campaigns = $this->getAccessibleCampaigns($user->id);
        $tickets = $this->getAccessibleTickets($user->id);
        $accounts = $this->getAccessibleAccounts($user->id);
        $contacts = $this->getAccessibleContacts($user->id);

        // $activities = Activity::where('owner_id', $userId)->get();
        // $leads = Lead::where('contact_owner_id', $userId)->get();
        // $deals = Deal::where('owner_id', $userId)->get();
        // $campaigns = Campaign::where('owner_id', $userId)->get();
        // $tickets = Ticket::where('contact_owner_id', $userId)->get();

        // $accounts = Account::where('contact_owner_id', auth()->id())->get();
        // $contacts = Contact::where('contact_owner_id', $userId)->get();


        $activitiesCount = $activities->count();
        $leadsCount = $leads->count();
        $dealsCount = $deals->count();
        $campaignsCount = $campaigns->count();
        $ticketsCount = $tickets->count();

        $todayLeads = Lead::where('contact_owner_id', $userId)
            ->whereDate('created_at', Carbon::today())
            ->get();
        $todayDeals = Deal::where('owner_id', $userId)
            ->whereDate('created_at', Carbon::today())
            ->get();

        $todayTickets = Ticket::where('contact_owner_id', $userId)
            ->whereDate('created_at', Carbon::today())
            ->get();

        $todayCampaigns = Campaign::where('owner_id', $userId)
            ->whereDate('created_at', Carbon::today())
            ->get();

        $priorities = Priority::all();
        $countries = Country::all();
        $meetings = MeetingThirdPartyIntegration::all();
        $eventStatuses = Status::all();
        $companies = Company::all();
        $repeats = Repeat::all();
        $users = $this->getAccessibleUsers();

        return view('dashboard.salesactivity', compact('activities', 'leads', 'deals', 'dealStages', 'campaigns', 'tickets', 'activitiesCount', 'leadsCount', 'dealsCount', 'campaignsCount', 'ticketsCount', 'todayLeads', 'todayDeals', 'todayTickets', 'todayCampaigns', 'priorities', 'countries', 'meetings', 'eventStatuses', 'companies', 'repeats', 'users', 'contacts', 'accounts'));
    }

    private function getAccessibleTodayMeetings($userId)
    {
        $accessibleUserIds = $this->getAccessibleUserIds($userId);
        
        return Activity::whereIn('owner_id', $accessibleUserIds)
            ->where('business_id', auth()->user()->business_id)
            ->whereDate('start_date', Carbon::today())
            ->where('activity_type_id', 2)
            ->get();
    }

    private function getAccessibleMonthLeads($userId)
    {
        $accessibleUserIds = $this->getAccessibleUserIds($userId);
        
        return Lead::whereIn('contact_owner_id', $accessibleUserIds)
            ->where('business_id', auth()->user()->business_id)
            ->whereMonth('created_at', Carbon::now()->month)
            ->whereYear('created_at', Carbon::now()->year)
            ->get();
    }

    private function getAccessibleMonthDeals($userId)
    {
        $accessibleUserIds = $this->getAccessibleUserIds($userId);
        
        return Deal::whereIn('owner_id', $accessibleUserIds)
            ->where('business_id', auth()->user()->business_id)
            ->whereMonth('created_at', Carbon::now()->month)
            ->whereYear('created_at', Carbon::now()->year)
            ->get();
    }

    private function getAccessibleMonthOpenDeals($userId)
    {
        $accessibleUserIds = $this->getAccessibleUserIds($userId);
        
        return Deal::whereIn('owner_id', $accessibleUserIds)
            ->where('business_id', auth()->user()->business_id)
            ->whereMonth('created_at', Carbon::now()->month)
            ->whereYear('created_at', Carbon::now()->year)
            ->where('stage_id', '<', 10)
            ->count();
    }

    private function getAccessibleMonthClosedDeals($userId)
    {
        $accessibleUserIds = $this->getAccessibleUserIds($userId);
        
        return Deal::whereIn('owner_id', $accessibleUserIds)
            ->where('business_id', auth()->user()->business_id)
            ->whereMonth('created_at', Carbon::now()->month)
            ->whereYear('created_at', Carbon::now()->year)
            ->where('stage_id', '=', 10)
            ->get();
    }

    private function getAccessibleMonthTickets($userId)
    {
        $accessibleUserIds = $this->getAccessibleUserIds($userId);
        
        return Ticket::whereIn('contact_owner_id', $accessibleUserIds)
            ->where('business_id', auth()->user()->business_id)
            ->whereMonth('created_at', Carbon::now()->month)
            ->whereYear('created_at', Carbon::now()->year)
            ->get();
    }

    private function getAccessibleRecentContacts($userId)
    {
        $accessibleUserIds = $this->getAccessibleUserIds($userId);
        
        return Contact::whereIn('contact_owner_id', $accessibleUserIds)
            ->where('business_id', auth()->user()->business_id)
            ->where('status', 'active')
            ->orderBy('created_at', 'desc')
            ->take(5)
            ->get();
    }

    private function getAccessibleActivities($userId, ?int $limit = null)
    {
        $accessibleUserIds = $this->getAccessibleUserIds($userId);
        
        $query = Activity::whereIn('owner_id', $accessibleUserIds)->where('business_id', auth()->user()->business_id)->latest('updated_at');
        return ($limit ? $query->limit($limit) : $query)->get();
    }

    private function getAccessibleLeads($userId, ?int $limit = null)
    {
        $accessibleUserIds = $this->getAccessibleUserIds($userId);
        
        $query = Lead::whereIn('contact_owner_id', $accessibleUserIds)->where('business_id', auth()->user()->business_id)->latest('updated_at');
        return ($limit ? $query->limit($limit) : $query)->get();
    }

    private function getAccessibleDeals($userId, ?int $limit = null)
    {
        $accessibleUserIds = $this->getAccessibleUserIds($userId);
        
        $query = Deal::whereIn('owner_id', $accessibleUserIds)->where('business_id', auth()->user()->business_id)->latest('updated_at');
        return ($limit ? $query->limit($limit) : $query)->get();
    }
    private function getAccessibleCampaigns($userId)
    {
        $accessibleUserIds = $this->getAccessibleUserIds($userId);
        
        return Campaign::whereIn('owner_id', $accessibleUserIds)
            ->where('business_id', auth()->user()->business_id)
            ->get();
    }

    private function getAccessibleTickets($userId, ?int $limit = null)
    {
        $accessibleUserIds = $this->getAccessibleUserIds($userId);
        
        $query = Ticket::whereIn('contact_owner_id', $accessibleUserIds)->where('business_id', auth()->user()->business_id)->latest('updated_at');
        return ($limit ? $query->limit($limit) : $query)->get();
    }

    private function getAccessibleAccounts($userId, ?int $limit = null)
    {
        $accessibleUserIds = $this->getAccessibleUserIds($userId);
        
        $query = Account::whereIn('contact_owner_id', $accessibleUserIds)->where('business_id', auth()->user()->business_id)->latest('updated_at');
        return ($limit ? $query->limit($limit) : $query)->get();
    }

    private function getAccessibleContacts($userId, ?int $limit = null)
    {
        $accessibleUserIds = $this->getAccessibleUserIds($userId);
        
        $query = Contact::whereIn('contact_owner_id', $accessibleUserIds)->where('business_id', auth()->user()->business_id)->latest('updated_at');
        return ($limit ? $query->limit($limit) : $query)->get();
    }


    private function getAccessibleUserIds($currentUserId)
    {
        $accessibleUserIds = collect([$currentUserId]); // Always include self

        // Check if current user is admin - admins can see all users
        $currentUser = User::find($currentUserId);
        if ($currentUser && $currentUser->is_admin === 1) {
            // Return all user IDs for admin users
            return User::where('business_id', auth()->user()->business_id)
                ->pluck('id')
                ->toArray();
        }

        // Employee previews contain only records assigned directly to that employee.
        return [$currentUserId];

        // First, check what access type the current user has
        $currentUserAccess = UserAccess::where('user_id', $currentUserId)->first();
        
        // If current user is PRIVATE, they can only see their own data
        if ($currentUserAccess && $currentUserAccess->access_type_id == AccessType::PRIVATE) {
            return $accessibleUserIds->unique()->toArray(); // Return only self
        }

        // If current user is PUBLIC, they can see PUBLIC, PRIVATE, and SPECIFIC users
        if ($currentUserAccess && $currentUserAccess->access_type_id == AccessType::PUBLIC) {
            $publicUsers = UserAccess::where('access_type_id', AccessType::PUBLIC)
                ->pluck('user_id');
            $privateUsers = UserAccess::where('access_type_id', AccessType::PRIVATE)
                ->pluck('user_id');
            $specificUsers = UserAccess::where('access_type_id', AccessType::SPECIFIC_USERS)
                ->pluck('user_id');
            
            $accessibleUserIds = $accessibleUserIds->merge($publicUsers)
                ->merge($privateUsers)
                ->merge($specificUsers);
        return $accessibleUserIds->unique()->toArray();
        } 
        // else {
        //     // For SPECIFIC users, they can see PUBLIC users only
        //     $publicUsers = UserAccess::where('access_type_id', AccessType::PUBLIC)
        //         ->pluck('user_id');
        //     $accessibleUserIds = $accessibleUserIds->merge($publicUsers);

        //     return $accessibleUserIds->unique()->toArray();
        // }

        // Get users with SPECIFIC_USERS access where current user is specifically allowed
        $specificUsers = UserAccess::where('access_type_id', AccessType::SPECIFIC_USERS)
            ->where('user_id', $currentUserId)
            ->pluck('specific_user_id'); 
        $accessibleUserIds = $accessibleUserIds->merge($specificUsers);

        return $accessibleUserIds->unique()->toArray();
    }

    private function getAccessibleUsers()
    {
        $accessibleUserIds = $this->getAccessibleUserIds(auth()->id());
        return User::whereIn('id', $accessibleUserIds)->get();
    }
}
