<template>
  <div class="relative flex items-center gap-1" v-memo="[currentStatusId, isUpdating, isLoadingStatuses, assignedUserId]" data-testid="editable-task-status">
    <!-- Status Selector -->
    <Select 
      :model-value="currentStatusId" 
      @update:model-value="handleStatusChange"
      :disabled="isUpdating || isLoadingStatuses"
    >
      <SelectTrigger class="h-6 w-[130px] font-semibold text-xs"
        :style="{ backgroundColor: currentStatusObject.color }"
      >
        <SelectValue>
          <!-- <TaskStatusBadge :status="currentStatusObject"/> -->
        </SelectValue>
      </SelectTrigger>
      <SelectContent>
        <SelectItem 
          v-for="statusOption in allStatusOptions" 
          :key="statusOption.id" 
          :value="statusOption.id"
        >
          <div class="flex items-center gap-2">
            <!-- Color indicator -->
            <!-- <div 
              v-if="statusOption.color"
              class="w-3 h-3 rounded-full border border-border"
              :style="{ backgroundColor: statusOption.color }"
            /> -->
            <TaskStatusBadge :status="statusOption" compact />
          </div>
        </SelectItem>
      </SelectContent>
    </Select>
    
    <!-- User Assignment Button -->
    <div @click.stop>
      <Popover>
        <PopoverTrigger as-child>
          <Button
            variant="ghost"
            size="sm"
            class="h-6 w-6 p-0 hover:bg-accent relative"
            :disabled="isUpdating"
            @click.stop="ensureMembersLoaded"
          >
            <Avatar class="h-4 w-4" v-if="assignedUser">
              <AvatarImage :src="getAvatarUrl(assignedUser?.user_avatar_url, assignedUser?.user_first_name, assignedUser?.user_last_name)" />
              <AvatarFallback class="text-[8px]">{{ getUserInitials(assignedUser) }}</AvatarFallback>
            </Avatar>
            <User class="h-3 w-3" v-else />
          </Button>
        </PopoverTrigger>
        <PopoverContent class="w-64 p-2" align="start" side="bottom" :side-offset="4">
          <div class="space-y-2">
            <div class="px-2 py-1.5 text-sm font-semibold">Assign Task</div>
            
            <!-- Current Assignment Display with X button -->
            <div v-if="assignedUser" class="px-2 py-2 bg-muted rounded-md flex items-center gap-2">
              <Avatar class="h-8 w-8">
                <AvatarImage :src="getAvatarUrl(assignedUser?.user_avatar_url, assignedUser?.user_first_name, assignedUser?.user_last_name)" />
                <AvatarFallback class="text-[8px]">{{ getUserInitials(assignedUser) }}</AvatarFallback>
              </Avatar>
              <div class="flex flex-col flex-1 min-w-0">
                <span class="text-xs font-medium truncate">{{ assignedUser.user_first_name }} {{ assignedUser.user_last_name }}</span>
                <span class="text-[10px] text-muted-foreground">Current</span>
              </div>
              <Button
                variant="ghost"
                size="sm"
                class="h-6 w-6 p-0 hover:bg-destructive hover:text-destructive-foreground"
                @click.stop="handleAssignUser(null)"
                :disabled="isAssigning"
              >
                <X class="h-3 w-3" />
              </Button>
            </div>
            
            <!-- Search Input -->
            <div class="relative">
              <Search class="absolute left-2 top-1/2 transform -translate-y-1/2 h-3 w-3 text-muted-foreground" />
              <Input
                v-model="searchQuery"
                placeholder="Search members..."
                class="pl-7 h-8 text-xs"
              />
            </div>
            
            <!-- Loading state -->
            <div v-if="isLoadingMembers" class="flex items-center justify-center py-4">
              <div class="animate-spin rounded-full h-4 w-4 border-b-2 border-primary"></div>
              <span class="ml-2 text-sm">Loading members...</span>
            </div>
            
            <!-- Error state -->
            <div v-else-if="projectMembers.length === 0" class="px-2 py-4 text-sm text-muted-foreground text-center">
              No project members found
              <Button 
                variant="outline" 
                size="sm" 
                class="mt-2" 
                @click="loadProjectMembers"
              >
                Retry
              </Button>
            </div>
            
            <!-- Content when members are loaded -->
            <template v-else>
              <!-- Project members list -->
              <div class="max-h-64 overflow-y-auto">
                <div v-if="filteredProjectMembers.length === 0" class="py-2 text-xs text-muted-foreground text-center">
                  No matching members found
                </div>
                <Button
                  v-else
                  v-for="member in filteredProjectMembers"
                  :key="member.user_id"
                  variant="ghost"
                  size="sm"
                  class="w-full justify-start h-10"
                  @click="handleAssignUser(member.user_id)"
                  :disabled="isAssigning"
                >
                  <Avatar class="h-8 w-8 mr-2">
                    <AvatarImage :src="getAvatarUrl(member.user_avatar_url, member.user_first_name, member.user_last_name)" />
                    <AvatarFallback class="text-[8px]">{{ getUserInitials(member) }}</AvatarFallback>
                  </Avatar>
                  <div class="flex flex-col items-start flex-1 min-w-0">
                    <span class="text-xs truncate">{{ member.user_first_name }} {{ member.user_last_name }}</span>
                    <span class="text-[10px] text-muted-foreground" v-if="member.department_role">{{ formatDepartmentRole(member.department_role) }}</span>
                  </div>
                  <Check v-if="assignedUserId === member.user_id" class="h-4 w-4 text-green-500 ml-1" />
                </Button>
              </div>
            </template>
          </div>
        </PopoverContent>
      </Popover>
    </div>
    
    <!-- Loading indicator -->
    <div 
      v-if="isUpdating || isLoadingStatuses" 
      class="absolute inset-0 bg-background/50 flex items-center justify-center rounded"
    >
      <div class="animate-spin rounded-full h-4 w-4 border-b-2 border-primary"></div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, watch } from 'vue'
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select'
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from '@/components/ui/popover'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
import { User, Search, Check, X } from 'lucide-vue-next'
import TaskStatusBadge from '@/components/task/TaskStatusBadge.vue'
import { TaskStatus } from '@/services/shot'
import { taskService } from '@/services/task'
import { projectService, type ProjectMember } from '@/services/project'
import { useTaskStatusesStore } from '@/stores/taskStatuses'

