import { useMemo } from "react";
import BooleanToggle from "@/components/BooleanToggle";
import type { AccessScope } from "@/lib/features/types";
import { useCoreFetcher } from "@/lib/features/useCoreFetcher";
import type { AdminRole } from "@/lib/features/users/roles/types";
import type { AdminUserDetailed } from "@/lib/features/users/types";
import {
  Button,
  Flex,
  Grid,
  MultiSelect,
  PasswordInput,
  Stack,
  TextInput,
  Title,
} from "@mantine/core";
import { useForm } from "@mantine/form";
import { zod4Resolver } from "mantine-form-zod-resolver";
import { toast } from "sonner";
import z from "zod";

const baseSchema = z.object({
  firstName: z.string().min(2, { error: "First name is required" }),
  lastName: z.string().min(2, { error: "Last name is required" }),
  email: z.email({ error: "Email is required" }),
  username: z
    .string({ error: "Username is required." })
    .min(4, { error: "Minimum 4 chars required" }),
  roleIds: z.array(z.string()).optional(),
  isSuperAdmin: z.boolean(),
  isActive: z.boolean(),
});

const createSchema = baseSchema
  .extend({
    password: z.string().max(16).optional().or(z.literal("")),
    confirmPassword: z.string().optional().or(z.literal("")),
  })
  .refine((data) => !data.password || data.password === data.confirmPassword, {
    message: "Passwords do not match",
    path: ["confirmPassword"],
  });

const editSchema = baseSchema
  .extend({
    password: z.string().max(16).optional().or(z.literal("")),
    confirmPassword: z.string().optional().or(z.literal("")),
  })
  .refine((data) => !data.password || data.password === data.confirmPassword, {
    message: "Passwords do not match",
    path: ["confirmPassword"],
  });

type SchemaType = z.infer<typeof createSchema>;

