<template>
  <div class="space-y-6">
    <!-- Header -->
    <div>
      <h3 class="text-lg font-semibold">Departments</h3>
      <p class="text-sm text-muted-foreground mt-1">
        Add custom departments beyond the standard ones. Departments are used on tasks and team member assignments.
      </p>
    </div>

    <!-- Loading State -->
    <div v-if="isLoading" class="flex items-center justify-center py-8">
      <div class="animate-spin rounded-full h-8 w-8 border-b-2 border-primary"></div>
    </div>

    <!-- Content -->
    <div v-else class="space-y-4">
      <div class="flex items-center justify-between">
        <div class="flex items-center gap-2">
          <Users class="h-5 w-5 text-muted-foreground" />
          <h4 class="font-semibold">All Departments</h4>
        </div>
        <Button size="sm" @click="openAddDialog">
          <Plus class="h-4 w-4 mr-2" />
          Add Department
        </Button>
      </div>

      <div class="border rounded-lg divide-y">
        <template v-if="allDepartments.length > 0">
          <div
            v-for="department in allDepartments"
            :key="department"
            class="flex items-center justify-between p-3 hover:bg-muted/50 transition-colors"
          >
            <div class="flex items-center gap-3">
              <span class="font-medium capitalize">{{ formatDepartmentName(department) }}</span>
              <Badge v-if="isStandardDepartment(department)" variant="secondary">
                Standard
              </Badge>
              <Badge v-else variant="outline">
                Custom
              </Badge>
            </div>
            <div v-if="!isStandardDepartment(department)" class="flex items-center gap-2">
              <Button
                size="sm"
                variant="ghost"
                @click="openEditDialog(department)"
              >
                <Pencil class="h-4 w-4" />
              </Button>
              <Button
                size="sm"
                variant="ghost"
                @click="handleDelete(department)"
              >
                <Trash2 class="h-4 w-4 text-destructive" />
              </Button>
            </div>
          </div>
        </template>
        <div v-else class="p-4 text-center text-sm text-muted-foreground">
          No departments defined
        </div>
      </div>
    </div>

    <!-- Add/Edit Dialog -->
    <Dialog :open="isDialogOpen" @update:open="closeDialog">
      <DialogContent>
        <DialogHeader>
          <DialogTitle>
            {{ dialogMode === 'add' ? 'Add' : 'Edit' }} Department
          </DialogTitle>
          <DialogDescription>
            {{ dialogMode === 'add'
              ? 'Enter a name for the new department. Use lowercase letters, numbers, and underscores only.'
              : 'Update the department name. This will update all team members and tasks using this department.'
            }}
          </DialogDescription>
        </DialogHeader>

        <div class="space-y-4 py-4">
          <div class="space-y-2">
            <Label for="departmentName">Department Name</Label>
            <Input
              id="departmentName"
              v-model="departmentName"
              placeholder="e.g., fx, previz, matchmove"
              :class="{ 'border-destructive': validationError }"
              @input="validateDepartmentName"
            />
            <p v-if="validationError" class="text-sm text-destructive">
              {{ validationError }}
            </p>
            <p v-else class="text-sm text-muted-foreground">
              2-50 characters, lowercase alphanumeric with underscores only
            </p>
          </div>
        </div>

        <DialogFooter>
          <Button variant="outline" @click="closeDialog">
            Cancel
          </Button>
          <Button @click="handleDialogSave" :disabled="!isDepartmentNameValid || isSaving">
            <div v-if="isSaving" class="animate-spin rounded-full h-4 w-4 border-b-2 border-white mr-2"></div>
            {{ dialogMode === 'add' ? 'Add' : 'Update' }}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>

    <!-- Delete Confirmation Dialog -->
    <AlertDialog
      :open="isDeleteDialogOpen"
      @update:open="(open) => {
        isDeleteDialogOpen = open
        if (!open && !isDeleting) {
          departmentToDelete = ''
          deleteError = ''
        }
      }"
    >
      <AlertDialogContent>
        <AlertDialogHeader>
          <AlertDialogTitle>Delete Department</AlertDialogTitle>
          <AlertDialogDescription>
            Are you sure you want to delete the department "{{ departmentToDelete }}"?
            <span v-if="deleteError" class="block mt-2 text-destructive font-medium">
              {{ deleteError }}
            </span>
          </AlertDialogDescription>
        </AlertDialogHeader>
        <AlertDialogFooter>
          <AlertDialogCancel>Cancel</AlertDialogCancel>
          <Button
            @click="confirmDelete"
            :disabled="isDeleting"
            class="bg-destructive hover:bg-destructive/90"
          >
            <div v-if="isDeleting" class="animate-spin rounded-full h-4 w-4 border-b-2 border-white mr-2"></div>
            Delete
          </Button>
        </AlertDialogFooter>
      </AlertDialogContent>
    </AlertDialog>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { Users, Plus, Pencil, Trash2 } from 'lucide-vue-next'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog'