interface StatusOption {
  id: string
  name: string
  color?: string
  is_system?: boolean
}

interface Props {
  shotId: number
  taskType: string
  status: TaskStatus | string
  taskId?: number | null
  projectId: number
  assignedUserId?: number | null
}

interface Emits {
  (e: 'status-updated', shotId: number, taskType: string, newStatus: string): void
  (e: 'assignment-updated', shotId: number, taskType: string, userId: number | null): void
}

const props = defineProps<Props>()
const emit = defineEmits<Emits>()

// Use the shared task statuses store instead of direct API calls
const taskStatusesStore = useTaskStatusesStore()

const isUpdating = ref(false)
const isAssigning = ref(false)
const isLoadingMembers = ref(false)
const projectMembers = ref<ProjectMember[]>([])
const searchQuery = ref('')

// Filtered project members based on search query
const filteredProjectMembers = computed(() => {
  if (!searchQuery.value.trim()) {
    return projectMembers.value
  }
  const query = searchQuery.value.toLowerCase().trim()
  return projectMembers.value.filter(member => {
    const fullName = `${member.user_first_name || ''} ${member.user_last_name || ''}`.toLowerCase()
    const departmentRole = member.department_role?.toLowerCase() || ''
    return fullName.includes(query) || departmentRole.includes(query)
  })
})

// Get loading state from store
const isLoadingStatuses = computed(() => taskStatusesStore.isLoading(props.projectId))

// Get all status options from store
const allStatusOptions = computed(() => taskStatusesStore.getAllStatusOptions(props.projectId))

// Get current status ID (handle both TaskStatus enum and custom status strings)
const currentStatusId = computed(() => {
  if (typeof props.status === 'string') {
    return props.status
  }
  return props.status as string
})

// Get current status object for display using store
const currentStatusObject = computed((): StatusOption => {
  const statusFromStore = taskStatusesStore.getStatusById(props.projectId, currentStatusId.value)
  if (statusFromStore) {
    return {
      id: statusFromStore.id,
      name: statusFromStore.name,
      color: statusFromStore.color,
      is_system: 'is_system' in statusFromStore ? statusFromStore.is_system : false
    }
  }
  
  // Fallback to current status as-is
  return {
    id: currentStatusId.value,
    name: formatStatusName(currentStatusId.value)
  }
})

// Get assigned user info
const assignedUserId = computed(() => props.assignedUserId)
const assignedUser = computed(() => {
  if (!assignedUserId.value) return null
  return projectMembers.value.find(member => member.user_id === assignedUserId.value) || null
})

