import { useState, useEffect } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import {
  ArrowLeft,
  Save,
  Plus,
  Trash2,
  FileText,
  User,
  Calendar,
  Package,
  AlertCircle,
} from 'lucide-react';
import { Button } from '@components/atoms/Button';
import { Spinner } from '@components/atoms/Spinner';
import { Card, CardHeader, CardTitle, CardContent } from '@components/molecules/Card';
import { Alert } from '@components/molecules/Alert';
import { Breadcrumbs } from '@components/organisms/Breadcrumbs';
import { useToast } from '@components/organisms/Toast';
import { ErrorEmptyState } from '@components/templates/EmptyState';
import { useQuotation } from '@features/sales/hooks';
import { salesApi } from '@features/sales';
import { usePartners } from '@features/partners/hooks';
import type { UpdateQuotationDto, CreateQuotationLineDto, UpdateQuotationLineDto } from '@features/sales/types';
import { formatNumber } from '@utils/formatters';

interface LineItemFormData {
  id?: string;
  productId: string;
  productName: string;
  description: string;
  quantity: number;
  uomId: string;
  uomName: string;
  priceUnit: number;
  discount: number;
  isNew?: boolean;
  isModified?: boolean;
  isDeleted?: boolean;
}

interface FormData {
  partnerId: string;
  quotationDate: string;
  validityDate: string;
  currencyId: string;
  notes: string;
  termsConditions: string;
}

interface FormErrors {
  partnerId?: string;
  quotationDate?: string;
  currencyId?: string;
  lines?: string;
}