import {
  AlertDialog,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from '@/components/ui/alert-dialog'
import { useDepartmentsStore } from '@/stores/departments'
import { departmentService } from '@/services/department'
import { useToast } from '@/components/ui/toast/use-toast'

interface Props {
  projectId: number
}

const props = defineProps<Props>()

const emit = defineEmits<{
  updated: []
}>()

const { toast } = useToast()
const departmentsStore = useDepartmentsStore()

// State
const isLoading = ref(true)

// Dialog state
const isDialogOpen = ref(false)
const dialogMode = ref<'add' | 'edit'>('add')
const departmentName = ref('')
const originalDepartmentName = ref('')
const validationError = ref('')
const isSaving = ref(false)

// Delete dialog state
const isDeleteDialogOpen = ref(false)
const departmentToDelete = ref('')
const deleteError = ref('')
const isDeleting = ref(false)

// Computed
const allDepartments = computed(() => departmentsStore.getAllDepartmentOptions(props.projectId))
const standardDepartments = computed(() => departmentsStore.getProjectDepartments(props.projectId)?.standard_departments || [])

const isDepartmentNameValid = computed(() => {
  return departmentName.value.length >= 2 && !validationError.value
})

// Methods
const loadDepartments = async () => {
  try {
    isLoading.value = true
    await departmentsStore.fetchProjectDepartments(props.projectId, true)
  } catch (error: any) {
    console.error('Failed to load departments:', error)
    toast({
      title: 'Error',
      description: error.response?.data?.detail || 'Failed to load departments',
      variant: 'destructive'
    })
  } finally {
    isLoading.value = false
  }
}

const isStandardDepartment = (department: string): boolean => {
  return standardDepartments.value.includes(department)
}

const formatDepartmentName = (department: string): string => {
  return department.replace(/_/g, ' ')
}

const validateDepartmentName = () => {
  const name = departmentName.value.trim()

  if (name.length === 0) {
    validationError.value = ''
    return
  }

  if (name.length < 2) {
    validationError.value = 'Department name must be at least 2 characters'
    return
  }

  if (name.length > 50) {
    validationError.value = 'Department name must be at most 50 characters'
    return
  }

  if (!/^[a-z0-9_]+$/.test(name)) {
    validationError.value = 'Department name must be lowercase alphanumeric with underscores only'
    return
  }

  if (dialogMode.value === 'add' || name !== originalDepartmentName.value) {
    if (allDepartments.value.includes(name)) {
      validationError.value = 'A department with this name already exists'
      return
    }
  }

  validationError.value = ''
}

const openAddDialog = () => {
  dialogMode.value = 'add'
  departmentName.value = ''
  originalDepartmentName.value = ''
  validationError.value = ''
  isDialogOpen.value = true
}

const openEditDialog = (department: string) => {
  dialogMode.value = 'edit'
  departmentName.value = department
  originalDepartmentName.value = department
  validationError.value = ''
  isDialogOpen.value = true
}

const closeDialog = () => {
  isDialogOpen.value = false
  departmentName.value = ''
  originalDepartmentName.value = ''
  validationError.value = ''
}

const handleDialogSave = async () => {
  validateDepartmentName()

  if (!isDepartmentNameValid.value) {
    return
  }

  try {
    isSaving.value = true

    if (dialogMode.value === 'add') {
      const response = await departmentService.addDepartment(props.projectId, { department: departmentName.value.trim() })
      departmentsStore.updateProjectDepartments(props.projectId, response)

      toast({
        title: 'Success',
        description: `Department "${departmentName.value}" added successfully`
      })
    } else {
      const response = await departmentService.updateDepartment(
        props.projectId,
        originalDepartmentName.value,
        {
          old_name: originalDepartmentName.value,
          new_name: departmentName.value.trim()
        }
      )
      departmentsStore.updateProjectDepartments(props.projectId, response)

      toast({
        title: 'Success',
        description: `Department updated successfully`
      })
    }

    emit('updated')
    closeDialog()
  } catch (error: any) {
    console.error('Failed to save department:', error)
    const errorMessage = error.response?.data?.detail || 'Failed to save department'
    validationError.value = errorMessage
    toast({
      title: 'Error',
      description: errorMessage,
      variant: 'destructive'
    })
  } finally {
    isSaving.value = false
  }
}

const handleDelete = (department: string) => {
  departmentToDelete.value = department
  deleteError.value = ''
  isDeleteDialogOpen.value = true
}

const confirmDelete = async () => {
  const departmentToDeleteLocal = departmentToDelete.value

  try {
    isDeleting.value = true
    deleteError.value = ''

    if (!departmentToDeleteLocal) {
      deleteError.value = 'Department name is missing. Please try again.'
      isDeleting.value = false
      return
    }

    const response = await departmentService.deleteDepartment(props.projectId, departmentToDeleteLocal)
    departmentsStore.updateProjectDepartments(props.projectId, response)

    toast({
      title: 'Success',
      description: `Department "${departmentToDeleteLocal}" deleted successfully`
    })

    emit('updated')

    isDeleteDialogOpen.value = false
    departmentToDelete.value = ''
    deleteError.value = ''
  } catch (error: any) {
    console.error('Failed to delete department:', error)
    const errorData = error.response?.data

    if (errorData?.detail?.task_count !== undefined || errorData?.detail?.member_count !== undefined) {
      const { task_count, member_count } = errorData.detail
      const parts = []
      if (member_count) parts.push(`${member_count} team member(s)`)
      if (task_count) parts.push(`${task_count} task(s)`)
      deleteError.value = `Cannot delete: ${parts.join(' and ')} are using this department`
    } else {
      deleteError.value = errorData?.detail || 'Failed to delete department'
    }

    toast({
      title: 'Error',
      description: deleteError.value,
      variant: 'destructive'
    })
  } finally {
    isDeleting.value = false
  }
}

// Lifecycle
onMounted(() => {
  loadDepartments()
})
</script>