// Format status name for display
const formatStatusName = (status: string): string => {
  switch (status) {
    case 'not_started':
      return 'Not Started'
    case 'in_progress':
      return 'In Progress'
    case 'submitted':
      return 'Submitted'
    case 'approved':
      return 'Approved'
    case 'retake':
      return 'Retake'
    default:
      // Convert snake_case to Title Case
      return status.split('_').map(word => 
        word.charAt(0).toUpperCase() + word.slice(1)
      ).join(' ')
  }
}

// Format department role for display
const formatDepartmentRole = (role: string): string => {
  return role.charAt(0).toUpperCase() + role.slice(1)
}

// Get user initials
const getUserInitials = (member: ProjectMember): string => {
  const first = member.user_first_name?.charAt(0) || ''
  const last = member.user_last_name?.charAt(0) || ''
  return (first + last).toUpperCase()
}

import { useAvatarUrl } from '@/composables/useAvatarUrl'

const { getAvatarUrl, getInitialsAvatarUrl } = useAvatarUrl()

// Fetch custom statuses for the project using store
const fetchStatuses = async () => {
  if (!props.projectId) return
  
  try {
    await taskStatusesStore.fetchProjectStatuses(props.projectId)
  } catch (error) {
    console.error('Failed to fetch task statuses:', error)
  }
}

// Load project members
const loadProjectMembers = async () => {
  if (projectMembers.value.length > 0) return // Already loaded
  
  isLoadingMembers.value = true
  try {
    console.log('Loading project members for project:', props.projectId)
    projectMembers.value = await projectService.getProjectMembers(props.projectId)
    console.log('Loaded project members:', projectMembers.value)
  } catch (error) {
    console.error('Failed to load project members:', error)
  } finally {
    isLoadingMembers.value = false
  }
}

// Ensure members are loaded when popover is about to open
const ensureMembersLoaded = () => {
  console.log('Ensuring project members are loaded')
  if (projectMembers.value.length === 0) {
    console.log('Loading project members on button click')
    loadProjectMembers()
  }
}

const handleStatusChange = async (newStatusId: any) => {
  if (!newStatusId || newStatusId === currentStatusId.value) return
  
  const statusId = newStatusId as string
  
  isUpdating.value = true
  
  try {
    let taskId = props.taskId
    
    // If no task exists, create one first
    if (!taskId) {
      const newTask = await taskService.createShotTask(props.shotId, props.taskType)
      taskId = newTask.task_id
    }
    
    // Update the task status
    if (taskId) {
      await taskService.updateTaskStatus(taskId, statusId as TaskStatus)
      emit('status-updated', props.shotId, props.taskType, statusId)
    }
  } catch (error) {
    console.error('Failed to update task status:', error)
    // Revert the status change by emitting the original status
    // This will cause the parent component to refresh the data
    emit('status-updated', props.shotId, props.taskType, currentStatusId.value)
  } finally {
    isUpdating.value = false
  }
}

const handleAssignUser = async (userId: number | null) => {
  isAssigning.value = true
  
  try {
    let taskId = props.taskId
    
    // If no task exists, create one first
    if (!taskId) {
      const newTask = await taskService.createShotTask(props.shotId, props.taskType)
      taskId = newTask.task_id
    }
    
    // Assign or unassign the task
    if (taskId) {
      if (userId) {
        // Use the assignment endpoint for assigning to a user
        await taskService.assignTask(taskId, userId)
      } else {
        // Use the update endpoint for unassignment (set assigned_user_id to 0)
        await taskService.updateTask(taskId, { assigned_user_id: 0 })
      }
      emit('assignment-updated', props.shotId, props.taskType, userId)
    }
    
    // Close popover by simulating click outside after assignment
    setTimeout(() => {
      document.querySelector('[data-state="open"]')?.dispatchEvent(new MouseEvent('click', { bubbles: true }))
    }, 100)
  } catch (error) {
    console.error('Failed to assign task:', error)
  } finally {
    isAssigning.value = false
  }
}

// Fetch statuses on mount
onMounted(() => {
  fetchStatuses()
  // Preload project members to ensure they're available when needed
  loadProjectMembers()
})

// Refetch statuses when projectId changes
watch(() => props.projectId, () => {
  fetchStatuses()
  // Clear project members when project changes
  projectMembers.value = []
})
</script>