const formatCurrency = (value: number): string => {
  return formatNumber(value, 'es-MX', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
};

export function QuotationEditPage() {
  const { id } = useParams<{ id: string }>();
  const navigate = useNavigate();
  const { showToast } = useToast();

  // Hooks
  const { quotation, isLoading: quotationLoading, error: quotationError, refresh } = useQuotation(id || null);
  const { partners, isLoading: partnersLoading } = usePartners({ isCustomer: true, limit: 100 });

  // Form state
  const [formData, setFormData] = useState<FormData>({
    partnerId: '',
    quotationDate: '',
    validityDate: '',
    currencyId: '',
    notes: '',
    termsConditions: '',
  });

  const [lineItems, setLineItems] = useState<LineItemFormData[]>([]);
  const [errors, setErrors] = useState<FormErrors>({});
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [submitError, setSubmitError] = useState<string | null>(null);
  const [hasChanges, setHasChanges] = useState(false);

  // Populate form when quotation loads
  useEffect(() => {
    if (quotation) {
      const qDate = String(quotation.quotationDate || '');
      const vDate = String(quotation.validityDate || '');
      setFormData({
        partnerId: String(quotation.partnerId || ''),
        quotationDate: qDate.split('T')[0] ?? qDate,
        validityDate: vDate.split('T')[0] ?? vDate,
        currencyId: String(quotation.currencyId || ''),
        notes: String(quotation.notes || ''),
        termsConditions: String(quotation.termsConditions || ''),
      });

      // Load existing lines
      if (quotation.lines) {
        setLineItems(
          quotation.lines.map((line) => ({
            id: line.id,
            productId: line.productId,
            productName: line.productName || '',
            description: line.description,
            quantity: line.quantity,
            uomId: line.uomId,
            uomName: line.uomName || '',
            priceUnit: line.priceUnit,
            discount: line.discount,
            isNew: false,
            isModified: false,
            isDeleted: false,
          }))
        );
      }
    }
  }, [quotation]);

  // Check if quotation is editable (only draft quotations can be edited)
  const isEditable = quotation?.status === 'draft';

  // Redirect if not editable
  useEffect(() => {
    if (quotation && !isEditable) {
      showToast({
        type: 'warning',
        title: 'No editable',
        message: `La cotizacion ${quotation.quotationNumber} no puede ser editada porque su estado es "${quotation.status}".`,
      });
      navigate(`/sales/quotations/${id}`);
    }
  }, [quotation, isEditable, navigate, id, showToast]);

  const handleFieldChange = (field: keyof FormData, value: string) => {
    setFormData((prev) => ({ ...prev, [field]: value }));
    setHasChanges(true);
    if (errors[field as keyof FormErrors]) {
      setErrors((prev) => ({ ...prev, [field]: undefined }));
    }
  };

  const handleLineChange = (index: number, field: keyof LineItemFormData, value: string | number) => {
    setLineItems((prev) => {
      const updated = [...prev];
      const currentLine = updated[index];
      if (currentLine) {
        updated[index] = {
          ...currentLine,
          [field]: value,
          isModified: !currentLine.isNew,
        };
      }
      return updated;
    });
    setHasChanges(true);
  };

  const addNewLine = () => {
    setLineItems((prev) => [
      ...prev,
      {
        productId: '',
        productName: '',
        description: '',
        quantity: 1,
        uomId: '',
        uomName: '',
        priceUnit: 0,
        discount: 0,
        isNew: true,
        isModified: false,
        isDeleted: false,
      },
    ]);
    setHasChanges(true);
  };

  const markLineForDeletion = (index: number) => {
    setLineItems((prev) => {
      const updated = [...prev];
      const currentLine = updated[index];
      if (currentLine?.isNew) {
        // Remove new lines immediately
        return updated.filter((_, i) => i !== index);
      }
      // Mark existing lines for deletion
      if (currentLine) {
        updated[index] = { ...currentLine, isDeleted: true };
      }
      return updated;
    });
    setHasChanges(true);
  };

  const restoreLine = (index: number) => {
    setLineItems((prev) => {
      const updated = [...prev];
      const currentLine = updated[index];
      if (currentLine) {
        updated[index] = { ...currentLine, isDeleted: false };
      }
      return updated;
    });
  };

  const calculateLineTotal = (line: LineItemFormData): number => {
    const subtotal = line.quantity * line.priceUnit;
    const discountAmount = subtotal * (line.discount / 100);
    return subtotal - discountAmount;
  };

  const calculateTotals = () => {
    const activeLines = lineItems.filter((l) => !l.isDeleted);
    const subtotal = activeLines.reduce((sum, line) => sum + calculateLineTotal(line), 0);
    // For simplicity, estimate tax at 16% (IVA Mexico)
    const taxRate = 0.16;
    const tax = subtotal * taxRate;
    const total = subtotal + tax;
    return { subtotal, tax, total };
  };

  const validateForm = (): boolean => {
    const newErrors: FormErrors = {};

    if (!formData.partnerId) {
      newErrors.partnerId = 'El cliente es requerido';
    }
    if (!formData.quotationDate) {
      newErrors.quotationDate = 'La fecha de cotizacion es requerida';
    }
    if (!formData.currencyId) {
      newErrors.currencyId = 'La moneda es requerida';
    }

    const activeLines = lineItems.filter((l) => !l.isDeleted);
    if (activeLines.length === 0) {
      newErrors.lines = 'Debe agregar al menos una linea de cotizacion';
    } else {
      const invalidLine = activeLines.find(
        (l) => !l.productId || l.quantity <= 0 || l.priceUnit < 0
      );
      if (invalidLine) {
        newErrors.lines = 'Todas las lineas deben tener producto, cantidad y precio validos';
      }
    }

    setErrors(newErrors);
    return Object.keys(newErrors).length === 0;
  };

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();

    if (!validateForm() || !id) return;

    setIsSubmitting(true);
    setSubmitError(null);

    try {
      // 1. Update quotation header
      const quotationUpdate: UpdateQuotationDto = {
        partnerId: formData.partnerId,
        quotationDate: formData.quotationDate,
        validityDate: formData.validityDate || null,
        currencyId: formData.currencyId,
        notes: formData.notes || null,
        termsConditions: formData.termsConditions || null,
      };

      await salesApi.updateQuotation(id, quotationUpdate);

      // 2. Process line items
      const linesToDelete = lineItems.filter((l) => l.isDeleted && l.id);
      const linesToUpdate = lineItems.filter((l) => l.isModified && l.id && !l.isDeleted);
      const linesToAdd = lineItems.filter((l) => l.isNew && !l.isDeleted);

      // Delete lines
      for (const line of linesToDelete) {
        if (line.id) {
          await salesApi.removeQuotationLine(id, line.id);
        }
      }

      // Update existing lines
      for (const line of linesToUpdate) {
        if (line.id) {
          const updateData: UpdateQuotationLineDto = {
            description: line.description,
            quantity: line.quantity,
            uomId: line.uomId,
            priceUnit: line.priceUnit,
            discount: line.discount,
          };
          await salesApi.updateQuotationLine(id, line.id, updateData);
        }
      }

      // Add new lines
      for (const line of linesToAdd) {
        const createData: CreateQuotationLineDto = {
          productId: line.productId,
          description: line.description,
          quantity: line.quantity,
          uomId: line.uomId,
          priceUnit: line.priceUnit,
          discount: line.discount,
        };
        await salesApi.addQuotationLine(id, createData);
      }

      showToast({
        type: 'success',
        title: 'Cotizacion actualizada',
        message: 'Los cambios han sido guardados exitosamente.',
      });

      navigate(`/sales/quotations/${id}`);
    } catch (err) {
      const message = err instanceof Error ? err.message : 'Error al actualizar la cotizacion';
      setSubmitError(message);
      showToast({
        type: 'error',
        title: 'Error',
        message,
      });
    } finally {
      setIsSubmitting(false);
    }
  };

  // Loading state
  if (quotationLoading) {
    return (
      <div className="flex h-96 items-center justify-center">
        <Spinner size="lg" />
      </div>
    );
  }

  // Error state
  if (quotationError || !quotation) {
    return (
      <div className="p-6">
        <ErrorEmptyState
          title="Cotizacion no encontrada"
          description="No se pudo cargar la informacion de la cotizacion."
          onRetry={refresh}
        />
      </div>
    );
  }

  const totals = calculateTotals();

  return (
    <div className="space-y-6 p-6">
      <Breadcrumbs
        items={[
          { label: 'Ventas', href: '/sales' },
          { label: 'Cotizaciones', href: '/sales/quotations' },
          { label: quotation.quotationNumber, href: `/sales/quotations/${id}` },
          { label: 'Editar' },
        ]}
      />

      <div className="flex items-center gap-4">
        <Button variant="ghost" size="sm" onClick={() => navigate(`/sales/quotations/${id}`)}>
          <ArrowLeft className="mr-2 h-4 w-4" />
          Volver
        </Button>
        <div>
          <h1 className="text-2xl font-bold text-gray-900">
            Editar Cotizacion {quotation.quotationNumber}
          </h1>
          <p className="text-sm text-gray-500">
            Modifica la informacion de la cotizacion
          </p>
        </div>
      </div>

      <form onSubmit={handleSubmit}>
        <div className="grid grid-cols-1 gap-6 lg:grid-cols-3">
          {/* Main Content */}
          <div className="lg:col-span-2 space-y-6">
            {/* Customer Information */}
            <Card>
              <CardHeader>
                <CardTitle className="flex items-center gap-2">
                  <User className="h-5 w-5" />
                  Informacion del Cliente
                </CardTitle>
              </CardHeader>
              <CardContent className="space-y-4">
                <div>
                  <label className="block text-sm font-medium text-gray-700 mb-1">
                    Cliente *
                  </label>
                  <select
                    value={formData.partnerId}
                    onChange={(e) => handleFieldChange('partnerId', e.target.value)}
                    className={`w-full rounded-md border px-3 py-2 focus:outline-none focus:ring-1 ${
                      errors.partnerId
                        ? 'border-red-300 focus:border-red-500 focus:ring-red-500'
                        : 'border-gray-300 focus:border-blue-500 focus:ring-blue-500'
                    }`}
                    disabled={partnersLoading}
                  >
                    <option value="">Seleccionar cliente...</option>
                    {partners.map((partner) => (
                      <option key={partner.id} value={partner.id}>
                        {partner.name}
                      </option>
                    ))}
                  </select>
                  {errors.partnerId && (
                    <p className="mt-1 text-sm text-red-600">{errors.partnerId}</p>
                  )}
                </div>
              </CardContent>
            </Card>

            {/* Quotation Details */}
            <Card>
              <CardHeader>
                <CardTitle className="flex items-center gap-2">
                  <Calendar className="h-5 w-5" />
                  Detalles de la Cotizacion
                </CardTitle>
              </CardHeader>
              <CardContent className="space-y-4">
                <div className="grid grid-cols-1 gap-4 sm:grid-cols-3">
                  <div>
                    <label className="block text-sm font-medium text-gray-700 mb-1">
                      Fecha de Cotizacion *
                    </label>
                    <input
                      type="date"
                      value={formData.quotationDate}
                      onChange={(e) => handleFieldChange('quotationDate', e.target.value)}
                      className={`w-full rounded-md border px-3 py-2 focus:outline-none focus:ring-1 ${
                        errors.quotationDate
                          ? 'border-red-300 focus:border-red-500 focus:ring-red-500'
                          : 'border-gray-300 focus:border-blue-500 focus:ring-blue-500'
                      }`}
                    />
                    {errors.quotationDate && (
                      <p className="mt-1 text-sm text-red-600">{errors.quotationDate}</p>
                    )}
                  </div>

                  <div>
                    <label className="block text-sm font-medium text-gray-700 mb-1">
                      Vigencia Hasta
                    </label>
                    <input
                      type="date"
                      value={formData.validityDate}
                      onChange={(e) => handleFieldChange('validityDate', e.target.value)}
                      className="w-full rounded-md border border-gray-300 px-3 py-2 focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500"
                    />
                  </div>

                  <div>
                    <label className="block text-sm font-medium text-gray-700 mb-1">
                      Moneda *
                    </label>
                    <select
                      value={formData.currencyId}
                      onChange={(e) => handleFieldChange('currencyId', e.target.value)}
                      className={`w-full rounded-md border px-3 py-2 focus:outline-none focus:ring-1 ${
                        errors.currencyId
                          ? 'border-red-300 focus:border-red-500 focus:ring-red-500'
                          : 'border-gray-300 focus:border-blue-500 focus:ring-blue-500'
                      }`}
                    >
                      <option value="">Seleccionar moneda...</option>
                      <option value="MXN">MXN - Peso Mexicano</option>
                      <option value="USD">USD - Dolar Americano</option>
                      <option value="EUR">EUR - Euro</option>
                    </select>
                    {errors.currencyId && (
                      <p className="mt-1 text-sm text-red-600">{errors.currencyId}</p>
                    )}
                  </div>
                </div>
              </CardContent>
            </Card>

            {/* Line Items */}
            <Card>
              <CardHeader>
                <div className="flex items-center justify-between">
                  <CardTitle className="flex items-center gap-2">
                    <Package className="h-5 w-5" />
                    Lineas de la Cotizacion
                  </CardTitle>
                  <Button type="button" variant="outline" size="sm" onClick={addNewLine}>
                    <Plus className="mr-1 h-4 w-4" />
                    Agregar Linea
                  </Button>
                </div>
              </CardHeader>
              <CardContent>
                {errors.lines && (
                  <Alert variant="danger" className="mb-4">
                    <AlertCircle className="h-4 w-4" />
                    {errors.lines}
                  </Alert>
                )}

                {lineItems.length === 0 ? (
                  <div className="text-center py-8 text-gray-500">
                    <Package className="mx-auto h-12 w-12 text-gray-300" />
                    <p className="mt-2">No hay lineas en la cotizacion</p>
                    <Button
                      type="button"
                      variant="outline"
                      size="sm"
                      className="mt-4"
                      onClick={addNewLine}
                    >
                      <Plus className="mr-1 h-4 w-4" />
                      Agregar primera linea
                    </Button>
                  </div>
                ) : (
                  <div className="space-y-4">
                    <div className="overflow-x-auto">
                      <table className="w-full text-sm">
                        <thead>
                          <tr className="border-b text-left text-gray-500">
                            <th className="pb-2 font-medium">Producto</th>
                            <th className="pb-2 font-medium">Descripcion</th>
                            <th className="pb-2 font-medium text-right">Cantidad</th>
                            <th className="pb-2 font-medium text-right">Precio</th>
                            <th className="pb-2 font-medium text-right">Desc %</th>
                            <th className="pb-2 font-medium text-right">Total</th>
                            <th className="pb-2 font-medium"></th>
                          </tr>
                        </thead>
                        <tbody>
                          {lineItems.map((line, index) => (
                            <tr
                              key={line.id || `new-${index}`}
                              className={`border-b ${line.isDeleted ? 'bg-red-50 opacity-50' : ''}`}
                            >
                              <td className="py-2">
                                <input
                                  type="text"
                                  value={line.productName || line.productId}
                                  onChange={(e) => handleLineChange(index, 'productId', e.target.value)}
                                  placeholder="ID Producto"
                                  disabled={line.isDeleted}
                                  className="w-24 rounded border border-gray-300 px-2 py-1 text-sm focus:border-blue-500 focus:outline-none disabled:bg-gray-100"
                                />
                              </td>
                              <td className="py-2">
                                <input
                                  type="text"
                                  value={line.description}
                                  onChange={(e) => handleLineChange(index, 'description', e.target.value)}
                                  placeholder="Descripcion"
                                  disabled={line.isDeleted}
                                  className="w-full rounded border border-gray-300 px-2 py-1 text-sm focus:border-blue-500 focus:outline-none disabled:bg-gray-100"
                                />
                              </td>
                              <td className="py-2">
                                <input
                                  type="number"
                                  value={line.quantity}
                                  onChange={(e) => handleLineChange(index, 'quantity', parseFloat(e.target.value) || 0)}
                                  min="0"
                                  step="0.01"
                                  disabled={line.isDeleted}
                                  className="w-20 rounded border border-gray-300 px-2 py-1 text-right text-sm focus:border-blue-500 focus:outline-none disabled:bg-gray-100"
                                />
                              </td>
                              <td className="py-2">
                                <input
                                  type="number"
                                  value={line.priceUnit}
                                  onChange={(e) => handleLineChange(index, 'priceUnit', parseFloat(e.target.value) || 0)}
                                  min="0"
                                  step="0.01"
                                  disabled={line.isDeleted}
                                  className="w-24 rounded border border-gray-300 px-2 py-1 text-right text-sm focus:border-blue-500 focus:outline-none disabled:bg-gray-100"
                                />
                              </td>
                              <td className="py-2">
                                <input
                                  type="number"
                                  value={line.discount}
                                  onChange={(e) => handleLineChange(index, 'discount', parseFloat(e.target.value) || 0)}
                                  min="0"
                                  max="100"
                                  step="0.01"
                                  disabled={line.isDeleted}
                                  className="w-16 rounded border border-gray-300 px-2 py-1 text-right text-sm focus:border-blue-500 focus:outline-none disabled:bg-gray-100"
                                />
                              </td>
                              <td className="py-2 text-right font-medium">
                                ${formatCurrency(calculateLineTotal(line))}
                              </td>
                              <td className="py-2 pl-2">
                                {line.isDeleted ? (
                                  <Button
                                    type="button"
                                    variant="ghost"
                                    size="sm"
                                    onClick={() => restoreLine(index)}
                                    className="text-blue-600 hover:text-blue-700"
                                  >
                                    Restaurar
                                  </Button>
                                ) : (
                                  <button
                                    type="button"
                                    onClick={() => markLineForDeletion(index)}
                                    className="rounded p-1 text-gray-400 hover:bg-red-50 hover:text-red-600"
                                  >
                                    <Trash2 className="h-4 w-4" />
                                  </button>
                                )}
                              </td>
                            </tr>
                          ))}
                        </tbody>
                      </table>
                    </div>
                  </div>
                )}
              </CardContent>
            </Card>

            {/* Notes */}
            <Card>
              <CardHeader>
                <CardTitle className="flex items-center gap-2">
                  <FileText className="h-5 w-5" />
                  Notas y Terminos
                </CardTitle>
              </CardHeader>
              <CardContent className="space-y-4">
                <div>
                  <label className="block text-sm font-medium text-gray-700 mb-1">
                    Notas
                  </label>
                  <textarea
                    value={formData.notes}
                    onChange={(e) => handleFieldChange('notes', e.target.value)}
                    rows={3}
                    placeholder="Notas internas sobre la cotizacion..."
                    className="w-full rounded-md border border-gray-300 px-3 py-2 focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500"
                  />
                </div>

                <div>
                  <label className="block text-sm font-medium text-gray-700 mb-1">
                    Terminos y Condiciones
                  </label>
                  <textarea
                    value={formData.termsConditions}
                    onChange={(e) => handleFieldChange('termsConditions', e.target.value)}
                    rows={3}
                    placeholder="Terminos y condiciones para el cliente..."
                    className="w-full rounded-md border border-gray-300 px-3 py-2 focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500"
                  />
                </div>
              </CardContent>
            </Card>
          </div>

          {/* Sidebar - Summary */}
          <div className="space-y-6">
            {/* Submit Error */}
            {submitError && (
              <Alert
                variant="danger"
                title="Error al guardar"
                onClose={() => setSubmitError(null)}
              >
                {submitError}
              </Alert>
            )}

            {/* Quotation Summary */}
            <Card>
              <CardHeader>
                <CardTitle className="flex items-center gap-2">
                  <FileText className="h-5 w-5" />
                  Resumen
                </CardTitle>
              </CardHeader>
              <CardContent>
                <div className="space-y-3">
                  <div className="flex justify-between text-sm">
                    <span className="text-gray-500">Subtotal</span>
                    <span>${formatCurrency(totals.subtotal)}</span>
                  </div>
                  <div className="flex justify-between text-sm">
                    <span className="text-gray-500">IVA (16%)</span>
                    <span>${formatCurrency(totals.tax)}</span>
                  </div>
                  <div className="border-t pt-3">
                    <div className="flex justify-between font-semibold">
                      <span>Total</span>
                      <span className="text-lg">${formatCurrency(totals.total)}</span>
                    </div>
                  </div>
                  <div className="text-xs text-gray-400">
                    {lineItems.filter((l) => !l.isDeleted).length} linea(s) activa(s)
                  </div>
                </div>
              </CardContent>
            </Card>

            {/* Actions */}
            <Card>
              <CardContent className="pt-6">
                <div className="space-y-3">
                  <Button
                    type="submit"
                    className="w-full"
                    disabled={isSubmitting || !hasChanges}
                  >
                    {isSubmitting ? (
                      <>
                        <Spinner size="sm" className="mr-2" />
                        Guardando...
                      </>
                    ) : (
                      <>
                        <Save className="mr-2 h-4 w-4" />
                        Guardar Cambios
                      </>
                    )}
                  </Button>
                  <Button
                    type="button"
                    variant="outline"
                    className="w-full"
                    onClick={() => navigate(`/sales/quotations/${id}`)}
                    disabled={isSubmitting}
                  >
                    Cancelar
                  </Button>
                </div>
                {!hasChanges && (
                  <p className="mt-3 text-center text-xs text-gray-400">
                    No hay cambios para guardar
                  </p>
                )}
              </CardContent>
            </Card>

            {/* Status Info */}
            <Card>
              <CardContent className="pt-6">
                <div className="text-center">
                  <span className="inline-flex items-center rounded-full bg-gray-100 px-3 py-1 text-sm font-medium text-gray-700">
                    Estado: Borrador
                  </span>
                  <p className="mt-2 text-xs text-gray-500">
                    Solo las cotizaciones en estado borrador pueden ser editadas
                  </p>
                </div>
              </CardContent>
            </Card>
          </div>
        </div>
      </form>
    </div>
  );
}

export default QuotationEditPage;
