'use client';

import { useEffect, useMemo, useState } from 'react';
import { useAppForm, useFormFields } from '@/components/ui/tanstack-form';
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue
} from '@/components/ui/select';
import {
  Sheet,
  SheetContent,
  SheetDescription,
  SheetFooter,
  SheetHeader,
  SheetTitle
} from '@/components/ui/sheet';
import { Icons } from '@/components/icons';
import { useMutation } from '@tanstack/react-query';
import { createUserMutation, updateUserMutation } from '../api/mutations';
import type { User } from '../api/types';
import { toast } from 'sonner';
import { type UserFormValues, userSchema } from '../schemas/user';
import type { BusinessRole } from '@/lib/auth/rbac';

interface UserFormSheetProps {
  user?: User;
  open: boolean;
  onOpenChange: (open: boolean) => void;
}

type OrganizationOption = {
  id: string;
  name: string;
  role: string;
  businessRole?: string;
  canManageUsers: boolean;
};

const membershipRoleOptions = [
  { value: 'admin', label: 'Organization Admin' },
  { value: 'user', label: 'User' }
] as const;

const businessRoleOptions = [
  { value: 'marketing', label: 'Marketing' },
  { value: 'sales_manager', label: 'Sales Manager' },
  { value: 'sales', label: 'Sales' },
  { value: 'sales_support', label: 'Sales Support' },
  { value: 'department_manager', label: 'Department Manager' },
  { value: 'top_manager', label: 'Top Manager' }
] as const;

