import { useMemo } from 'react';
import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import * as Yup from 'yup';
import Card from '@mui/material/Card';
import Stack from '@mui/material/Stack';
import LoadingButton from '@mui/lab/LoadingButton';
import { useRouter } from '@/hooks';
import { useBoolean } from '@/hooks/use-boolean';
import { paths } from '@/routes/paths';
import { useSnackbar } from '@/shared/components/snackbar';
import FormProvider from '@/shared/components/hook-form';
import { IInvoice } from '@/shared/types/invoice';
import { createInvoice } from '@/shared/api/invoice';
import InvoiceNewEditDetails from './invoice-new-edit-details';
import InvoiceNewAddAddress from './invoice-new-add-address';
import InvoiceNewEditStatusDate from './invoice-new-edit-status-date';
import { generateToken } from '@/utils/firebase';
import { INotif } from '@/shared/types/notif';
import { sendNotificationToUserAfterInvoiceCreation } from '@/shared/api/notif';

type Props = {
  currentInvoice?: IInvoice;
};

export default function InvoiceNewAddForm({ currentInvoice }: Props) {
  const router = useRouter();
  const { enqueueSnackbar } = useSnackbar();
  const loadingSave = useBoolean();
  const loadingSend = useBoolean();

  const NewInvoiceSchema = Yup.object().shape({
    invoiceClient: Yup.mixed<any>().nullable().required('Invoice to is required'),
    dueDate: Yup.mixed<any>()
      .required('Due date is required')
      .test('date-min', 'Due date must be later than create date', (value, { parent }) => 
        value.getTime() > new Date().getTime()
      ),
    productLine: Yup.array().of(
      Yup.object().shape({
        title: Yup.string().required('Title is required'),
        description: Yup.string(),
        price: Yup.number(),
        total: Yup.number(),
        quantity: Yup.number().required('Quantity is required').min(1, 'Quantity must be more than 0'),
      })
    ),
    devise: Yup.string().required('Devise is required'),
    paymentMode: Yup.object().shape({
      id: Yup.string(),
      name: Yup.string().required('Payment mode name is required'),
    }).required('Payment mode is required'),
    notes: Yup.string(),
    taxes: Yup.number(),
    status: Yup.string(),
    invoiceIssuer: Yup.number(),
    agencyId: Yup.number().nullable(),
    totalAmount: Yup.number(),
    invoiceNumber: Yup.string(),
    signatureUrl: Yup.string().nullable(),
    signatureUrlS3: Yup.string().nullable(),
    responsibleId: Yup.number().nullable(),
  });

  const defaultValues = useMemo(() => ({
    invoiceNumber: currentInvoice?.invoiceNumber || '',
    dueDate: currentInvoice?.dueDate || null,
    responsibleId: currentInvoice?.responsibleId || null,
    taxes: currentInvoice?.taxes || 0,
    status: currentInvoice?.status || 'draft',
    invoiceIssuer: currentInvoice?.invoiceIssuer || 2,
    invoiceClient: currentInvoice?.invoiceClient || null,
    productLine: currentInvoice?.productLine || [{ title: '', description: '', quantity: 1, price: 0, total: 0 }],
    devise: currentInvoice?.devise || '',
    paymentMode: currentInvoice?.paymentMode || { id: '', name: '' },
    totalAmount: currentInvoice?.totalAmount || 0,
    signatureUrl: currentInvoice?.signatureUrl || null,
    signatureUrlS3: currentInvoice?.signatureUrlS3 || null,
    notes: currentInvoice?.notes || '',
    agencyId: currentInvoice?.agencyId || null,
    responsibleEmail: localStorage.getItem('email') || '',

  }), [currentInvoice]);
  type InvoiceFormValues = Yup.InferType<typeof NewInvoiceSchema>;
  const methods = useForm<InvoiceFormValues>({
    resolver: yupResolver(NewInvoiceSchema),
    defaultValues,
  });

  const {
    reset,
    handleSubmit,
    formState: { isSubmitting },
  } = methods;

  const handleSaveAsDraft = handleSubmit(async (data: InvoiceFormValues) => {
    loadingSave.onTrue();
    try {
      await createInvoice({ ...data, status: 'draft' } as unknown as Partial<IInvoice>);
      reset();
      loadingSave.onFalse();
      router.push(paths.dashboard.invoice.root);
      enqueueSnackbar('Invoice saved as draft successfully!', { variant: 'success' });
    } catch (error) {
      console.error(error);
      loadingSave.onFalse();
      enqueueSnackbar('Failed to save invoice', { variant: 'error' });
    }
  });
  
  
  const handleCreateAndSend = handleSubmit(async (data) => {
    loadingSend.onTrue();
  
    try {
      await createInvoice(data as unknown as Partial<IInvoice>);
      
      // Générer le token Firebase
      const firebaseToken = await generateToken();
      const clientEmail = data.invoiceClient?.emailAddress;
      if (firebaseToken) {
        const notificationData: INotif = {
          firebaseToken: firebaseToken,
          email: clientEmail, 
        };
        await sendNotificationToUserAfterInvoiceCreation(notificationData);
      } else {
        console.warn('Failed to generate Firebase token');
      }
  
      await new Promise((resolve) => setTimeout(resolve, 500));
      reset();
      loadingSend.onFalse();
      router.push(paths.dashboard.invoice.root);
      enqueueSnackbar('Invoice created and notification sent successfully!', { variant: 'success' });
      console.info('DATA', JSON.stringify(data, null, 2));
    } catch (error) {
      console.error('Error creating invoice or sending notification:', error);
      enqueueSnackbar('Failed to create invoice or send notification', { variant: 'error' });
      loadingSend.onFalse();
    }
  });

  return (
    <FormProvider methods={methods}>
      <Card>
        <InvoiceNewAddAddress />
        <InvoiceNewEditStatusDate  isEdit={false}/>
        <InvoiceNewEditDetails />
      </Card>

      <Stack justifyContent="flex-end" direction="row" spacing={2} sx={{ mt: 3 }}>
        <LoadingButton
          color="inherit"
          size="large"
          variant="outlined"
          loading={loadingSave.value && isSubmitting}
          onClick={handleSaveAsDraft}
        >
          Save as Draft
        </LoadingButton>

        <LoadingButton
          size="large"
          variant="contained"
          sx={{
            backgroundColor: '#144dd5',
            '&:hover': {
              backgroundColor: '#144dd5',
            },
        
            textTransform: 'none',
            px: 2,
            marginLeft: 2,
          }}
          loading={loadingSend.value && isSubmitting}
          onClick={handleCreateAndSend}
        >
          {currentInvoice ? 'Update' : 'Create'} and Send
        </LoadingButton>
      </Stack>
    </FormProvider>
  );
}