import React, { useState, useCallback, useRef } from 'react';
import { Modal, Button, Form, Row, Col, Spinner } from 'react-bootstrap';
import { Upload, X, FileText, CheckCircle } from 'lucide-react';
import axios from 'axios';
import Swal from 'sweetalert2';
import { useTiposDocumento } from '../hooks/useTiposDocumento';
import MultiSelectContratos from './MultiSelectContratos';
import {
    PROPUESTA_DOC_ACCEPT,
    PROPUESTA_DOC_FORMATOS_TEXTO,
    PROPUESTA_DOC_MAX_BYTES,
    PROPUESTA_DOC_MAX_LABEL_COMPACT,
    PROPUESTA_DOC_MAX_LABEL_SPACED,
    isPropuestaDocumentFileAllowed,
} from '../../../../../utils/propuestaDocumentFileRules';

interface Comercializadora {
    CodCom: number;
    NomCom: string;
}

interface ContratoAsociado {
    id: number;
    NumCon: string;
    label: string;
    tipo: 'LUZ' | 'GAS';
    CodCups: string;
}

interface UploadDocumentoModalProps {
    show: boolean;
    onHide: () => void;
    codProCom: number;
    comercializadorasUnicas: Comercializadora[];
    contratosAsociados: ContratoAsociado[];
    onSuccess?: () => void;
    showLoading: () => void;
    hideLoading: () => void;
}

