<template>
  <Card>
    <CardHeader>
      <CardTitle>Field-Level Security</CardTitle>
      <CardDescription>
        Control which fields each role can read and edit
      </CardDescription>
    </CardHeader>
    <CardContent>
      <div v-if="loading" 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>

      <div v-else-if="roles.length === 0" class="text-sm text-muted-foreground py-4">
        No roles available. Create roles first to manage field-level permissions.
      </div>

      <div v-else class="space-y-4">
        <div class="rounded-md border">
          <table class="w-full">
            <thead>
              <tr class="border-b bg-muted/50">
                <th class="p-3 text-left font-medium">Field</th>
                <th 
                  v-for="role in roles" 
                  :key="role.id" 
                  class="p-3 text-center font-medium border-l"
                  :colspan="2"
                >
                  {{ role.name }}
                </th>
              </tr>
              <tr class="border-b bg-muted/30">
                <th class="p-2 text-left text-xs font-medium text-muted-foreground"></th>
                <template v-for="role in roles" :key="`${role.id}-headers`">
                  <th class="p-2 text-center text-xs font-medium text-muted-foreground border-l">Read</th>
                  <th class="p-2 text-center text-xs font-medium text-muted-foreground">Edit</th>
                </template>
              </tr>
            </thead>
            <tbody>
              <tr 
                v-for="field in fields" 
                :key="field.id"
                class="border-b hover:bg-muted/30"
              >
                <td class="p-3">
                  <div>
                    <div class="font-medium">{{ field.label }}</div>
                    <div class="text-xs text-muted-foreground">{{ field.apiName }}</div>
                  </div>
                </td>
                <template v-for="role in roles" :key="`${field.id}-${role.id}`">
                  <td class="p-3 text-center border-l">
                    <Checkbox
                      :model-value="hasPermission(field.id, role.id, 'read')"
                      @update:model-value="(checked: boolean) => updatePermission(field.id, role.id, 'read', checked)"
                      :disabled="field.isSystem"
                    />
                  </td>
                  <td class="p-3 text-center">
                    <Checkbox
                      :model-value="hasPermission(field.id, role.id, 'edit')"
                      @update:model-value="(checked: boolean) => updatePermission(field.id, role.id, 'edit', checked)"
                      :disabled="field.isSystem || !hasPermission(field.id, role.id, 'read')"
                    />
                  </td>
                </template>
              </tr>
            </tbody>
          </table>
        </div>

        <div class="flex items-center gap-2 text-sm text-muted-foreground">
          <Info class="h-4 w-4" />
          <span>System fields are always readable. Edit permissions require read permission first. Changes save automatically.</span>
        </div>
        
        <div v-if="saving" class="flex items-center gap-2 text-sm text-primary">
          <div class="animate-spin rounded-full h-4 w-4 border-b-2 border-primary"></div>
          <span>Saving...</span>
        </div>
      </div>
    </CardContent>
  </Card>
</template>

<script setup lang="ts">
import { ref, onMounted, computed } from 'vue';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '~/components/ui/card';
import { Checkbox } from '~/components/ui/checkbox';
import { Info } from 'lucide-vue-next';

const props = defineProps<{
  objectId: string;
  fields: any[];
}>();

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

const loading = ref(true);
const saving = ref(false);
const roles = ref<any[]>([]);
const permissions = ref<Map<string, Map<string, { canRead: boolean; canEdit: boolean }>>>(new Map());

// Load roles and permissions
onMounted(async () => {
  try {
    loading.value = true;
    
    // Load roles
    const rolesResponse = await api.get('/setup/roles');
    roles.value = rolesResponse || [];
    
    // Load existing permissions for this object
    const permsResponse = await api.get(`/setup/objects/${props.objectId}/field-permissions`);
    
    // Build permissions map: fieldId -> roleId -> {canRead, canEdit}
    const permsMap = new Map();
    if (permsResponse && Array.isArray(permsResponse)) {
      for (const perm of permsResponse) {
        if (!permsMap.has(perm.fieldDefinitionId)) {
          permsMap.set(perm.fieldDefinitionId, new Map());
        }
        permsMap.get(perm.fieldDefinitionId).set(perm.roleId, {
          canRead: Boolean(perm.canRead),
          canEdit: Boolean(perm.canEdit),
        });
      }
    }
    permissions.value = permsMap;
    
  } catch (error: any) {
    console.error('Failed to load field permissions:', error);
    toast.error('Failed to load field permissions');
  } finally {
    loading.value = false;
  }
});

const hasPermission = (fieldId: string, roleId: string, type: 'read' | 'edit'): boolean => {
  const fieldPerms = permissions.value.get(fieldId);
  if (!fieldPerms) return true; // Default to true if no permissions set
  const rolePerm = fieldPerms.get(roleId);
  if (!rolePerm) return true; // Default to true if no permissions set
  const value = type === 'read' ? rolePerm.canRead : rolePerm.canEdit;
  return Boolean(value); // Convert 1/0 to true/false
};

const updatePermission = async (fieldId: string, roleId: string, type: 'read' | 'edit', checked: boolean) => {
  console.log('updatePermission called:', { fieldId, roleId, type, checked });
  
  try {
    saving.value = true;
    
    // Get current permissions
    if (!permissions.value.has(fieldId)) {
      permissions.value.set(fieldId, new Map());
    }
    const fieldPerms = permissions.value.get(fieldId)!;
    
    if (!fieldPerms.has(roleId)) {
      fieldPerms.set(roleId, { canRead: true, canEdit: true });
    }
    const perm = fieldPerms.get(roleId)!;
    
    // Update permission
    if (type === 'read') {
      perm.canRead = checked;
      // If disabling read, also disable edit
      if (!checked) {
        perm.canEdit = false;
      }
    } else {
      perm.canEdit = checked;
      // If enabling edit, also enable read
      if (checked) {
        perm.canRead = true;
      }
    }
    
    console.log('Saving permission:', {
      roleId,
      fieldDefinitionId: fieldId,
      canRead: perm.canRead,
      canEdit: perm.canEdit,
    });
    
    // Save to backend
    const result = await api.put(`/setup/objects/${props.objectId}/field-permissions`, {
      roleId,
      fieldDefinitionId: fieldId,
      canRead: perm.canRead,
      canEdit: perm.canEdit,
    });
    
    console.log('Save result:', result);
    toast.success('Permission updated');
    
  } catch (error: any) {
    console.error('Failed to update field permission:', error);
    toast.error(error.message || 'Failed to update permission');
    
    // Revert change
    if (!permissions.value.has(fieldId)) return;
    const fieldPerms = permissions.value.get(fieldId)!;
    if (!fieldPerms.has(roleId)) return;
    const perm = fieldPerms.get(roleId)!;
    if (type === 'read') {
      perm.canRead = !checked;
    } else {
      perm.canEdit = !checked;
    }
  } finally {
    saving.value = false;
  }
};
</script>
