import { useEffect, useMemo, useRef, useState } from 'react';
import {
  Box,
  Button,
  Center,
  Group,
  Paper,
  Stack,
  Text,
  Title,
  rem,
} from '@mantine/core';
import {
  IconArrowLeft,
  IconArrowRight,
  IconCheck,
  IconCircleCheck,
  IconLogout2,
  IconMapPin,
  IconUser,
} from '@tabler/icons-react';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { useNavigate } from 'react-router-dom';
import { useApiMutation } from '@ema-platform/api';
import { notify } from '@ema-platform/ui';
import { authStorage, setUser, logout } from '@ema-platform/auth';
import { useAppDispatch, useAppSelector } from '../../../store/hooks';
import {
  ProfileFormContent,
  profileSchema,
  type ProfileValues,
} from '../../profile/components/ProfileFormContent';
import {
  AddressFormContent,
  addressSchema,
  type AddressValues,
} from '../../profile/components/AddressFormContent';

const STEPS = [
  { label: 'Profile', icon: IconUser },
  { label: 'Address', icon: IconMapPin },
];

function StepIndicator({ active, completed }: { active: number; completed: number[] }) {
  return (
    <Box mb={32}>
      <Group gap={0} align="center" wrap="nowrap">
        {STEPS.map((step, i) => {
          const isDone = completed.includes(i);
          const isCurrent = active === i;
          return (
            <Group key={i} gap={0} align="center" style={{ flex: i < STEPS.length - 1 ? 1 : 'none' }}>
              <Stack gap={4} align="center" style={{ minWidth: rem(40) }}>
                <Box
                  style={{
                    width: rem(40),
                    height: rem(40),
                    borderRadius: '50%',
                    display: 'flex',
                    alignItems: 'center',
                    justifyContent: 'center',
                    backgroundColor: isDone
                      ? 'var(--mantine-color-blue-8)'
                      : isCurrent
                      ? 'var(--mantine-color-blue-7)'
                      : 'var(--mantine-color-gray-1)',
                    border: isCurrent ? '2.5px solid var(--mantine-color-blue-5)' : '2px solid transparent',
                    boxShadow: isCurrent || isDone ? '0 2px 8px rgba(34, 139, 230, 0.2)' : 'none',
                    flexShrink: 0,
                    transition: 'all 0.2s ease',
                  }}
                >
                  {isDone ? (
                    <IconCheck size={18} color="white" stroke={2.5} />
                  ) : (
                    <Text fw={700} fz="sm" c={isCurrent ? 'white' : 'gray.5'}>
                      {i + 1}
                    </Text>
                  )}
                </Box>
                <Text
                  fz="xs"
                  fw={isCurrent ? 700 : 400}
                  c={isCurrent ? 'blue.7' : 'dimmed'}
                  style={{ whiteSpace: 'nowrap' }}
                >
                  {step.label}
                </Text>
              </Stack>

              {i < STEPS.length - 1 && (
                <Box
                  style={{
                    flex: 1,
                    height: rem(2),
                    backgroundColor: isDone
                      ? 'var(--mantine-color-blue-8)'
                      : 'var(--mantine-color-gray-2)',
                    marginBottom: rem(22),
                  }}
                />
              )}
            </Group>
          );
        })}
      </Group>
    </Box>
  );
}

function inferUserType(professionName: string): string {
  const name = professionName.toLowerCase();
  if (name.includes('seafarer')) return 'SEAFARER';
  return 'EMPLOYEE';
}