const UploadDocumentoModal: React.FC<UploadDocumentoModalProps> = ({
    show,
    onHide,
    codProCom,
    comercializadorasUnicas,
    contratosAsociados,
    onSuccess,
    showLoading,
    hideLoading
}) => {
    const [archivo, setArchivo] = useState<File | null>(null);
    const [codCom, setCodCom] = useState<string>('');
    const [tipoDoc, setTipoDoc] = useState<string>('');
    const [observaciones, setObservaciones] = useState<string>('');
    const [selectedContratos, setSelectedContratos] = useState<ContratoAsociado[]>([]);
    const [isDragging, setIsDragging] = useState(false);
    const [isUploading, setIsUploading] = useState(false);
    const fileInputRef = useRef<HTMLInputElement>(null);

    // Hook para obtener tipos de documento desde el backend
    const { tiposDocumento, loading: loadingTipos, error: errorTipos } = useTiposDocumento();

    const resetForm = () => {
        setArchivo(null);
        setCodCom('');
        setTipoDoc('');
        setObservaciones('');
        setSelectedContratos([]);
    };

    const handleClose = () => {
        resetForm();
        onHide();
    };

    const handleDragEnter = useCallback((e: React.DragEvent) => {
        e.preventDefault();
        e.stopPropagation();
        setIsDragging(true);
    }, []);

    const handleDragLeave = useCallback((e: React.DragEvent) => {
        e.preventDefault();
        e.stopPropagation();
        setIsDragging(false);
    }, []);

    const handleDragOver = useCallback((e: React.DragEvent) => {
        e.preventDefault();
        e.stopPropagation();
    }, []);

    const handleDrop = useCallback((e: React.DragEvent) => {
        e.preventDefault();
        e.stopPropagation();
        setIsDragging(false);

        const files = e.dataTransfer.files;
        if (files && files.length > 0) {
            const file = files[0];
            if (!isPropuestaDocumentFileAllowed(file)) {
                Swal.fire({
                    icon: 'warning',
                    title: 'Tipo de archivo no permitido',
                    text: `Formatos permitidos: ${PROPUESTA_DOC_FORMATOS_TEXTO}`,
                    timer: 3000,
                    showConfirmButton: false
                });
                return;
            }
            if (file.size > PROPUESTA_DOC_MAX_BYTES) {
                Swal.fire({
                    icon: 'warning',
                    title: 'Archivo demasiado grande',
                    text: `El tamaño máximo permitido es ${PROPUESTA_DOC_MAX_LABEL_SPACED}.`,
                    timer: 3000,
                    showConfirmButton: false
                });
                return;
            }
            setArchivo(file);
        }
    }, []);

    const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
        const files = e.target.files;
        if (files && files.length > 0) {
            const file = files[0];
            if (!isPropuestaDocumentFileAllowed(file)) {
                Swal.fire({
                    icon: 'warning',
                    title: 'Tipo de archivo no permitido',
                    text: `Formatos permitidos: ${PROPUESTA_DOC_FORMATOS_TEXTO}`,
                    timer: 3000,
                    showConfirmButton: false
                });
                e.target.value = '';
                return;
            }
            if (file.size > PROPUESTA_DOC_MAX_BYTES) {
                Swal.fire({
                    icon: 'warning',
                    title: 'Archivo demasiado grande',
                    text: `El tamaño máximo permitido es ${PROPUESTA_DOC_MAX_LABEL_SPACED}.`,
                    timer: 3000,
                    showConfirmButton: false
                });
                e.target.value = '';
                return;
            }
            setArchivo(file);
        }
    };

    const handleClickDropzone = () => {
        fileInputRef.current?.click();
    };

    const handleRemoveFile = () => {
        setArchivo(null);
        if (fileInputRef.current) {
            fileInputRef.current.value = '';
        }
    };

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

        if (!archivo) {
            Swal.fire({
                icon: 'warning',
                title: 'Archivo requerido',
                text: 'Por favor, selecciona un archivo para cargar',
                timer: 2500,
                showConfirmButton: false
            });
            return;
        }

        /*if (!codCom) {
            Swal.fire({
                icon: 'warning',
                title: 'Comercializadora requerida',
                text: 'Por favor, selecciona una comercializadora',
                timer: 2500,
                showConfirmButton: false
            });
            return;
        }*/

        if (!tipoDoc) {
            Swal.fire({
                icon: 'warning',
                title: 'Tipo de documento requerido',
                text: 'Por favor, selecciona un tipo de documento',
                timer: 2500,
                showConfirmButton: false
            });
            return;
        }

        if (archivo.size > PROPUESTA_DOC_MAX_BYTES) {
            Swal.fire({
                icon: 'warning',
                title: 'Archivo demasiado grande',
                text: `El tamaño máximo permitido es ${PROPUESTA_DOC_MAX_LABEL_SPACED}.`,
                timer: 3000,
                showConfirmButton: false
            });
            return;
        }

        setIsUploading(true);
        showLoading();

        try {
            // 1. Cargar el archivo
            const formData = new FormData();
            formData.append('archivo', archivo);
            //formData.append('CodCom', codCom);
            formData.append('observaciones', observaciones || '-');
            formData.append('CodProCom', codProCom.toString());
            formData.append('TipDoc', tipoDoc);

            const uploadResponse = await axios.post('/api/v1/files/saveFile', formData, {
                headers: {
                    'Content-Type': 'multipart/form-data',
                },
            });

            if (!uploadResponse.data.success && uploadResponse.status !== 200 && uploadResponse.status !== 201) {
                throw new Error(uploadResponse.data.message || 'Error al cargar el documento');
            }

            // 2. Si hay contratos seleccionados, asociarlos al documento
            /*
            if (selectedContratos.length > 0 && uploadResponse.data.data) {
                const documentData = uploadResponse.data.data;

                // Construir el array de documentos según el formato requerido
                const documents = selectedContratos.map(contrato => ({
                    cod_com: parseInt(codCom),
                    documentId: documentData.id,
                    numeroContrato: parseInt(contrato.NumCon),
                    tipoContrato: contrato.tipo,
                    CodProCom: codProCom
                }));

                // Enviar la asociación de documentos
                const associationResponse = await axios.post(
                    route('v1.contracts.documentContract'),
                    { documents },
                    {
                        headers: {
                            'Content-Type': 'application/json',
                        }
                    }
                );

                // Verificar respuesta de asociación
                if (!associationResponse.data.success && associationResponse.status !== 200 && associationResponse.status !== 201) {
                    console.warn('Advertencia al asociar documentos:', associationResponse.data);
                }
            }*/

            hideLoading();
            setIsUploading(false);

           /* Swal.fire({
                icon: 'success',
                title: '¡Documento cargado!',
                text: selectedContratos.length > 0
                    ? `El documento se ha cargado y asociado a ${selectedContratos.length} contrato(s)`
                    : 'El documento se ha cargado correctamente',
                timer: 2500,
                showConfirmButton: false
            });*/
            handleClose();
            onSuccess?.();

        } catch (error: any) {
            hideLoading();
            setIsUploading(false);
            console.error('Error al cargar documento:', error);
            const status = error.response?.status;
            let text =
                error.response?.data?.message ||
                error.message ||
                'Error al cargar el documento';
            if (status === 413) {
                text =
                    'El servidor rechazó el archivo por tamaño (HTTP 413). php.ini no basta: en Apache2 revise LimitRequestBody en el VirtualHost o public/.htaccess, y si usa mod_fcgid (FcgidMaxRequestLen) o ModSecurity (SecRequestBodyLimit). Ejemplos en deploy/apache-upload-limits.conf.example.';
            }
            Swal.fire({
                icon: 'error',
                title: 'Error',
                text,
                confirmButtonText: 'Aceptar',
            });
        }
    };

    const formatFileSize = (bytes: number): string => {
        if (bytes === 0) return '0 Bytes';
        const k = 1024;
        const sizes = ['Bytes', 'KB', 'MB', 'GB'];
        const i = Math.floor(Math.log(bytes) / Math.log(k));
        return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
    };

    return (
        <Modal show={show} onHide={handleClose} centered size="xl">
            <Modal.Header closeButton className="border-0 pb-0">
                <Modal.Title className="d-flex align-items-center gap-2">
                    <Upload size={24} className="text-primary" />
                    Cargar Documento
                </Modal.Title>
            </Modal.Header>

            <Form onSubmit={handleSubmit}>
                <Modal.Body className="pt-3">
                    {/* Dropzone */}
                    <div
                        className={`border-2 border-dashed rounded-3 p-4 text-center mb-4 transition-all ${
                            isDragging
                                ? 'border-primary bg-primary bg-opacity-10'
                                : archivo
                                ? 'border-success bg-success bg-opacity-10'
                                : 'border-secondary'
                        }`}
                        style={{
                            cursor: 'pointer',
                            minHeight: '140px',
                            display: 'flex',
                            flexDirection: 'column',
                            alignItems: 'center',
                            justifyContent: 'center',
                            borderStyle: 'dashed',
                            borderWidth: '2px',
                        }}
                        onDragEnter={handleDragEnter}
                        onDragLeave={handleDragLeave}
                        onDragOver={handleDragOver}
                        onDrop={handleDrop}
                        onClick={!archivo ? handleClickDropzone : undefined}
                    >
                        <input
                            type="file"
                            ref={fileInputRef}
                            onChange={handleFileSelect}
                            accept={PROPUESTA_DOC_ACCEPT}
                            style={{ display: 'none' }}
                        />

                        {archivo ? (
                            <div className="d-flex flex-column align-items-center">
                                <div className="d-flex align-items-center gap-3 mb-2">
                                    <CheckCircle size={40} className="text-success" />
                                    <div className="text-start">
                                        <p className="mb-0 fw-semibold text-dark">{archivo.name}</p>
                                        <small className="text-muted">{formatFileSize(archivo.size)}</small>
                                    </div>
                                </div>
                                <Button
                                    variant="outline-danger"
                                    size="sm"
                                    onClick={(e) => {
                                        e.stopPropagation();
                                        handleRemoveFile();
                                    }}
                                    className="mt-2"
                                >
                                    <X size={16} className="me-1" />
                                    Quitar archivo
                                </Button>
                            </div>
                        ) : (
                            <>
                                <Upload
                                    size={40}
                                    className={isDragging ? 'text-primary' : 'text-muted'}
                                />
                                <p className="mt-2 mb-1 fw-semibold">
                                    {isDragging ? 'Suelta el archivo aquí' : 'Arrastra y suelta tu archivo aquí'}
                                </p>
                                <p className="text-muted mb-0">
                                    o <span className="text-primary" style={{ cursor: 'pointer' }}>haz clic para seleccionar</span>
                                </p>
                                <small className="text-muted mt-1">
                                    Formatos permitidos: {PROPUESTA_DOC_FORMATOS_TEXTO} (máx. {PROPUESTA_DOC_MAX_LABEL_COMPACT})
                                </small>
                            </>
                        )}
                    </div>

                    {/* Layout de dos columnas */}
                    <Row className="g-4">
                        {/* COLUMNA IZQUIERDA: Datos del archivo */}
                        <Col md={12}>
                            <div className="border rounded p-3 h-100" style={{ backgroundColor: '#f8f9fa' }}>
                                <h6 className="fw-bold mb-3 text-primary">
                                    <FileText size={18} className="me-2" style={{ display: 'inline' }} />
                                    Datos del Documento
                                </h6>

                                {/*
                                <Form.Group className="mb-3">
                                    <Form.Label className="fw-semibold">
                                        Comercializadora <span className="text-danger">*</span>
                                    </Form.Label>
                                    <Form.Select
                                        value={codCom}
                                        onChange={(e) => setCodCom(e.target.value)}
                                        required
                                    >
                                        <option value="">Seleccionar comercializadora...</option>
                                        {comercializadorasUnicas.map((com) => (
                                            <option key={com.CodCom} value={com.CodCom}>
                                                {com.NomCom}
                                            </option>
                                        ))}
                                    </Form.Select>
                                </Form.Group>
                                */}

                                <Form.Group className="mb-3">
                                    <Form.Label className="fw-semibold">
                                        Tipo de Documento <span className="text-danger">*</span>
                                    </Form.Label>
                                    {loadingTipos ? (
                                        <div className="d-flex align-items-center gap-2 py-2">
                                            <Spinner animation="border" size="sm" />
                                            <span className="text-muted">Cargando tipos...</span>
                                        </div>
                                    ) : errorTipos ? (
                                        <div className="text-danger small">{errorTipos}</div>
                                    ) : (
                                        <Form.Select
                                            value={tipoDoc}
                                            onChange={(e) => setTipoDoc(e.target.value)}
                                            required
                                        >
                                            <option value="">Seleccionar tipo...</option>
                                            {tiposDocumento.map((tipo) => (
                                                <option key={tipo.value} value={tipo.value}>
                                                    {tipo.label}
                                                </option>
                                            ))}
                                        </Form.Select>
                                    )}
                                </Form.Group>

                                <Form.Group className="mb-3">
                                    <Form.Label className="fw-semibold">Observaciones</Form.Label>
                                    <Form.Control
                                        as="textarea"
                                        rows={4}
                                        value={observaciones}
                                        onChange={(e) => setObservaciones(e.target.value)}
                                        placeholder="Ingresa observaciones adicionales (opcional)"
                                    />
                                </Form.Group>

                                {/* Info de la propuesta */}
                                <div className="mt-3 p-2 bg-white rounded border">
                                    <small className="text-muted d-flex align-items-center gap-2">
                                        <FileText size={14} />
                                        Propuesta Comercial: <strong>#{codProCom}</strong>
                                    </small>
                                </div>
                            </div>
                        </Col>

                        {/* COLUMNA DERECHA: Selector de contratos */}
                        {/*}
                        <Col md={6}>
                            <div className="border rounded p-3 h-100" style={{ backgroundColor: '#f8f9fa' }}>
                                <h6 className="fw-bold mb-3 text-primary">
                                    <FileText size={18} className="me-2" style={{ display: 'inline' }} />
                                    Contratos Asociados
                                </h6>

                                {contratosAsociados.length > 0 ? (
                                    <>
                                        <MultiSelectContratos
                                            contratos={contratosAsociados}
                                            onSelectionChange={setSelectedContratos}
                                        />
                                        <Form.Text className="text-muted d-block mt-2">
                                            Selecciona los contratos a los que deseas asociar este documento
                                        </Form.Text>
                                    </>
                                ) : (
                                    <div className="text-center text-muted py-5">
                                        <FileText size={48} className="mb-2 opacity-50" />
                                        <p className="mb-0">No hay contratos asociados a esta propuesta</p>
                                    </div>
                                )}
                            </div>
                        </Col>
                        */}
                    </Row>
                </Modal.Body>

                <Modal.Footer className="border-0 pt-0">
                    <Button variant="outline-secondary" onClick={handleClose} disabled={isUploading}>
                        Cancelar
                    </Button>
                    <Button
                        variant="primary"
                        type="submit"
                        disabled={isUploading || !archivo}
                        className="d-flex align-items-center gap-2"
                    >
                        <Upload size={18} />
                        {isUploading ? 'Cargando...' : 'Cargar Documento'}
                    </Button>
                </Modal.Footer>
            </Form>
        </Modal>
    );
};

export default UploadDocumentoModal;
