<template>
  <div class="space-y-6">
    <div v-if="loading" class="text-center py-8">Loading...</div>
    
    <div v-else class="space-y-6">
      <!-- Object Permissions -->
      <div
        v-for="obj in objects"
        :key="obj.id"
        class="border rounded-lg p-4 space-y-3"
      >
        <div class="flex items-center justify-between">
          <h3 class="font-semibold">{{ obj.label }}</h3>
          <Button
            variant="ghost"
            size="sm"
            @click="toggleObjectExpanded(obj.id)"
          >
            {{ expandedObjects[obj.id] ? 'Collapse' : 'Expand' }}
          </Button>
        </div>

        <div v-if="expandedObjects[obj.id]" class="space-y-4">
          <!-- CRUD Permissions -->
          <div class="grid grid-cols-2 gap-3">
            <div class="flex items-center space-x-2">
              <Checkbox
                :id="`${obj.id}-read`"
                :checked="hasPermission(obj.apiName, 'read')"
                @update:checked="(val) => setPermission(obj.apiName, 'read', val)"
              />
              <Label :for="`${obj.id}-read`" class="cursor-pointer">Read</Label>
            </div>
            <div class="flex items-center space-x-2">
              <Checkbox
                :id="`${obj.id}-create`"
                :checked="hasPermission(obj.apiName, 'create')"
                @update:checked="(val) => setPermission(obj.apiName, 'create', val)"
              />
              <Label :for="`${obj.id}-create`" class="cursor-pointer">Create</Label>
            </div>
            <div class="flex items-center space-x-2">
              <Checkbox
                :id="`${obj.id}-update`"
                :checked="hasPermission(obj.apiName, 'update')"
                @update:checked="(val) => setPermission(obj.apiName, 'update', val)"
              />
              <Label :for="`${obj.id}-update`" class="cursor-pointer">Update</Label>
            </div>
            <div class="flex items-center space-x-2">
              <Checkbox
                :id="`${obj.id}-delete`"
                :checked="hasPermission(obj.apiName, 'delete')"
                @update:checked="(val) => setPermission(obj.apiName, 'delete', val)"
              />
              <Label :for="`${obj.id}-delete`" class="cursor-pointer">Delete</Label>
            </div>
          </div>

          <!-- Advanced: Condition-based permissions -->
          <div class="border-t pt-3">
            <div class="flex items-center space-x-2 mb-2">
              <Checkbox
                :id="`${obj.id}-conditions`"
                :checked="hasConditions(obj.apiName)"
                @update:checked="(val) => toggleConditions(obj.apiName, val)"
              />
              <Label :for="`${obj.id}-conditions`" class="cursor-pointer text-sm">
                Apply conditions (e.g., own records only)
              </Label>
            </div>
            
            <div v-if="hasConditions(obj.apiName)" class="ml-6 space-y-2">
              <div class="text-sm text-muted-foreground">
                Only allow access to records where:
              </div>
              <div class="flex gap-2">
                <Input
                  v-model="getConditions(obj.apiName).field"
                  placeholder="Field name (e.g., ownerId)"
                  class="flex-1"
                />
                <Input
                  v-model="getConditions(obj.apiName).value"
                  placeholder="Value (e.g., $userId)"
                  class="flex-1"
                />
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- Save Button -->
      <div class="flex justify-end gap-2">
        <Button variant="outline" @click="$emit('cancel')">Cancel</Button>
        <Button @click="savePermissions" :disabled="saving">
          {{ saving ? 'Saving...' : 'Save Permissions' }}
        </Button>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Checkbox } from '@/components/ui/checkbox'

interface Props {
  role: any
}

const props = defineProps<Props>()
const emit = defineEmits(['saved', 'cancel'])

const { api } = useApi()
const { toast } = useToast()

const loading = ref(true)
const saving = ref(false)
const objects = ref<any[]>([])
const expandedObjects = ref<Record<string, boolean>>({})

// Store permissions as CASL-like rules
const permissions = ref<Record<string, {
  actions: string[]
  conditions?: any
}>>({})

const fetchObjects = async () => {
  try {
    loading.value = true
    objects.value = await api.get('/setup/objects')
    
    // Expand all objects by default
    objects.value.forEach(obj => {
      expandedObjects.value[obj.id] = true
    })
  } catch (e: any) {
    console.error('Error fetching objects:', e)
  } finally {
    loading.value = false
  }
}

const fetchRolePermissions = async () => {
  try {
    const rules = await api.get(`/role-rules/role/${props.role.id}`)
    // Parse existing rules into our format
    if (rules && rules.length > 0 && rules[0].rulesJson) {
      const rulesJson = rules[0].rulesJson
      rulesJson.forEach((rule: any) => {
        if (!permissions.value[rule.subject]) {
          permissions.value[rule.subject] = { actions: [] }
        }
        if (Array.isArray(rule.action)) {
          permissions.value[rule.subject].actions.push(...rule.action)
        } else {
          permissions.value[rule.subject].actions.push(rule.action)
        }
        if (rule.conditions) {
          permissions.value[rule.subject].conditions = rule.conditions
        }
      })
    }
  } catch (e: any) {
    console.error('Error fetching role permissions:', e)
  }
}

const toggleObjectExpanded = (objectId: string) => {
  expandedObjects.value[objectId] = !expandedObjects.value[objectId]
}

const hasPermission = (subject: string, action: string): boolean => {
  return permissions.value[subject]?.actions.includes(action) || false
}

const setPermission = (subject: string, action: string, value: boolean) => {
  if (!permissions.value[subject]) {
    permissions.value[subject] = { actions: [] }
  }
  
  if (value) {
    if (!permissions.value[subject].actions.includes(action)) {
      permissions.value[subject].actions.push(action)
    }
  } else {
    permissions.value[subject].actions = permissions.value[subject].actions.filter(a => a !== action)
  }
}

const hasConditions = (subject: string): boolean => {
  return !!permissions.value[subject]?.conditions
}

const toggleConditions = (subject: string, value: boolean) => {
  if (!permissions.value[subject]) {
    permissions.value[subject] = { actions: [] }
  }
  
  if (value) {
    permissions.value[subject].conditions = { field: 'ownerId', value: '$userId' }
  } else {
    delete permissions.value[subject].conditions
  }
}

const getConditions = (subject: string) => {
  if (!permissions.value[subject]?.conditions) {
    return { field: '', value: '' }
  }
  const cond = permissions.value[subject].conditions
  // Convert CASL condition format to simple field/value
  const field = Object.keys(cond)[0] || ''
  const value = cond[field] || ''
  return { field, value }
}

const savePermissions = async () => {
  try {
    saving.value = true

    // Convert our permission structure to CASL rules format
    const rules: any[] = []
    
    Object.entries(permissions.value).forEach(([subject, perm]) => {
      if (perm.actions.length > 0) {
        const rule: any = {
          action: perm.actions,
          subject,
        }
        
        if (perm.conditions) {
          const cond = getConditions(subject)
          if (cond.field && cond.value) {
            rule.conditions = { [cond.field]: cond.value }
          }
        }
        
        rules.push(rule)
      }
    })

    await api.post('/role-rules', {
      roleId: props.role.id,
      rulesJson: rules,
    })

    emit('saved')
  } catch (e: any) {
    console.error('Error saving permissions:', e)
    toast.error('Failed to save permissions')
  } finally {
    saving.value = false
  }
}

onMounted(async () => {
  await fetchObjects()
  await fetchRolePermissions()
})
</script>
