'use client';

import { useEffect } from 'react';
import { useParams, useRouter } from 'next/navigation';
import {
  addUsers,
  fetchUserById,
  updateUsers,
} from '@/network/apis/dashboard/userManagment/users/users.apis';
import { getCountries } from '@/network/apis/shared/countries/countries';
import { CountryProps } from '@/network/apis/shared/countries/type';
import { assignRoleToUser } from '@/modules/Roles/apis/roles.apis';
import { zodResolver } from '@hookform/resolvers/zod';
import { RiCheckboxCircleFill, RiErrorWarningFill } from '@remixicon/react';
import { useMutation, useQuery } from '@tanstack/react-query';
import { useForm } from 'react-hook-form';
import { toast } from 'sonner';
import { Alert, AlertIcon, AlertTitle } from '@/components/ui/alert';
import { ArrowLeft } from 'lucide-react';
import { Button } from '@/components/ui/button';
import {
  Card,
  CardContent,
  CardHeader,
  CardTitle,
} from '@/components/ui/card';
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from '@/components/ui/form';
import { Input } from '@/components/ui/input';
import {
  Select,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import { Spinner } from '@/components/ui/spinners';
import { Switch } from '@/components/ui/switch';
import { SelectRole } from '@/modules/users/components/SelectRole';
import { useRoles } from '@/modules/users/hooks/useRoles';
import { UserAddSchema, UserAddSchemaType } from './user-add-schema';

const UserAdd = () => {
  const router = useRouter();
  const params = useParams();
  const id = params?.slug?.[0] ? Number(params?.slug?.[0]) : undefined;
  const isEdit = !!id;

  const ACCOUNT_TYPES = [
    { label: 'Admin', value: 1 },
    { label: 'Brand', value: 2 },
    { label: 'Influencer', value: 3 },
  ];

  const { data: countries } = useQuery({
    queryKey: ['countries'],
    queryFn: getCountries,
    enabled: true,
    select: (data) => data?.data,
  });

  const { data: rolesData } = useRoles();

  const { data: userDetails } = useQuery({
    queryKey: ['user_details', id],
    queryFn: async () => {
      if (id === undefined) return;
      const response = await fetchUserById(id?.toString());
      return response;
    },
    enabled: isEdit,
  });

  const form = useForm<UserAddSchemaType>({
    resolver: zodResolver(UserAddSchema),
    defaultValues: {
      first_name: '',
      last_name: '',
      brand_name: '',
      phone: '',
      country_id: undefined as unknown as number,
      account_type_id: undefined as unknown as number,
      role_id: undefined as unknown as number,
      email: '',
      password: undefined,
      password_confirmation: undefined,
      is_activated: 1, // 0 | 1
    },
    mode: 'onSubmit',
  });

  useEffect(() => {
    if (userDetails && Object.keys(userDetails).length && rolesData) {
      // Get the first role's name if user has roles, then find matching role ID
      const userRoleName = userDetails.roles?.[0]?.name;
      const matchingRole = rolesData.find(
        (role) => role.name === userRoleName,
      );

      form.reset({
        first_name: userDetails.first_name ?? '',
        last_name: userDetails.last_name ?? '',
        brand_name: userDetails.brand_name ?? '',
        phone: userDetails.phone ?? '',
        country_id: Number(userDetails.country?.id ?? 0),
        account_type_id: Number(userDetails.account_type_id ?? 0),
        role_id: matchingRole?.id ?? (undefined as unknown as number),
        email: userDetails.email ?? '',
        password: undefined,
        password_confirmation: undefined,
        is_activated: userDetails.is_activated ? 1 : 0,
      });
    }
  }, [userDetails, rolesData, form]);

  const mutation = useMutation({
    mutationFn: async (values: UserAddSchemaType) => {
      const fd = new FormData();
      fd.append('first_name', values.first_name);
      fd.append('last_name', values.last_name);
      fd.append('brand_name', values?.brand_name ?? '');
      fd.append('phone', values.phone);
      fd.append('country_id', String(values.country_id));
      fd.append('account_type_id', String(values.account_type_id));
      fd.append('email', values.email);
      if (values.password) fd.append('password', values.password);
      if (values.password_confirmation) {
        fd.append('password_confirmation', values.password_confirmation);
      }
      fd.append('is_activated', String(values.is_activated));

      if (isEdit) {
        await updateUsers(fd, id?.toString());
        // For edit mode, assign role to the existing user
        const selectedRole = rolesData?.find(
          (role) => role.id === values.role_id,
        );
        if (selectedRole && id) {
          await assignRoleToUser(id.toString(), selectedRole.name);
        }
      } else {
        // Create new user
        const createdUser = await addUsers(fd);

        // Assign role to the newly created user
        const selectedRole = rolesData?.find(
          (role) => role.id === values.role_id,
        );

        // Get the user ID from the response
        const userId = Array.isArray(createdUser)
          ? createdUser[0]?.id
          : (createdUser as any)?.id;

        if (selectedRole && userId) {
          await assignRoleToUser(String(userId), selectedRole.name);
        }
      }
    },
    onSuccess: () => {
      const message = isEdit
        ? 'User updated successfully'
        : 'User added successfully';
      toast.custom(
        () => (
          <Alert variant="mono" icon="success" close={false}>
            <AlertIcon>
              <RiCheckboxCircleFill />
            </AlertIcon>
            <AlertTitle>{message}</AlertTitle>
          </Alert>
        ),
        { position: 'top-center' },
      );
      router.push('/users');
    },
    onError: (error: any) => {
      // Extract the error message from the backend response
      const errorMessage = error?.response?.data?.message || error?.message || 'Failed to save user';

      // Set field-specific errors if they exist
      if (error?.response?.data?.errors) {
        const fieldErrors = error.response.data.errors;
        Object.keys(fieldErrors).forEach((fieldName) => {
          const errorMessages = fieldErrors[fieldName];
          if (Array.isArray(errorMessages) && errorMessages.length > 0) {
            form.setError(fieldName as any, {
              type: 'manual',
              message: errorMessages[0],
            });
          }
        });
      }

      // Show toast with the backend error message
      toast.custom(
        () => (
          <Alert variant="mono" icon="destructive" close={false}>
            <AlertIcon>
              <RiErrorWarningFill />
            </AlertIcon>
            <AlertTitle>{errorMessage}</AlertTitle>
          </Alert>
        ),
        { position: 'top-center' },
      );
    },
  });

  const isProcessing = mutation.status === 'pending';

  const handleSubmit = (values: UserAddSchemaType) => {
    mutation.mutate(values);
  };

  return (
    <div className="container mx-auto py-6 max-w-3xl">
      <Form {...form}>
        <form className="w-full space-y-5" onSubmit={form.handleSubmit(handleSubmit)}>
          {/* Header */}
          <div className="flex items-center justify-between gap-3">
            <div className="flex items-center gap-2">
              <Button type="button" variant="ghost" size="sm" onClick={() => router.push('/users')}>
                <ArrowLeft className="size-4 mr-1.5" /> Back
              </Button>
              <h1 className="text-2xl font-semibold">{isEdit ? 'Update user' : 'Create user'}</h1>
            </div>
            <FormField
              control={form.control}
              name="is_activated"
              render={({ field }) => (
                <FormItem className="flex items-center gap-2 space-y-0">
                  <FormLabel htmlFor="is_activated" className="text-sm">
                    {field.value === 1 ? 'Active' : 'Inactive'}
                  </FormLabel>
                  <FormControl>
                    <Switch
                      id="is_activated"
                      checked={field.value === 1}
                      onCheckedChange={(checked) => field.onChange(checked ? 1 : 0)}
                    />
                  </FormControl>
                </FormItem>
              )}
            />
          </div>

          {/* Identity */}
          <Card>
            <CardHeader><CardTitle className="text-base">Identity</CardTitle></CardHeader>
            <CardContent className="grid grid-cols-1 sm:grid-cols-2 gap-4 pt-0">
              <FormField control={form.control} name="first_name" render={({ field }) => (
                <FormItem><FormLabel>First Name</FormLabel><FormControl><Input placeholder="Enter first name" {...field} /></FormControl><FormMessage /></FormItem>
              )} />
              <FormField control={form.control} name="last_name" render={({ field }) => (
                <FormItem><FormLabel>Last Name</FormLabel><FormControl><Input placeholder="Enter last name" {...field} /></FormControl><FormMessage /></FormItem>
              )} />
              <FormField control={form.control} name="country_id" render={({ field }) => (
                <FormItem>
                  <FormLabel>Country</FormLabel>
                  <FormControl>
                    <Select onValueChange={(value) => field.onChange(Number(value))} value={field.value ? field.value.toString() : ''}>
                      <SelectTrigger><SelectValue placeholder="Select Country" /></SelectTrigger>
                      <SelectContent>
                        <SelectGroup>
                          {countries?.data?.map((country: CountryProps) => (
                            <SelectItem key={country.id} value={`${country.id}`}>{country.name}</SelectItem>
                          ))}
                        </SelectGroup>
                      </SelectContent>
                    </Select>
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )} />
              <FormField control={form.control} name="phone" render={({ field }) => (
                <FormItem><FormLabel>Phone</FormLabel><FormControl><Input placeholder="Enter phone" {...field} /></FormControl><FormMessage /></FormItem>
              )} />
            </CardContent>
          </Card>

          {/* Account & access */}
          <Card>
            <CardHeader><CardTitle className="text-base">Account &amp; access</CardTitle></CardHeader>
            <CardContent className="grid grid-cols-1 sm:grid-cols-2 gap-4 pt-0">
              <FormField control={form.control} name="account_type_id" render={({ field }) => (
                <FormItem>
                  <FormLabel>Account Type</FormLabel>
                  <FormControl>
                    <Select onValueChange={(val) => field.onChange(Number(val))} value={field.value ? String(field.value) : ''}>
                      <SelectTrigger><SelectValue placeholder="Select account type" /></SelectTrigger>
                      <SelectContent>
                        {ACCOUNT_TYPES.map((opt) => (
                          <SelectItem key={opt.value} value={String(opt.value)}>{opt.label}</SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )} />
              {form.watch('account_type_id') === 2 ? (
                <FormField control={form.control} name="brand_name" render={({ field }) => (
                  <FormItem><FormLabel>Brand Name</FormLabel><FormControl><Input placeholder="Enter brand name" {...field} /></FormControl><FormMessage /></FormItem>
                )} />
              ) : <div className="hidden sm:block" />}
              <FormField control={form.control} name="role_id" render={({ field }) => (
                <FormItem>
                  <FormLabel>Role</FormLabel>
                  <FormControl>
                    <SelectRole value={field.value ? field.value.toString() : ''} onValueChange={(value) => field.onChange(Number(value))} onBlur={field.onBlur} placeholder="Select a role" />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )} />
              <FormField control={form.control} name="email" render={({ field }) => (
                <FormItem><FormLabel>Email</FormLabel><FormControl><Input placeholder="Enter email" {...field} /></FormControl><FormMessage /></FormItem>
              )} />
            </CardContent>
          </Card>

          {/* Security */}
          <Card>
            <CardHeader><CardTitle className="text-base">Security</CardTitle></CardHeader>
            <CardContent className="grid grid-cols-1 sm:grid-cols-2 gap-4 pt-0">
              <FormField control={form.control} name="password" render={({ field }) => (
                <FormItem><FormLabel>Password {isEdit ? '(optional)' : ''}</FormLabel><FormControl><Input type="password" placeholder="Enter password" {...field} /></FormControl><FormMessage /></FormItem>
              )} />
              <FormField control={form.control} name="password_confirmation" render={({ field }) => (
                <FormItem><FormLabel>Confirm Password {isEdit ? '(optional)' : ''}</FormLabel><FormControl><Input type="password" placeholder="Confirm password" {...field} /></FormControl><FormMessage /></FormItem>
              )} />
            </CardContent>
          </Card>

          <div className="flex justify-end gap-3">
            <Button type="button" variant="outline" onClick={() => router.push('/users')}>Cancel</Button>
            <Button type="submit" disabled={isProcessing}>
              {isProcessing && <Spinner className="size-4 animate-spin mr-1.5" />}
              {isEdit ? 'Update' : 'Add'}
            </Button>
          </div>
        </form>
      </Form>
    </div>
  );
};

export default UserAdd;
