<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-6">
        <!-- Role Selector -->
        <div class="space-y-2">
          <Label>Select Role</Label>
          <Select v-model="selectedRoleId" @update:model-value="(value) => selectedRoleId = value">
            <SelectTrigger class="w-full">
              <SelectValue placeholder="Choose a role to configure permissions" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem v-for="role in roles" :key="role.id" :value="role.id">
                {{ role.name }}
              </SelectItem>
            </SelectContent>
          </Select>
        </div>

        <!-- Object-Level Permissions -->
        <div v-if="selectedRoleId" class="space-y-2">
          <h3 class="text-sm font-medium">Object-Level Permissions</h3>
          <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">Permission</th>
                  <th class="p-3 text-center font-medium">Enabled</th>
                </tr>
              </thead>
              <tbody>
                <tr class="border-b hover:bg-muted/30">
                  <td class="p-3">Create</td>
                  <td class="p-3 text-center">
                    <Checkbox
                      :model-value="objectPermissions.canCreate"
                      @update:model-value="(checked: boolean) => updateObjectPermission('canCreate', checked)"
                    />
                  </td>
                </tr>
                <tr class="border-b hover:bg-muted/30">
                  <td class="p-3">Read</td>
                  <td class="p-3 text-center">
                    <Checkbox
                      :model-value="objectPermissions.canRead"
                      @update:model-value="(checked: boolean) => updateObjectPermission('canRead', checked)"
                    />
                  </td>
                </tr>
                <tr class="border-b hover:bg-muted/30">
                  <td class="p-3">Edit</td>
                  <td class="p-3 text-center">
                    <Checkbox
                      :model-value="objectPermissions.canEdit"
                      @update:model-value="(checked: boolean) => updateObjectPermission('canEdit', checked)"
                    />
                  </td>
                </tr>
                <tr class="border-b hover:bg-muted/30">
                  <td class="p-3">Delete</td>
                  <td class="p-3 text-center">
                    <Checkbox
                      :model-value="objectPermissions.canDelete"
                      @update:model-value="(checked: boolean) => updateObjectPermission('canDelete', checked)"
                    />
                  </td>
                </tr>
                <tr class="border-b hover:bg-muted/30">
                  <td class="p-3">View All</td>
                  <td class="p-3 text-center">
                    <Checkbox
                      :model-value="objectPermissions.canViewAll"
                      @update:model-value="(checked: boolean) => updateObjectPermission('canViewAll', checked)"
                    />
                  </td>
                </tr>
                <tr class="hover:bg-muted/30">
                  <td class="p-3">Modify All</td>
                  <td class="p-3 text-center">
                    <Checkbox
                      :model-value="objectPermissions.canModifyAll"
                      @update:model-value="(checked: boolean) => updateObjectPermission('canModifyAll', checked)"
                    />
                  </td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>

        <!-- Field-Level Permissions -->
        <div v-if="selectedRoleId" class="space-y-2">
          <h3 class="text-sm font-medium">Field-Level Permissions</h3>
          <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 class="p-3 text-center font-medium">Read</th>
                  <th class="p-3 text-center font-medium">Edit</th>
                </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>
                  <td class="p-3 text-center">
                    <Checkbox
                      :model-value="hasPermission(field.id, selectedRoleId, 'read')"
                      @update:model-value="(checked: boolean) => updatePermission(field.id, selectedRoleId, 'read', checked)"
                      :disabled="field.isSystem"
                    />
                  </td>
                  <td class="p-3 text-center">
                    <Checkbox
                      :model-value="hasPermission(field.id, selectedRoleId, 'edit')"
                      @update:model-value="(checked: boolean) => updatePermission(field.id, selectedRoleId, 'edit', checked)"
                      :disabled="field.isSystem || !hasPermission(field.id, selectedRoleId, 'read')"
                    />
                  </td>
                </tr>
              </tbody>
            </table>
          </div>
        </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, watch } from 'vue';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '~/components/ui/card';
import { Checkbox } from '~/components/ui/checkbox';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '~/components/ui/select';
import { Label } from '~/components/ui/label';
import { Info } from 'lucide-vue-next';

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

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

const loading = ref(true);
const saving = ref(false);
const roles = ref<any[]>([]);
const selectedRoleId = ref<string>('');
const permissions = ref<Map<string, Map<string, { canRead: boolean; canEdit: boolean }>>>(new Map());
const objectPermissions = ref({
  canCreate: false,
  canRead: false,
  canEdit: false,
  canDelete: false,
  canViewAll: false,
  canModifyAll: false,
});

// 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) => {
  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;
      }
    }
    
    // Save to backend
    await api.put(`/setup/objects/${props.objectId}/field-permissions`, {
      roleId,
      fieldDefinitionId: fieldId,
      canRead: perm.canRead,
      canEdit: perm.canEdit,
    });
    
    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;
  }
};

const updateObjectPermission = async (permission: string, checked: boolean) => {
  if (!selectedRoleId.value) return;
  
  try {
    saving.value = true;
    
    // Update local state
    (objectPermissions.value as any)[permission] = checked;
    
    // Save to backend
    await api.put(`/setup/objects/${props.objectApiName}/permissions`, {
      roleId: selectedRoleId.value,
      ...objectPermissions.value,
    });
    
    toast.success('Object permission updated');
  } catch (error: any) {
    console.error('Failed to update object permission:', error);
    toast.error(error.message || 'Failed to update permission');
    
    // Revert change
    (objectPermissions.value as any)[permission] = !checked;
  } finally {
    saving.value = false;
  }
};

// Load object permissions when role changes
watch(selectedRoleId, async (roleId) => {
  if (!roleId) return;
  
  try {
    const response = await api.get(`/setup/objects/${props.objectApiName}/permissions/${roleId}`);
    if (response) {
      objectPermissions.value = {
        canCreate: Boolean(response.canCreate),
        canRead: Boolean(response.canRead),
        canEdit: Boolean(response.canEdit),
        canDelete: Boolean(response.canDelete),
        canViewAll: Boolean(response.canViewAll),
        canModifyAll: Boolean(response.canModifyAll),
      };
    }
  } catch (error: any) {
    console.error('Failed to load object permissions:', error);
  }
});
</script>
