'use client';

import { useMemo } from 'react';
import { useMutation, useSuspenseQuery } from '@tanstack/react-query';
import { Checkbox } from '@/components/ui/checkbox';
import { Button } from '@/components/ui/button';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue
} from '@/components/ui/select';
import {
  Sheet,
  SheetContent,
  SheetDescription,
  SheetFooter,
  SheetHeader,
  SheetTitle
} from '@/components/ui/sheet';
import { Label } from '@/components/ui/label';
import { useAppForm, useFormFields } from '@/components/ui/tanstack-form';
import { toast } from 'sonner';
import { userPermissionAssignmentDetailQueryOptions } from '../api/queries';
import { saveUserPermissionAssignmentMutation } from '../api/mutations';
import {
  userPermissionAssignmentSchema,
  type UserPermissionAssignmentFormValues
} from '../schemas/user-permission-assignment';
import { EffectivePermissionPreview } from './effective-permission-preview';

export function UserPermissionSheet({
  userId,
  open,
  onOpenChange
}: {
  userId: string;
  open: boolean;
  onOpenChange: (open: boolean) => void;
}) {
  const { data } = useSuspenseQuery(userPermissionAssignmentDetailQueryOptions(userId));
  const detail = data.detail;

  const saveMutation = useMutation({
    ...saveUserPermissionAssignmentMutation,
    onSuccess: () => {
      toast.success('บันทึก User Permission เรียบร้อยแล้ว');
      onOpenChange(false);
    },
    onError: (error) => {
      toast.error(error.message || 'ไม่สามารถบันทึก User Permission ได้');
    }
  });

  const form = useAppForm({
    defaultValues: {
      template_id: detail.assignment.template_id ?? detail.templates[0]?.id ?? 0,
      allow_permissions: detail.overrides
        .filter((override) => override.effect === 'allow')
        .map((override) => override.permission),
      deny_permissions: detail.overrides
        .filter((override) => override.effect === 'deny')
        .map((override) => override.permission),
      reason: ''
    } as UserPermissionAssignmentFormValues,
    validators: {
      onSubmit: userPermissionAssignmentSchema
    },
    onSubmit: async ({ value }) => {
      await saveMutation.mutateAsync({
        userId,
        values: value
      });
    }
  });

  const { FormTextareaField } = useFormFields<UserPermissionAssignmentFormValues>();

  const selectedTemplate = useMemo(
    () =>
      detail.templates.find((template) => template.id === form.state.values.template_id) ?? null,
    [detail.templates, form.state.values.template_id]
  );

  const effectivePermissions = useMemo(() => {
    const basePermissions = selectedTemplate?.permissions ?? [];
    const allowPermissions = form.state.values.allow_permissions ?? [];
    const denyPermissions = form.state.values.deny_permissions ?? [];

    return [...new Set([...basePermissions, ...allowPermissions])].filter(
      (permission) => !denyPermissions.includes(permission)
    );
  }, [
    form.state.values.allow_permissions,
    form.state.values.deny_permissions,
    selectedTemplate?.permissions
  ]);

  return (
    <Sheet open={open} onOpenChange={onOpenChange}>
      <SheetContent className='flex w-full flex-col sm:max-w-4xl'>
        <SheetHeader>
          <SheetTitle>Manage User Permissions</SheetTitle>
          <SheetDescription>
            {detail.user.full_name} ({detail.user.employee_code ?? 'N/A'})
          </SheetDescription>
        </SheetHeader>

        <div className='flex-1 overflow-auto'>
          <form.AppForm>
            <form.Form id='user-permission-form' className='space-y-6'>
              <div className='rounded-lg border p-4'>
                <div className='grid grid-cols-1 gap-2 md:grid-cols-2'>
                  <div>
                    <p className='text-muted-foreground text-xs'>Email</p>
                    <p className='font-medium'>{detail.user.email}</p>
                  </div>
                  <div>
                    <p className='text-muted-foreground text-xs'>Department / Position</p>
                    <p className='font-medium'>
                      {detail.user.department_name ?? '-'} / {detail.user.position_name ?? '-'}
                    </p>
                  </div>
                </div>
              </div>

              <form.AppField
                name='template_id'
                children={(field) => (
                  <field.FieldSet>
                    <field.Field>
                      <field.FieldLabel htmlFor={field.name}>
                        Permission Template *
                      </field.FieldLabel>
                      <Select
                        value={String(field.state.value)}
                        onValueChange={(value) => {
                          const templateId = Number(value);
                          if (Number.isInteger(templateId) && templateId > 0) {
                            field.handleChange(templateId);
                          }
                        }}
                        onOpenChange={(open) => {
                          if (!open) {
                            field.handleBlur();
                          }
                        }}
                      >
                        <SelectTrigger
                          id={field.name}
                          aria-invalid={field.state.meta.isTouched && !field.state.meta.isValid}
                        >
                          <SelectValue placeholder='Select permission template' />
                        </SelectTrigger>
                        <SelectContent>
                          {detail.templates.map((template) => (
                            <SelectItem key={template.id} value={String(template.id)}>
                              {template.name} ({template.code})
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                    </field.Field>
                    <field.FieldError />
                  </field.FieldSet>
                )}
              />

              <form.AppField
                name='allow_permissions'
                mode='array'
                children={(field) => {
                  const values = field.state.value ?? [];

                  return (
                    <field.FieldSet>
                      <field.FieldLabel>Extra Permissions</field.FieldLabel>
                      <div className='grid grid-cols-1 gap-3 md:grid-cols-2'>
                        {(selectedTemplate?.permissions ?? detail.effective_permissions).map(
                          (permission) => (
                            <div
                              key={`allow-${permission}`}
                              className='flex items-center gap-3 rounded-md border p-3'
                            >
                              <Checkbox
                                id={`allow-${permission}`}
                                checked={values.includes(permission)}
                                onCheckedChange={(checked) => {
                                  if (checked) {
                                    field.pushValue(permission);
                                    return;
                                  }

                                  const index = values.indexOf(permission);
                                  if (index > -1) {
                                    field.removeValue(index);
                                  }
                                }}
                              />
                              <Label htmlFor={`allow-${permission}`}>{permission}</Label>
                            </div>
                          )
                        )}
                      </div>
                    </field.FieldSet>
                  );
                }}
              />

              <form.AppField
                name='deny_permissions'
                mode='array'
                children={(field) => {
                  const values = field.state.value ?? [];

                  return (
                    <field.FieldSet>
                      <field.FieldLabel>Deny Permissions</field.FieldLabel>
                      <div className='grid grid-cols-1 gap-3 md:grid-cols-2'>
                        {(selectedTemplate?.permissions ?? detail.effective_permissions).map(
                          (permission) => (
                            <div
                              key={`deny-${permission}`}
                              className='flex items-center gap-3 rounded-md border p-3'
                            >
                              <Checkbox
                                id={`deny-${permission}`}
                                checked={values.includes(permission)}
                                onCheckedChange={(checked) => {
                                  if (checked) {
                                    field.pushValue(permission);
                                    return;
                                  }

                                  const index = values.indexOf(permission);
                                  if (index > -1) {
                                    field.removeValue(index);
                                  }
                                }}
                              />
                              <Label htmlFor={`deny-${permission}`}>{permission}</Label>
                            </div>
                          )
                        )}
                      </div>
                    </field.FieldSet>
                  );
                }}
              />

              <FormTextareaField
                name='reason'
                label='Reason'
                placeholder='ระบุเหตุผลในการเปลี่ยนสิทธิ์'
                rows={2}
              />

              <EffectivePermissionPreview permissions={effectivePermissions} />
            </form.Form>
          </form.AppForm>
        </div>

        <SheetFooter>
          <Button type='button' variant='outline' onClick={() => onOpenChange(false)}>
            Cancel
          </Button>
          <Button type='submit' form='user-permission-form' isLoading={saveMutation.isPending}>
            Save Assignment
          </Button>
        </SheetFooter>
      </SheetContent>
    </Sheet>
  );
}
