import { zodResolver } from "@hookform/resolvers/zod";
import { useFieldArray, useForm } from "react-hook-form";
import * as z from "zod";

import { ClientSelector } from "@erp/customers/components";

import { DevTool } from "@hookform/devtools";
import { DatePickerInputField, TextAreaField, TextField } from "@repo/rdx-ui/components";
import {
  Button,
  Calendar,
  Card,
  CardAction,
  CardContent,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
  Input,
  Label,
  Popover,
  PopoverContent,
  PopoverTrigger,
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
  Separator,
  Textarea,
} from "@repo/shadcn-ui/components";
import { format } from "date-fns";
import { es } from "date-fns/locale";
import { CalendarIcon, PlusIcon, Save, Trash2Icon, X } from "lucide-react";
import { CustomerInvoicePricesCard } from "../../components";
import { CustomerInvoiceItemsCardEditor } from "../../components/items";
import { useTranslation } from "../../i18n";
import { CustomerInvoiceData } from "./customer-invoice.schema";
import { formatCurrency } from "./utils";

const invoiceFormSchema = z.object({
  id: z.string(),
  invoice_status: z.string(),
  invoice_number: z.string().min(1, "Número de factura requerido"),
  invoice_series: z.string().min(1, "Serie requerida"),
  invoice_date: z.string(),
  operation_date: z.string(),
  language_code: z.string(),
  currency: z.string(),
  customer_id: z.string().min(1, "ID de cliente requerido"),
  items: z
    .array(
      z.object({
        description: z.string().optional(),
        quantity: z
          .object({
            amount: z.number().nullable(),
            scale: z.number(),
          })
          .optional(),
        unit_price: z
          .object({
            amount: z.number().nullable(),
            scale: z.number(),
            currency_code: z.string(),
          })
          .optional(),
        subtotal_price: z
          .object({
            amount: z.number().nullable(),
            scale: z.number(),
            currency_code: z.string(),
          })
          .optional(),
        discount: z
          .object({
            amount: z.number().min(0).max(100).nullable(),
            scale: z.number(),
          })
          .optional(),
        discount_price: z
          .object({
            amount: z.number().nullable(),
            scale: z.number(),
            currency_code: z.string(),
          })
          .optional(),
        total_price: z
          .object({
            amount: z.number().nullable(),
            scale: z.number(),
            currency_code: z.string(),
          })
          .optional(),
      })
    )
    .min(1, "Al menos un item es requerido"),
  subtotal_price: z.object({
    amount: z.number().nullable(),
    scale: z.number(),
    currency_code: z.string(),
  }),
  discount: z.object({
    amount: z.number().nullable(),
    scale: z.number(),
  }),
  discount_price: z.object({
    amount: z.number().nullable(),
    scale: z.number(),
    currency_code: z.string(),
  }),
  before_tax_price: z.object({
    amount: z.number().nullable(),
    scale: z.number(),
    currency_code: z.string(),
  }),
  tax: z.object({
    amount: z.number().nullable(),
    scale: z.number(),
  }),
  tax_price: z.object({
    amount: z.number().nullable(),
    scale: z.number(),
    currency_code: z.string(),
  }),
  total_price: z.object({
    amount: z.number().nullable(),
    scale: z.number(),
    currency_code: z.string(),
  }),
  metadata: z.object({
    entity: z.string(),
  }),
});

