import React, { useState, useEffect, useMemo } from 'react';
import { Table, Panel, Modal, Form, FormGroup, Input, FileUploader, Checkbox, Button } from '@bigcommerce/big-design';
import { EditIcon, DeleteIcon } from '@bigcommerce/big-design-icons';
import { getPartImageUrl, getPartThumbUrl } from '../lib/client/imageUtils';

const HosePartsTable = ({ tableItems, itemName, PartID }: { tableItems: any, itemName: string, PartID: string }) => {

    const [currentPage, setCurrentPage] = useState(1);
    const [itemsPerPageOptions] = useState([5, 10, 20, 30]);
    const [itemsPerPage, setItemsPerPage] = useState(5);
    const [currentItems, setCurrentItems] = useState([]);
    const [isAddOpen, setIsAddOpen] = useState(false);
    const [isEditOpen, setIsEditOpen] = useState(false);
    const [files, setFiles] = useState([]);
    const [thumbnailFiles, setThumbnailFiles] = useState([]);
    const [code, setCode] = useState('');
    const [prefix, setPrefix] = useState(' ');
    const [label, setLabel] = useState('');
    const [length, setLength] = useState('');
    const [isSwivelCompatible, setIsSwivelCompatible] = useState(false);
    const [partEntityId, setPartEntityId] = useState('');

    const validateFileSize = (file: File) => {
        const MB = 1024 * 1024;
    
        return file.size <= MB;
      };

    const columns = useMemo(() => {
        let actionColumn = {
            header: 'Action',
            hash: 'action',
            render: (value: any) => (
                <div>
                    <Button 
                        variant="subtle" 
                        iconOnly={<DeleteIcon />}
                        aria-label="Delete option value"
                        onClick={() => handleDelete(value.id)}
                    />
                    <Button 
                        variant="subtle" 
                        iconOnly={<EditIcon />}
                        aria-label="Edit option value"
                        onClick={() => handleEdit(value)}
                    />
                </div>
            )
        }

        if (!tableItems.length) return [];

        const mapped = Object.keys(tableItems[0]).map((key) => {
            // Do not show the raw thumbnail filename column
            if (key === 'thumbnail') {
                return null;
            }
            if (key === 'image') {
                return {
                    header: 'Image',
                    hash: 'image',
                    render: (item) => (
                        <img
                            src={getPartImageUrl(item[key])}
                            alt={item[key]}
                            style={{ objectFit: 'cover', borderRadius: '5px', border: '1px solid #ccc', width: '50px', height: '50px' }}
                        />
                    ),
                }
            }

            if (key === 'prefix') {
                return {
                    header: 'Prefix',
                    hash: 'prefix',
                    render: (item) => item[key] === 'null' ? ' ' : item[key],
                }
            }
            return {
                header: key.replace(/_/g, ' ').replace(/\b\w/g, c => c.toUpperCase()),
                hash: key,
                render: (item) => item[key],
            }
        });

        return [...mapped.filter(Boolean) as any[], actionColumn];
    }, [tableItems]);
    const displayColumns = useMemo(
        () => (itemName === 'Outlet' ? columns.filter((c: any) => c && c.hash !== 'is_swivel_compatible') : columns),
        [columns, itemName]
    );

    
    const onItemsPerPageChange = (newRange) => {
        setCurrentPage(1);
        setItemsPerPage(newRange);
    };

    const handleSubmit = async (e: React.FormEvent) => {
        e.preventDefault();
        try {
            const formData = new FormData();
            formData.append('part_id', PartID);
            formData.append('code', code);
            formData.append('prefix', prefix);
            formData.append('label', label);
            formData.append('length', length);
            formData.append('isSwivelCompatible', PartID === 'hose_outlet' ? 'true' : String(isSwivelCompatible));
            if (files.length > 0) {
                formData.append('image', files[0]);
            }
            if (thumbnailFiles.length > 0) {
                formData.append('thumbnail', thumbnailFiles[0]);
            }

            const response = await fetch('/api/hose/parts', {
                method: 'POST',
                body: formData,
            });

            let data: any = null;
            try {
                data = await response.json();
            } catch (_) {
                data = null;
            }

            if (!response.ok || (data && data.error)) {
                console.error('Error submitting form:', (data && data.error) || response.statusText);
                return;
            }

            if (data && data.tableItems) {
                setCurrentItems(data.tableItems);
            }

            setCode('');
            setPrefix(' ');
            setLabel('');
            setLength('');
            setIsSwivelCompatible(false);
            setFiles([]);
            setThumbnailFiles([]);
            setIsAddOpen(false);
        } catch (error) {
            console.error('Error submitting form:', error);
        }
    };

    const handleEditSubmit = async (e: React.FormEvent) => {
        e.preventDefault();
        try {
            const formData = new FormData();
            formData.append('entity_id', partEntityId);
            formData.append('part_id', PartID);
            formData.append('code', code);
            formData.append('prefix', prefix);
            formData.append('label', label);
            formData.append('length', length);
            formData.append('isSwivelCompatible', PartID === 'hose_outlet' ? 'true' : String(isSwivelCompatible));
            if (files.length > 0) {
                formData.append('image', files[0]);
            }
            if (thumbnailFiles.length > 0) {
                formData.append('thumbnail', thumbnailFiles[0]);
            }

            await fetch('/api/hose/parts', {
                method: 'PUT',
                body: formData,
            }).then((response) => {
                setIsEditOpen(false);
                response.json().then((data) => {
                    setCurrentItems(data.tableItems);
                });
            });
        } catch (error) {
            console.error('Error submitting form:', error);
        }
    };
    
    const handleDelete = async (id: string) => {
        try {
            const deleteData = {
                id: id,
                part_id: PartID
            }

            await fetch(`/api/hose/parts`, {
                method: 'DELETE',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify(deleteData),
            }).then((response) => {
                response.json().then((data) => {
                    setCurrentItems(data.tableItems);
                }); 
            });
        } catch (error) {
            console.error('Error deleting item:', error);
        }
    };

    const handleEdit = async (PartDetail: any) => {
        console.log(PartDetail);
        setPartEntityId(PartDetail.id);
        setCode(PartDetail.code);
        setPrefix(PartDetail.prefix === 'null' ? ' ' : PartDetail.prefix);
        setLabel(PartDetail.label);
        setLength(PartDetail.value_ft);
        setIsSwivelCompatible(PartDetail.is_swivel_compatible);
        setIsEditOpen(true);

        if (PartDetail.image) {
            const url = getPartImageUrl(PartDetail.image);
            const response = await fetch(url);
            if (response.status === 200) {
                const blob = await response.blob();
                const name = url.split('/').pop() || 'downloaded-file';
                const file = new File([blob], name, { type: blob.type });
                setFiles([file]);
            }
        } else {
            setFiles([]);
        }

        // Prefill thumbnail if available, else try generated thumb from image
        if (PartDetail.thumbnail) {
            const turl = getPartThumbUrl(PartDetail.thumbnail);
            const tres = await fetch(turl);
            if (tres.status === 200) {
                const blob = await tres.blob();
                const name = turl.split('/').pop() || 'downloaded-thumb';
                const file = new File([blob], name, { type: blob.type });
                setThumbnailFiles([file]);
            } else {
                setThumbnailFiles([]);
            }
        } else if (PartDetail.image) {
            const turl = getPartThumbUrl(PartDetail.image);
            const tres = await fetch(turl);
            if (tres.status === 200) {
                const blob = await tres.blob();
                const name = turl.split('/').pop() || 'downloaded-thumb';
                const file = new File([blob], name, { type: blob.type });
                setThumbnailFiles([file]);
            } else {
                setThumbnailFiles([]);
            }
        } else {
            setThumbnailFiles([]);
        }
    };
    
    useEffect(() => {
        const maxItems = currentPage * itemsPerPage;
        const lastItem = Math.min(maxItems, tableItems.length);
        const firstItem = Math.max(0, maxItems - itemsPerPage);
    
        setCurrentItems(tableItems.slice(firstItem, lastItem));
    }, [currentPage, itemsPerPage]);

    return (
        <Panel
        action={{
                variant: 'secondary',
                text: 'Add',
                onClick: () => {
                    setIsAddOpen(true)
                },
            }}
            //   description="This is the panel's optional description."
            header={itemName}
        >
            {tableItems.length > 0 && (
            <div style={{ overflowX: 'auto', WebkitOverflowScrolling: 'touch' }}>
                <Table
                    columns={displayColumns}
                    keyField="sku"
                    items={currentItems}
                    pagination={{
                        currentPage,
                        totalItems: tableItems.length,
                        onPageChange: setCurrentPage,
                        itemsPerPageOptions,
                        onItemsPerPageChange,
                        itemsPerPage,
                    }}
                    stickyHeader
                />
            </div>
            )}
            <Modal
                actions={[
                {
                    text: 'Cancel',
                    variant: 'subtle',
                    onClick: () => setIsAddOpen(false),
                },
                { text: 'Add', onClick: () =>
                    (document.getElementById("add-form") as HTMLFormElement)?.requestSubmit()
                },
                ]}
                closeOnClickOutside={false}
                closeOnEscKey={true}
                header={`Add ${itemName}`}
                isOpen={isAddOpen}
                onClose={() => setIsAddOpen(false)}
            >
                <Form fullWidth={true} onSubmit={handleSubmit} id="add-form">
                    <FormGroup>
                        <Input label="Code" placeholder="Part Code" required value={code} onChange={e => setCode(e.target.value)} />
                        {itemName !== "Standard" && itemName !== "Length" && (
                            <Input label="Prefix" placeholder="Part Prefix" value={prefix} onChange={e => setPrefix(e.target.value)} />
                        )}
                    </FormGroup>
                    <FormGroup>
                        <Input label="Label" placeholder="Part Label" required value={label} onChange={e => setLabel(e.target.value)} />
                        {itemName == "Length" && (
                            <Input label="Length" placeholder="Hose Length(ft)" required value={length} onChange={e => setLength(e.target.value)} />
                        )}
                    </FormGroup>
                    { (itemName == "Inlet") && (
                        <FormGroup>
                            <Checkbox checked={isSwivelCompatible} label="Is Swivel Comptabile" onChange={() => setIsSwivelCompatible(v => !v)} />
                        </FormGroup>
                    )}
                    {itemName !== "Length" && (
                    <>
                    <FormGroup>
                        <FileUploader
                        dropzoneConfig={{
                            label: 'Drag and drop image here'
                        }}
                        files={files}
                        label="Part Image"
                        multiple ={false}
                        onFilesChange={setFiles}
                        required
                        validators={[
                            {
                            validator: validateFileSize,
                            type: 'file-size',
                            },
                        ]}
                        />
                    </FormGroup>
                    <FormGroup>
                        <FileUploader
                        dropzoneConfig={{
                            label: 'Drag and drop thumbnail here'
                        }}
                        files={thumbnailFiles}
                        label="Thumbnail Image"
                        multiple ={false}
                        onFilesChange={setThumbnailFiles}
                        validators={[
                            {
                            validator: validateFileSize,
                            type: 'file-size',
                            },
                        ]}
                        />
                    </FormGroup>
                    </>
                    )}
                </Form>
            </Modal>
            <Modal
                actions={[
                {
                    text: 'Cancel',
                    variant: 'subtle',
                    onClick: () => setIsEditOpen(false),
                },
                { text: 'Edit', onClick: () =>
                    (document.getElementById("edit-form") as HTMLFormElement)?.requestSubmit()
                },
                ]}
                closeOnClickOutside={false}
                closeOnEscKey={true}
                header={`Edit ${itemName}`}
                isOpen={isEditOpen}
                onClose={() => setIsEditOpen(false)}
            >
                <Form fullWidth={true} onSubmit={handleEditSubmit} id="edit-form">
                    <input type='hidden' name='id' value={partEntityId} onChange={e => setPartEntityId(e.target.value)} />
                    <FormGroup>
                        <Input label="Code" placeholder="Part Code" required value={code} onChange={e => setCode(e.target.value)} />
                        {itemName !== "Standard" && itemName !== "Length" && (
                            <Input label="Prefix" placeholder="Part Prefix" value={prefix} onChange={e => setPrefix(e.target.value)} />
                        )}
                    </FormGroup>
                    <FormGroup>
                        <Input label="Label" placeholder="Part Label" required value={label} onChange={e => setLabel(e.target.value)} />
                        {itemName == "Length" && (
                            <Input label="Length" placeholder="Hose Length(ft)" required value={length} onChange={e => setLength(e.target.value)} />
                        )}
                    </FormGroup>
                    { (itemName == "Inlet") && (
                        <FormGroup>
                            <Checkbox checked={isSwivelCompatible} label="Is Swivel Comptabile" onChange={() => setIsSwivelCompatible(v => !v)} />
                        </FormGroup>
                    )}
                    {itemName !== "Length" && (
                        <>
                        <FormGroup>
                            <FileUploader
                            dropzoneConfig={{
                                label: 'Drag and drop image here'
                            }}
                        files={files}
                        label="Part Image"
                        multiple ={false}
                        onFilesChange={setFiles}
                        required
                        validators={[
                            {
                            validator: validateFileSize,
                            type: 'file-size',
                            },
                        ]}
                        />
                    </FormGroup>
                    <FormGroup>
                        <FileUploader
                        dropzoneConfig={{
                            label: 'Drag and drop thumbnail here'
                        }}
                        files={thumbnailFiles}
                        label="Thumbnail Image"
                        multiple ={false}
                        onFilesChange={setThumbnailFiles}
                        validators={[
                            {
                            validator: validateFileSize,
                            type: 'file-size',
                            },
                        ]}
                        />
                    </FormGroup>
                    </>
                    )}
                </Form>
            </Modal>
        </Panel>
    );
};
export default HosePartsTable;