export function UserFormSheet({ user, open, onOpenChange }: UserFormSheetProps) {
  const isEdit = !!user;
  const [organizations, setOrganizations] = useState<OrganizationOption[]>([]);
  const [isLoadingOrganizations, setIsLoadingOrganizations] = useState(false);

  const createMutation = useMutation({
    ...createUserMutation,
    onSuccess: () => {
      toast.success('User created successfully');
      onOpenChange(false);
      form.reset();
    },
    onError: (error) =>
      toast.error(error instanceof Error ? error.message : 'Failed to create user')
  });

  const updateMutation = useMutation({
    ...updateUserMutation,
    onSuccess: () => {
      toast.success('User updated successfully');
      onOpenChange(false);
    },
    onError: (error) =>
      toast.error(error instanceof Error ? error.message : 'Failed to update user')
  });

  const initialMemberships = useMemo(
    () =>
      user?.memberships.map((membership) => ({
        organizationId: membership.organizationId,
        membershipRole: membership.membershipRole,
        businessRole: membership.businessRole
      })) ?? [],
    [user?.memberships]
  );

  const form = useAppForm({
    defaultValues: {
      name: user?.name ?? '',
      email: user?.email ?? '',
      password: '',
      systemRole: user?.systemRole ?? 'user',
      memberships: initialMemberships
    } as UserFormValues,
    validators: {
      onSubmit: userSchema
    },
    onSubmit: async ({ value }) => {
      if (!isEdit && (!value.password || value.password.length < 8)) {
        toast.error('Password must be at least 8 characters');
        return;
      }

      if (isEdit) {
        await updateMutation.mutateAsync({ id: user.id, values: value });
      } else {
        await createMutation.mutateAsync({
          ...value,
          systemRole: 'user'
        });
      }
    }
  });

  const { FormTextField } = useFormFields<UserFormValues>();

  useEffect(() => {
    if (!open) {
      return;
    }

    let cancelled = false;

    async function loadOrganizations() {
      setIsLoadingOrganizations(true);

      try {
        const response = await fetch('/api/organizations?scope=manageable');
        const data = (await response.json()) as {
          organizations?: OrganizationOption[];
          message?: string;
        };

        if (!response.ok) {
          throw new Error(data.message ?? 'Unable to load organizations');
        }

        if (!cancelled) {
          setOrganizations(data.organizations ?? []);
        }
      } catch (error) {
        if (!cancelled) {
          toast.error(error instanceof Error ? error.message : 'Unable to load organizations');
        }
      } finally {
        if (!cancelled) {
          setIsLoadingOrganizations(false);
        }
      }
    }

    void loadOrganizations();

    return () => {
      cancelled = true;
    };
  }, [open]);

  const isPending = createMutation.isPending || updateMutation.isPending;

  return (
    <Sheet open={open} onOpenChange={onOpenChange}>
      <SheetContent className='flex flex-col sm:max-w-2xl'>
        <SheetHeader>
          <SheetTitle>{isEdit ? 'Edit User' : 'New User'}</SheetTitle>
          <SheetDescription>
            {isEdit
              ? 'Update the user details and workspace memberships below.'
              : 'Create a user account and assign workspace-specific roles.'}
          </SheetDescription>
        </SheetHeader>

        <div className='flex-1 overflow-auto'>
          <form.AppForm>
            <form.Form id='user-form-sheet' className='space-y-4'>
              <FormTextField name='name' label='Full Name' required placeholder='Jane Doe' />

              <FormTextField
                name='email'
                label='Email'
                required
                type='email'
                placeholder='jane@example.com'
              />

              <FormTextField
                name='password'
                label={isEdit ? 'Password (optional)' : 'Password'}
                required={!isEdit}
                type='password'
                placeholder={
                  isEdit ? 'Leave blank to keep current password' : 'Minimum 8 characters'
                }
              />

              {isEdit && user?.systemRole === 'super_admin' && (
                <div className='rounded-lg border border-dashed p-3 text-sm'>
                  <span className='font-medium'>System Role:</span> Super Admin
                </div>
              )}

              {!isEdit && (
                <div className='text-muted-foreground rounded-lg border border-dashed p-3 text-sm'>
                  New users are created with system role <strong>user</strong>. Creating new
                  <strong> super_admin</strong> users is intentionally not exposed in this form.
                </div>
              )}

              <form.AppField
                name='memberships'
                children={(field) => (
                  <field.FieldSet>
                    <field.Field>
                      <div className='text-sm font-medium'>Workspace Memberships *</div>
                      <div className='text-muted-foreground text-xs'>
                        One user can have different roles in different workspaces.
                      </div>
                      <div className='space-y-2 rounded-lg border p-3'>
                        {isLoadingOrganizations ? (
                          <div className='text-muted-foreground text-sm'>Loading workspaces...</div>
                        ) : organizations.length ? (
                          organizations.map((organization) => {
                            const membership = field.state.value.find(
                              (value) => value.organizationId === organization.id
                            );
                            const checked = !!membership;

                            return (
                              <div
                                key={organization.id}
                                className='grid gap-3 rounded-md border p-3 md:grid-cols-[1fr_180px_180px]'
                              >
                                <div className='flex items-start gap-3'>
                                  <Checkbox
                                    aria-label={`Select workspace ${organization.name}`}
                                    checked={checked}
                                    onCheckedChange={(value) => {
                                      if (!value) {
                                        field.handleChange(
                                          field.state.value.filter(
                                            (item) => item.organizationId !== organization.id
                                          )
                                        );
                                        field.handleBlur();
                                        return;
                                      }

                                      field.handleChange([
                                        ...field.state.value,
                                        {
                                          organizationId: organization.id,
                                          membershipRole: 'user',
                                          businessRole: 'sales_support'
                                        }
                                      ]);
                                      field.handleBlur();
                                    }}
                                  />
                                  <div className='flex flex-col'>
                                    <span className='font-medium'>{organization.name}</span>
                                    <span className='text-muted-foreground text-xs'>
                                      Your role here: {organization.role}
                                    </span>
                                  </div>
                                </div>

                                <Select
                                  value={membership?.membershipRole ?? 'user'}
                                  disabled={!checked}
                                  onValueChange={(value) => {
                                    field.handleChange(
                                      field.state.value.map((item) =>
                                        item.organizationId === organization.id
                                          ? {
                                              ...item,
                                              membershipRole: value as 'admin' | 'user'
                                            }
                                          : item
                                      )
                                    );
                                    field.handleBlur();
                                  }}
                                >
                                  <SelectTrigger aria-label={`Role for ${organization.name}`}>
                                    <SelectValue placeholder='Select role' />
                                  </SelectTrigger>
                                  <SelectContent>
                                    {membershipRoleOptions.map((option) => (
                                      <SelectItem key={option.value} value={option.value}>
                                        {option.label}
                                      </SelectItem>
                                    ))}
                                  </SelectContent>
                                </Select>

                                <Select
                                  value={membership?.businessRole ?? 'sales_support'}
                                  disabled={!checked}
                                  onValueChange={(value) => {
                                    field.handleChange(
                                      field.state.value.map((item) =>
                                        item.organizationId === organization.id
                                          ? {
                                              ...item,
                                              businessRole: value as BusinessRole
                                            }
                                          : item
                                      )
                                    );
                                    field.handleBlur();
                                  }}
                                >
                                  <SelectTrigger
                                    aria-label={`Business role for ${organization.name}`}
                                  >
                                    <SelectValue placeholder='Select business role' />
                                  </SelectTrigger>
                                  <SelectContent>
                                    {businessRoleOptions.map((option) => (
                                      <SelectItem key={option.value} value={option.value}>
                                        {option.label}
                                      </SelectItem>
                                    ))}
                                  </SelectContent>
                                </Select>
                              </div>
                            );
                          })
                        ) : (
                          <div className='text-muted-foreground text-sm'>
                            No manageable workspaces available.
                          </div>
                        )}
                      </div>
                    </field.Field>
                    <field.FieldError />
                  </field.FieldSet>
                )}
              />
            </form.Form>
          </form.AppForm>
        </div>

        <SheetFooter>
          <Button type='button' variant='outline' onClick={() => onOpenChange(false)}>
            Cancel
          </Button>
          <Button
            type='submit'
            form='user-form-sheet'
            isLoading={isPending}
            disabled={isLoadingOrganizations || organizations.length === 0}
          >
            <Icons.check /> {isEdit ? 'Update User' : 'Create User'}
          </Button>
        </SheetFooter>
      </SheetContent>
    </Sheet>
  );
}

export function UserFormSheetTrigger() {
  const [open, setOpen] = useState(false);

  return (
    <>
      <Button onClick={() => setOpen(true)}>
        <Icons.add className='mr-2 h-4 w-4' /> Add User
      </Button>
      <UserFormSheet open={open} onOpenChange={setOpen} />
    </>
  );
}