export function ProfileSetupPage() {
  const navigate = useNavigate();
  const dispatch = useAppDispatch();
  const user = useAppSelector((state) => state.auth.user);
  const [active, setActive] = useState(0);
  const [completed, setCompleted] = useState<number[]>([]);
  const [submitting, setSubmitting] = useState(false);
  const [professions, setProfessions] = useState<Array<{ id: string; name: { en: string } }>>([]);
  const [professionsLoading, setProfessionsLoading] = useState(true);
  const [profileTrigger] = useApiMutation<{ id: string }>();
  const [addressTrigger] = useApiMutation<unknown>();
  const [meTrigger] = useApiMutation<{ id: string }>();
  const [profileCheckTrigger] = useApiMutation<{ total: number; items: Array<{ id: string; user: { id: string }; isComplete: boolean }> }>();
  const [fetchProfessions] = useApiMutation<{ count: number; items: Array<{ id: string; name: { en: string } }> }>();
  const fetched = useRef(false);

  const checkedExistingProfile = useRef(false);

  useEffect(() => {
    if (fetched.current) return;
    fetched.current = true;
    fetchProfessions({ url: '/professions?take=100', method: 'GET' })
      .unwrap()
      .then((data) => setProfessions(data.items ?? []))
      .catch(() => setProfessions([]))
      .finally(() => setProfessionsLoading(false));
  }, [fetchProfessions]);

  useEffect(() => {
    if (!user || checkedExistingProfile.current) return;
    checkedExistingProfile.current = true;
    profileCheckTrigger({ url: `/profiles?q=${encodeURIComponent('i=user')}`, method: 'GET' })
      .unwrap()
      .then((data) => {
        const existing = data.items?.find((p) => p.user?.id === user.id);
        if (existing?.isComplete) {
          authStorage.setProfileId(existing.id);
          navigate('/dashboard', { replace: true });
        }
      })
      .catch(() => {});
  }, [user, navigate, profileCheckTrigger]);

  const professionOptions = useMemo(
    () => professions.map((p) => ({ value: p.id, label: p.name.en })),
    [professions],
  );

  const professionNameMap = useMemo(() => {
    const map: Record<string, string> = {};
    professions.forEach((p) => {
      map[p.id] = p.name.en;
    });
    return map;
  }, [professions]);

  const nameParts = useMemo(() => (user?.name?.en || '').trim().split(/\s+/), [user]);
  const profileDefaults: ProfileValues = useMemo(() => ({
    professionId: '',
    firstName: nameParts[0] || '',
    middleName: nameParts.length > 2 ? nameParts.slice(1, -1).join(' ') : '',
    lastName: nameParts.length > 1 ? nameParts[nameParts.length - 1] : '',
    gender: '',
    dob: '',
    pob: '',
    maritalStatus: '',
  }), [nameParts]);

  const addressDefaults: AddressValues = useMemo(() => ({
    idType: '',
    idNumber: '',
    nationality: '',
    primaryPhoneNumber: user?.phoneNumber || '',
    secondaryPhoneNumber: '',
    email: user?.email || '',
    regionId: '',
    cityId: '',
    subcityId: '',
    woredaId: '',
    kebeleId: '',
    streetAddress: '',
    postalAddress: '',
    emergencyContactName: '',
    emergencyContactPhone: '',
    emergencyContactRelation: '',
  }), [user]);

  const {
    register: profileRegister,
    handleSubmit: profileHandleSubmit,
    formState: { errors: profileErrors },
    setValue: profileSetValue,
    watch: profileWatch,
    trigger: profileTriggerValidation,
  } = useForm<ProfileValues>({
    resolver: zodResolver(profileSchema),
    defaultValues: profileDefaults,
  });

  const {
    register: addressRegister,
    handleSubmit: addressHandleSubmit,
    formState: { errors: addressErrors },
    setValue: addressSetValue,
    watch: addressWatch,
    trigger: addressTriggerValidation,
  } = useForm<AddressValues>({
    resolver: zodResolver(addressSchema),
    defaultValues: addressDefaults,
  });

  const onNext = async () => {
    const valid = await profileTriggerValidation();
    if (!valid) return;
    setCompleted((prev) => (prev.includes(active) ? prev : [...prev, active]));
    setActive((c) => c + 1);
  };

  const onSubmitAddress = async () => {
    const valid = await addressTriggerValidation();
    if (!valid) return;

    setSubmitting(true);
    try {
      const pv = profileWatch();
      const av = addressWatch();
      const selectedProfessionName = professionNameMap[pv.professionId] ?? '';

      const profileResult = await profileTrigger({
        url: '/profiles',
        method: 'POST',
        body: {
          userId: user?.id,
          type: inferUserType(selectedProfessionName),
          professionId: pv.professionId,
          firstName: pv.firstName,
          middleName: pv.middleName,
          lastName: pv.lastName,
          gender: pv.gender,
          dob: pv.dob,
          pob: pv.pob || undefined,
          maritalStatus: pv.maritalStatus,
        },
      }).unwrap();

      await profileTrigger({
        url: `/profiles/${profileResult.id}`,
        method: 'PUT',
        body: { isComplete: true },
      }).unwrap();
      authStorage.setProfileId(profileResult.id);

      await addressTrigger({
        url: `/addresss/profile/${profileResult.id}`,
        method: 'POST',
        body: {
          idType: av.idType,
          idNumber: av.idNumber,
          nationality: av.nationality,
          primaryPhoneNumber: av.primaryPhoneNumber,
          secondaryPhoneNumber: av.secondaryPhoneNumber || undefined,
          email: av.email || undefined,
          regionId: av.regionId || undefined,
          cityId: av.cityId || undefined,
          subcityId: av.subcityId || undefined,
          woredaId: av.woredaId || undefined,
          kebeleId: av.kebeleId || undefined,
          streetAddress: av.streetAddress || undefined,
          postalAddess: av.postalAddress || undefined,
          emergencyContactName: av.emergencyContactName || undefined,
          emergencyContactPhone: av.emergencyContactPhone || undefined,
          emergencyContactRelation: av.emergencyContactRelation || undefined,
        },
      }).unwrap();

      const me = await meTrigger({ url: '/auth/me', method: 'GET' }).unwrap();
      dispatch(setUser(me));

      notify.success('Profile setup complete!');
      navigate('/dashboard');
    } catch {
      notify.error('Failed to save profile. Please try again.');
    } finally {
      setSubmitting(false);
    }
  };

  if (!user) {
    return (
      <Center mih="100vh">
        <Text c="dimmed">Please log in first.</Text>
      </Center>
    );
  }

  return (
    <Center mih="100vh" bg="gray.0">
      <Paper withBorder radius="lg" p="xl" maw={900} w="100%" mx="md">
        <Stack gap="md">
          <div>
            <Title order={3}>Complete Your Profile</Title>
            <Text fz="sm" c="dimmed">
              Set up your profile and address to get started
            </Text>
          </div>

          <StepIndicator active={active} completed={completed} />

          {active === 0 && (
            <>
              <Text fw={600} fz="sm" tt="uppercase" c="gray.6" mb="sm">
                Personal Information
              </Text>
              <ProfileFormContent
                register={profileRegister}
                errors={profileErrors}
                setValue={profileSetValue}
                watch={profileWatch}
                trigger={profileTriggerValidation}
                professionsLoading={professionsLoading}
                professionOptions={professionOptions}
              />
            </>
          )}

          {active === 1 && (
            <>
              <Text fw={600} fz="sm" tt="uppercase" c="gray.6" mb="sm">
                Identity & Contact
              </Text>
              <AddressFormContent
                register={addressRegister}
                errors={addressErrors}
                setValue={addressSetValue}
                watch={addressWatch}
                trigger={addressTriggerValidation}
              />
            </>
          )}

          <Group justify="space-between" mt="xl">
            <Button
              variant="default"
              color="gray"
              leftSection={<IconLogout2 size={16} />}
              onClick={() => {
                dispatch(logout());
                navigate('/login');
              }}
            >
              Sign out
            </Button>
            <Group gap="sm">
              {active > 0 && (
                <Button
                  variant="default"
                  leftSection={<IconArrowLeft size={16} />}
                  onClick={() => setActive((c) => c - 1)}
                >
                  Previous
                </Button>
              )}
              {active < STEPS.length - 1 ? (
                <Button rightSection={<IconArrowRight size={16} />} onClick={onNext}>
                  Next Step
                </Button>
              ) : (
                <Button
                  color="blue"
                  leftSection={<IconCircleCheck size={16} />}
                  onClick={onSubmitAddress}
                  loading={submitting}
                >
                  Complete Setup
                </Button>
              )}
            </Group>
          </Group>
        </Stack>
      </Paper>
    </Center>
  );
}