const AdminUserFormBlock: React.FC<{
  adminUser?: AdminUserDetailed;
  adminRoles: AdminRole[];
  accessScope: AccessScope;
}> = ({ adminUser, adminRoles, accessScope }) => {
  const schema = adminUser ? editSchema : createSchema;

  const roleOptions = useMemo(() => {
    const map = new Map<string, string>();
    for (const r of adminRoles || []) {
      if (r?.id && r?.name) map.set(r.id, r.name);
    }
    if (adminUser?.roles) {
      for (const r of adminUser.roles) {
        const id = r.console_role_id || r.id;
        if (id && !map.has(id)) {
          map.set(id, r.name || id);
        }
      }
    }
    return Array.from(map.entries()).map(([value, label]) => ({
      value,
      label,
    }));
  }, [adminRoles, adminUser?.roles]);

  const form = useForm<SchemaType>({
    initialValues: {
      firstName: adminUser?.first_name ?? "",
      lastName: adminUser?.last_name ?? "",
      email: adminUser?.email ?? "",
      confirmPassword: "",
      password: "",
      username: adminUser?.username ?? "",
      roleIds:
        (adminUser?.roles
          ?.map((r) => r.console_role_id || r.id)
          .filter(Boolean) as string[]) ?? [],
      isSuperAdmin: adminUser?.is_super_admin ?? false,
      isActive: adminUser?.is_active ?? true,
    },
    validate: zod4Resolver(schema),
  });
  const { trigger: createTrigger, isLoading: createLoading } = useCoreFetcher(
    "create-admin-user",
    "post",
    {
      onSuccess: () => {
        toast.success("User created successfully");
        form.reset();
      },
      onError: (error) => {
        toast.error((error as Error)?.message ?? "Failed to create user");
      },
    },
  );

  const { trigger: updateTrigger, isLoading: updateLoading } = useCoreFetcher(
    "update-admin-user",
    "put",
    {
      onSuccess: () => {
        toast.success("User updated successfully");
      },
      onError: (error) => {
        toast.error((error as Error)?.message ?? "Failed to updated user");
      },
    },
  );

  const handleSubmit = async () => {
    const result = form.validate();
    if (result.hasErrors) return;

    if (adminUser?.id) {
      await updateTrigger({
        firstName: form.values.firstName,
        lastName: form.values.lastName,
        isSuperAdmin: form.values.isSuperAdmin,
        isActive: form.values.isActive,
        password: form.values.password,
        roles: adminRoles?.length
          ? form.values.roleIds?.map((id) => ({ roleId: id }))
          : adminUser?.roles?.map((role) => ({
              roleId: role.console_role_id,
            })),
      });
    } else {
      const { roleIds, ...restPayload } = form.values;
      await createTrigger({
        ...restPayload,
        roles: roleIds?.map((id) => ({ roleId: id })),
      });
    }
  };

  return (
    <Stack bg={"grey.0"} mih={"100vh"} p={"sm"}>
      <form>
        <Stack gap={20} bg={"white.0"} p={"sm"} bdrs={"sm"}>
          <Title order={6}>User Details</Title>
          <Grid columns={6} gutter={"lg"}>
            <Grid.Col span={3}>
              <TextInput
                label="First Name"
                placeholder="Enter First name"
                key={form.key("firstName")}
                {...form.getInputProps("firstName")}
              />
            </Grid.Col>
            <Grid.Col span={3}>
              <TextInput
                label="Last Name"
                placeholder="Enter Last Name"
                key={form.key("lastName")}
                {...form.getInputProps("lastName")}
              />
            </Grid.Col>
            <Grid.Col span={3}>
              <TextInput
                label="Email"
                placeholder="Enter email"
                key={form.key("email")}
                disabled={!!adminUser}
                {...form.getInputProps("email")}
              />
            </Grid.Col>
            <Grid.Col span={3}>
              <TextInput
                label="Username"
                placeholder="Enter username"
                key={form.key("username")}
                disabled={!!adminUser}
                {...form.getInputProps("username")}
              />
            </Grid.Col>
            <Grid.Col span={3}>
              <PasswordInput
                label="Password"
                placeholder="Enter password"
                key={form.key("password")}
                {...form.getInputProps("password")}
              />
            </Grid.Col>
            <Grid.Col span={3}>
              <PasswordInput
                label="Confirm Password"
                placeholder="Enter Confirm password"
                key={form.key("confirmPassword")}
                {...form.getInputProps("confirmPassword")}
              />
            </Grid.Col>

            {/* {accessScope?.superAdmin && (
              <Grid.Col span={3}>
                <Stack gap={4} justify="flex-end" h="100%" pb={4}>
                  <Switch
                    label={
                      <Text size="md" fw={500} pt={"xs"}>
                        Super Admin
                      </Text>
                    }
                    labelPosition="left"
                    style={{ cursor: "pointer", width: "fit-content" }}
                    checked={form.values.isSuperAdmin}
                    size="xl"
                    key={form.key("isSuperAdmin")}
                    {...form.getInputProps("isSuperAdmin")}
                  />
                </Stack>
              </Grid.Col>
            )} */}
            <Grid.Col span={3}>
              <Flex gap="xl" align="flex-end" h="100%" pb={4}>
                <BooleanToggle
                  label="Status"
                  value={form.values.isActive}
                  onChange={(val) => form.setFieldValue("isActive", val)}
                  onLabel="Active"
                  offLabel="Inactive"
                  listStyle={{ backgroundColor: "#f1f3f5" }}
                  tabStyle={{ padding: "6px 12px" }}
                />
                {accessScope?.superAdmin && (
                  <BooleanToggle
                    label="Super Admin"
                    value={form.values.isSuperAdmin}
                    onChange={(val) => form.setFieldValue("isSuperAdmin", val)}
                    onLabel="True"
                    offLabel="False"
                    listStyle={{ backgroundColor: "#f1f3f5" }}
                    tabStyle={{ padding: "6px 12px" }}
                  />
                )}
              </Flex>
            </Grid.Col>
            {accessScope.superAdmin && (
              <Grid.Col span={3}>
                <MultiSelect
                  label="User Role"
                  placeholder="Select roles"
                  disabled={form.values.isSuperAdmin}
                  data={roleOptions}
                  key={form.key("roleIds")}
                  {...form.getInputProps("roleIds")}
                />
              </Grid.Col>
            )}
          </Grid>
        </Stack>
        <Flex justify={"end"} mt={20}>
          <Button
            variant="filled"
            bg="blue.1"
            c="blue.9"
            loading={createLoading || updateLoading}
            onClick={handleSubmit}
          >
            {adminUser
              ? "Update User"
              : form.values.password
                ? "Create User"
                : "Send Invitation Link"}
          </Button>
        </Flex>
      </form>
    </Stack>
  );
};

export default AdminUserFormBlock;