const defaultInvoiceData = {
  id: "34ae34af-1ffc-4de5-b0a8-c2cf203ef011",
  invoice_status: "draft",
  invoice_number: "1",
  invoice_series: "A",
  invoice_date: "2025-04-30T00:00:00.000Z",
  operation_date: "2025-04-30T00:00:00.000Z",
  description: "",
  language_code: "ES",
  currency: "EUR",
  customer_id: "5e4dc5b3-96b9-4968-9490-14bd032fec5f",
  items: [
    {
      description: "",
      quantity: {
        amount: 100,
        scale: 2,
      },

      unit_price: {
        amount: 100,
        scale: 2,
        currency_code: "EUR",
      },
      subtotal_price: {
        amount: 100,
        scale: 2,
        currency_code: "EUR",
      },
      discount: {
        amount: 0,
        scale: 2,
      },
      discount_price: {
        amount: 0,
        scale: 2,
        currency_code: "EUR",
      },
      total_price: {
        amount: 100,
        scale: 2,
        currency_code: "EUR",
      },
    },
  ],
  subtotal_price: {
    amount: 0,
    scale: 2,
    currency_code: "EUR",
  },
  discount: {
    amount: 0,
    scale: 0,
  },
  discount_price: {
    amount: 0,
    scale: 0,
    currency_code: "EUR",
  },
  before_tax_price: {
    amount: 0,
    scale: 2,
    currency_code: "EUR",
  },
  tax: {
    amount: 2100,
    scale: 2,
  },
  tax_price: {
    amount: 0,
    scale: 2,
    currency_code: "EUR",
  },
  total_price: {
    amount: 0,
    scale: 2,
    currency_code: "EUR",
  },
};

interface InvoiceFormProps {
  initialData?: CustomerInvoiceData;
  isPending?: boolean;
  /**
   * Callback function to handle form submission.
   * @param data - The invoice data submitted by the form.
   */
  onSubmit?: (data: CustomerInvoiceData) => void;
}

export const CustomerInvoiceEditForm = ({
  initialData = defaultInvoiceData,
  onSubmit,
  isPending,
}: InvoiceFormProps) => {
  const { t } = useTranslation();

  const form = useForm<CustomerInvoiceData>({
    resolver: zodResolver(invoiceFormSchema),
    defaultValues: initialData,
  });

  const { fields, append, remove } = useFieldArray({
    control: form.control,
    name: "items",
  });

  const watchedItems = form.watch("items");
  const watchedTaxRate = form.watch("tax.amount");

  const addItem = () => {
    append({
      id_article: "",
      description: "",
      quantity: { amount: 100, scale: 2 },
      unit_price: { amount: 0, scale: 2, currency_code: form.getValues("currency") },
      subtotal_price: { amount: 0, scale: 2, currency_code: form.getValues("currency") },
      discount: { amount: 0, scale: 2 },
      discount_price: { amount: 0, scale: 2, currency_code: form.getValues("currency") },
      total_price: { amount: 0, scale: 2, currency_code: form.getValues("currency") },
    });
  };

  const handleSubmit = (data: CustomerInvoiceData) => {
    console.log("Datos del formulario:", data);
    onSubmit?.(data);
  };

  const handleError = (errors: any) => {
    console.error("Errores en el formulario:", errors);
    // Aquí puedes manejar los errores, por ejemplo, mostrar un mensaje al usuario
  };

  const handleCancel = () => {
    form.reset(initialData);
  };

  return (
    <Form {...form}>
      <form
        onSubmit={form.handleSubmit(handleSubmit, handleError)}
        className='grid grid-cols-1 md:gap-6 md:grid-cols-2'
      >
        <Card className='border-0 shadow-none md:grid-span-2'>
          <CardHeader>
            <CardTitle>Cliente</CardTitle>
            <CardDescription>Description</CardDescription>
            <CardAction>
              <Button variant='link'>Sign Up</Button>
              <Button variant='link'>Sign Up</Button>
              <Button variant='link'>Sign Up</Button>
              <Button variant='link'>Sign Up</Button>
            </CardAction>
          </CardHeader>
          <CardContent className='grid grid-cols-1 gap-4 space-y-6'>
            <div>
              <div className='space-y-1'>
                <h4 className='text-sm leading-none font-medium'>Radix Primitives</h4>
                <p className='text-muted-foreground text-sm'>
                  An open-source UI component library.
                </p>
              </div>
              <Separator className='my-4' />
              <div className='flex h-5 items-center space-x-4 text-sm'>
                <div>Blog</div>
                <Separator orientation='vertical' />
                <div>Docs</div>
                <Separator orientation='vertical' />
                <div>Source</div>
              </div>
            </div>
          </CardContent>
          <CardFooter className='flex-col gap-2'>
            <Button type='submit' className='w-full'>
              Login
            </Button>
            <Button variant='outline' className='w-full'>
              Login with Google
            </Button>
          </CardFooter>{" "}
        </Card>

        {/* Información básica */}
        <Card className='border-0 shadow-none '>
          <CardHeader>
            <CardTitle>Información Básica</CardTitle>
            <CardDescription>Detalles generales de la factura</CardDescription>
          </CardHeader>
          <CardContent className='space-y-8'>
            <div className='grid gap-y-6 gap-x-8 md:grid-cols-4'>
              <TextField
                control={form.control}
                name='invoice_number'
                required
                disabled
                readOnly
                label={t("form_fields.invoice_number.label")}
                placeholder={t("form_fields.invoice_number.placeholder")}
                description={t("form_fields.invoice_number.description")}
              />

              <DatePickerInputField
                control={form.control}
                name='invoice_date'
                required
                label={t("form_fields.invoice_date.label")}
                placeholder={t("form_fields.invoice_date.placeholder")}
                description={t("form_fields.invoice_date.description")}
              />

              <TextField
                control={form.control}
                name='invoice_series'
                required
                label={t("form_fields.invoice_series.label")}
                placeholder={t("form_fields.invoice_series.placeholder")}
                description={t("form_fields.invoice_series.description")}
              />
            </div>
            <div className='grid gap-y-6 gap-x-8 grid-cols-1'>
              <TextField
                control={form.control}
                name='description'
                required
                label={t("form_fields.description.label")}
                placeholder={t("form_fields.description.placeholder")}
                description={t("form_fields.description.description")}
              />
            </div>
            <div className='grid gap-y-6 gap-x-8 grid-cols-1'>
              <TextAreaField
                control={form.control}
                name='notes'
                required
                label={t("form_fields.notes.label")}
                placeholder={t("form_fields.notes.placeholder")}
                description={t("form_fields.notes.description")}
              />
            </div>
          </CardContent>
        </Card>

        {/* Cliente */}
        <Card className='col-span-full'>
          <CardHeader>
            <CardTitle>Cliente</CardTitle>
          </CardHeader>
          <CardContent className='grid grid-cols-1 gap-4 space-y-6'>
            <ClientSelector />
            <TextField
              control={form.control}
              name='customer_id'
              required
              label={t("form_fields.customer_id.label")}
              placeholder={t("form_fields.customer_id.placeholder")}
              description={t("form_fields.customer_id.description")}
            />
          </CardContent>
        </Card>

        {/*Items */}
        <CustomerInvoiceItemsCardEditor
          defaultValues={defaultInvoiceData}
          className='col-span-full'
        />

        {/* Items */}
        <Card>
          <CardHeader className='flex flex-row items-center justify-between'>
            <div>
              <CardTitle>Artículos</CardTitle>
              <CardDescription>Lista de productos o servicios facturados</CardDescription>
            </div>
            <Button type='button' onClick={addItem} size='sm'>
              <PlusIcon className='h-4 w-4 mr-2' />
              Agregar Item
            </Button>
          </CardHeader>
          <CardContent className='space-y-4'>
            {fields.map((field, index) => (
              <Card key={field.id} className='p-4'>
                <div className='flex justify-between items-start mb-4'>
                  <div className='flex items-center gap-2'>
                    <h4 className='font-medium'>Item {index + 1}</h4>
                  </div>
                  {fields.length > 1 && (
                    <Button type='button' variant='outline' size='sm' onClick={() => remove(index)}>
                      <Trash2Icon className='h-4 w-4' />
                    </Button>
                  )}
                </div>

                <div className='grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-4'>
                  <FormField
                    control={form.control}
                    name={`items.${index}.id_article`}
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>Código Artículo</FormLabel>
                        <FormControl>
                          <Input placeholder='Código' {...field} />
                        </FormControl>
                        <FormMessage />
                      </FormItem>
                    )}
                  />

                  <FormField
                    control={form.control}
                    name={`items.${index}.description`}
                    render={({ field }) => (
                      <FormItem className='md:col-span-2'>
                        <FormLabel>Descripción</FormLabel>
                        <FormControl>
                          <Textarea placeholder='Descripción del producto/servicio' {...field} />
                        </FormControl>
                        <FormMessage />
                      </FormItem>
                    )}
                  />

                  <TextAreaField
                    control={form.control}
                    name={`items.${index}.description`}
                    label={t("form_fields.items.description.label")}
                    placeholder={t("form_fields.items.description.placeholder")}
                    description={t("form_fields.items.description.description")}
                  />

                  <FormField
                    control={form.control}
                    name={`items.${index}.quantity.amount`}
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>Cantidad</FormLabel>
                        <FormControl>
                          <Input
                            type='number'
                            step='0.01'
                            min='0'
                            {...field}
                            onChange={(e) => field.onChange(Number(e.target.value) * 100)}
                            value={field.value / 100}
                          />
                        </FormControl>
                        <FormMessage />
                      </FormItem>
                    )}
                  />

                  <FormField
                    control={form.control}
                    name={`items.${index}.unit_price.amount`}
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>Precio Unitario</FormLabel>
                        <FormControl>
                          <Input
                            type='number'
                            step='0.01'
                            min='0'
                            {...field}
                            onChange={(e) => field.onChange(Number(e.target.value) * 100)}
                            value={field.value / 100}
                          />
                        </FormControl>
                        <FormMessage />
                      </FormItem>
                    )}
                  />

                  <FormField
                    control={form.control}
                    name={`items.${index}.discount.amount`}
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>Descuento (%)</FormLabel>
                        <FormControl>
                          <Input
                            type='number'
                            step='0.01'
                            min='0'
                            max='100'
                            {...field}
                            onChange={(e) => field.onChange(Number(e.target.value) * 100)}
                            value={field.value / 100}
                          />
                        </FormControl>
                        <FormMessage />
                      </FormItem>
                    )}
                  />
                </div>

                <div className='mt-4 p-3 bg-muted rounded-lg'>
                  <div className='text-sm text-muted-foreground'>
                    Total del item:{" "}
                    {formatCurrency(
                      watchedItems[index]?.total_price?.amount || 0,
                      2,
                      form.getValues("currency")
                    )}
                  </div>
                </div>
              </Card>
            ))}
          </CardContent>
        </Card>

        <CustomerInvoicePricesCard />

        {/* Configuración de Impuestos */}
        <Card>
          <CardHeader>
            <CardTitle>Impuestos y Totales</CardTitle>
            <CardDescription>Configuración de impuestos y resumen de totales</CardDescription>
          </CardHeader>
          <CardContent className='space-y-4'>
            <div className='grid grid-cols-1 md:grid-cols-2 gap-4'>
              <FormField
                control={form.control}
                name='tax.amount'
                render={({ field }) => (
                  <FormItem>
                    <FormLabel>Tasa de Impuesto (%)</FormLabel>
                    <FormControl>
                      <Input
                        type='number'
                        step='0.01'
                        min='0'
                        max='100'
                        {...field}
                        onChange={(e) => field.onChange(Number(e.target.value) * 100)}
                        value={field.value / 100}
                      />
                    </FormControl>
                    <FormMessage />
                  </FormItem>
                )}
              />
            </div>

            <Separator />

            {/* Resumen de totales */}
            <div className='space-y-3'>
              <div className='flex justify-between text-sm'>
                <span>Subtotal:</span>
                <span>
                  {formatCurrency(form.watch("subtotal_price.amount"), 2, form.watch("currency"))}
                </span>
              </div>
              <div className='flex justify-between text-sm'>
                <span>Descuento:</span>
                <span>
                  -{formatCurrency(form.watch("discount_price.amount"), 2, form.watch("currency"))}
                </span>
              </div>
              <div className='flex justify-between text-sm'>
                <span>Base imponible:</span>
                <span>
                  {formatCurrency(form.watch("before_tax_price.amount"), 2, form.watch("currency"))}
                </span>
              </div>
              <div className='flex justify-between text-sm'>
                <span>Impuestos ({(form.watch("tax.amount") / 100).toFixed(2)}%):</span>
                <span>
                  {formatCurrency(form.watch("tax_price.amount"), 2, form.watch("currency"))}
                </span>
              </div>
              <Separator />
              <div className='flex justify-between text-lg font-semibold'>
                <span>Total:</span>
                <span>
                  {formatCurrency(form.watch("total_price.amount"), 2, form.watch("currency"))}
                </span>
              </div>
            </div>
          </CardContent>
        </Card>
        <div className='flex justify-end space-x-4'>
          <Button type='button' variant='outline' disabled={isPending} onClick={handleCancel}>
            Cancelar
          </Button>
          <Button type='submit' disabled={isPending}>
            Guardar Factura
          </Button>
        </div>
      </form>
      <DevTool control={form.control} />
    </Form>
  );

  return (
    <div className='grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 bg-muted/50'>
      <form onSubmit={handleSubmit} className='space-y-6'>
        {/* Información básica */}
        <div className='grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4'>
          <div className='space-y-2'>
            <Label htmlFor='id'>ID de Factura</Label>
            <Input id='id' value={formData.id} disabled className='bg-muted' />
          </div>

          <div className='space-y-2'>
            <Label htmlFor='invoice_status'>Estado</Label>
            <Select
              value={formData.invoice_status}
              onValueChange={(value) => handleInputChange("invoice_status", value)}
            >
              <SelectTrigger>
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value='draft'>Borrador</SelectItem>
                <SelectItem value='sent'>Enviada</SelectItem>
                <SelectItem value='paid'>Pagada</SelectItem>
                <SelectItem value='cancelled'>Cancelada</SelectItem>
              </SelectContent>
            </Select>
          </div>

          <div className='space-y-2'>
            <Label htmlFor='language_code'>Idioma</Label>
            <Select
              value={formData.language_code}
              onValueChange={(value) => handleInputChange("language_code", value)}
            >
              <SelectTrigger>
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value='ES'>Español</SelectItem>
                <SelectItem value='EN'>English</SelectItem>
                <SelectItem value='FR'>Français</SelectItem>
                <SelectItem value='DE'>Deutsch</SelectItem>
              </SelectContent>
            </Select>
          </div>
        </div>

        {/* Numeración */}
        <div className='grid grid-cols-1 md:grid-cols-3 gap-4'>
          <div className='space-y-2'>
            <Label htmlFor='invoice_series'>Serie</Label>
            <Input
              id='invoice_series'
              value={formData.invoice_series}
              onChange={(e) => handleInputChange("invoice_series", e.target.value)}
              placeholder='A'
            />
          </div>

          <div className='space-y-2'>
            <Label htmlFor='invoice_number'>Número</Label>
            <Input
              id='invoice_number'
              value={formData.invoice_number}
              onChange={(e) => handleInputChange("invoice_number", e.target.value)}
              placeholder='1'
            />
          </div>

          <div className='space-y-2 hidden'>
            <Label htmlFor='currency'>Moneda</Label>
            <Select
              value={formData.currency}
              onValueChange={(value) => handleInputChange("currency", value)}
            >
              <SelectTrigger>
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value='EUR'>EUR (€)</SelectItem>
                <SelectItem value='USD'>USD ($)</SelectItem>
                <SelectItem value='GBP'>GBP (£)</SelectItem>
                <SelectItem value='JPY'>JPY (¥)</SelectItem>
              </SelectContent>
            </Select>
          </div>
        </div>

        {/* Fechas */}
        <div className='grid grid-cols-1 md:grid-cols-2 gap-4'>
          <div className='space-y-2'>
            <Label>Fecha de Emisión</Label>
            <Popover>
              <PopoverTrigger asChild>
                <Button variant='outline' className='w-full justify-start text-left font-normal'>
                  <CalendarIcon className='mr-2 h-4 w-4' />
                  {format(invoiceDate, "PPP", { locale: es })}
                </Button>
              </PopoverTrigger>
              <PopoverContent className='w-auto p-0' align='start'>
                <Calendar
                  mode='single'
                  selected={invoiceDate}
                  onSelect={(date) => handleDateChange("invoice_date", date)}
                  initialFocus
                />
              </PopoverContent>
            </Popover>
          </div>

          <div className='space-y-2'>
            <Label>Fecha de Operación</Label>
            <Popover>
              <PopoverTrigger asChild>
                <Button variant='outline' className='w-full justify-start text-left font-normal'>
                  <CalendarIcon className='mr-2 h-4 w-4' />
                  {format(operationDate, "PPP", { locale: es })}
                </Button>
              </PopoverTrigger>
              <PopoverContent className='w-auto p-0' align='start'>
                <Calendar
                  mode='single'
                  selected={operationDate}
                  onSelect={(date) => handleDateChange("operation_date", date)}
                  initialFocus
                />
              </PopoverContent>
            </Popover>
          </div>
        </div>

        {/* Importes */}
        <div className='space-y-4'>
          <h3 className='text-lg font-semibold'>Importes</h3>

          <div className='grid grid-cols-1 md:grid-cols-2 gap-6'>
            <Card>
              <CardHeader className='pb-3'>
                <CardTitle className='text-base'>Subtotal</CardTitle>
              </CardHeader>
              <CardContent className='space-y-3'>
                <div className='space-y-2'>
                  <Label htmlFor='subtotal_amount'>Importe</Label>
                  <Input
                    id='subtotal_amount'
                    type='number'
                    step='0.01'
                    value={formData.subtotal.amount / Math.pow(10, formData.subtotal.scale)}
                    onChange={(e) =>
                      handleNestedChange(
                        "subtotal",
                        "amount",
                        Number.parseFloat(e.target.value) * Math.pow(10, formData.subtotal.scale)
                      )
                    }
                  />
                </div>
                <div className='space-y-2'>
                  <Label htmlFor='subtotal_currency'>Moneda</Label>
                  <Select
                    value={formData.subtotal.currency_code}
                    onValueChange={(value) =>
                      handleNestedChange("subtotal", "currency_code", value)
                    }
                  >
                    <SelectTrigger>
                      <SelectValue />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem value='EUR'>EUR</SelectItem>
                      <SelectItem value='USD'>USD</SelectItem>
                      <SelectItem value='GBP'>GBP</SelectItem>
                    </SelectContent>
                  </Select>
                </div>
              </CardContent>
            </Card>

            <Card>
              <CardHeader className='pb-3'>
                <CardTitle className='text-base'>Total</CardTitle>
              </CardHeader>
              <CardContent className='space-y-3'>
                <div className='space-y-2'>
                  <Label htmlFor='total_amount'>Importe</Label>
                  <Input
                    id='total_amount'
                    type='number'
                    step='0.01'
                    value={formData.total.amount / Math.pow(10, formData.total.scale)}
                    onChange={(e) =>
                      handleNestedChange(
                        "total",
                        "amount",
                        Number.parseFloat(e.target.value) * Math.pow(10, formData.total.scale)
                      )
                    }
                  />
                </div>
                <div className='space-y-2'>
                  <Label htmlFor='total_currency'>Moneda</Label>
                  <Select
                    value={formData.total.currency_code}
                    onValueChange={(value) => handleNestedChange("total", "currency_code", value)}
                  >
                    <SelectTrigger>
                      <SelectValue />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem value='EUR'>EUR</SelectItem>
                      <SelectItem value='USD'>USD</SelectItem>
                      <SelectItem value='GBP'>GBP</SelectItem>
                    </SelectContent>
                  </Select>
                </div>
              </CardContent>
            </Card>
          </div>
        </div>

        {/* Botones de acción */}
        <div className='flex justify-end gap-3 pt-6 border-t'>
          <Button
            type='button'
            variant='outline'
            onClick={handleCancel}
            className='flex items-center gap-2'
          >
            <X className='h-4 w-4' />
            Cancelar
          </Button>
          <Button type='submit' className='flex items-center gap-2'>
            <Save className='h-4 w-4' />
            Guardar Cambios
          </Button>
        </div>
      </form>
    </div>
  );
};
