import React from 'react';
import {
    Container, Typography, List, ListItem, IconButton, TextField, Box, ListItemText, ListItemSecondaryAction, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, Button
} from '@mui/material';
import DeleteIcon from '@mui/icons-material/Delete';
import EditIcon from '@mui/icons-material/Edit';
import SaveIcon from '@mui/icons-material/Save';
import AddIcon from '@mui/icons-material/Add';
import { AddressesService } from '../../openapi';
import type { Address, AddressCreate, AddressUpdate } from '../models/Address';

const AddressManager: React.FC = () => {
    const [addresses, setAddresses] = React.useState<Address[]>([]);
    const [newAddress, setNewAddress] = React.useState<Partial<Address>>({
        street: '',
        city: '',
        zipcode: '',
        country: '',
    });
    const [editAddressId, setEditAddressId] = React.useState<number | null>(null);
    const [errorMessage, setErrorMessage] = React.useState<string | null>(null);
    const [dialogOpen, setDialogOpen] = React.useState(false);
    const [selectedAddress, setSelectedAddress] = React.useState<Address | null>(null);

    React.useEffect(() => {
        const fetchAddresses = async () => {
            try {
                const response = await AddressesService.getReturnAddressesAddressesGet();
                setAddresses(response);
            } catch (error) {
                console.error('Failed to fetch addresses', error);
                setErrorMessage('Failed to load addresses. Please try again later.');
            }
        };

        fetchAddresses();
    }, []);

    const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
        const { name, value } = event.target;
        setNewAddress({ ...newAddress, [name]: value });
    };

    const handleAddOrUpdateAddress = async () => {
        try {
            if (editAddressId !== null) {
                // Update address
                await AddressesService.updateReturnAddressAddressesAddressIdPut(editAddressId, newAddress as AddressUpdate);
                setAddresses(addresses.map(address => address.id === editAddressId ? { ...address, ...newAddress } : address));
                setEditAddressId(null);
            } else {
                // Add new address
                const response = await AddressesService.createReturnAddressAddressesPost(newAddress as AddressCreate);
                setAddresses([...addresses, response]);
            }
            setNewAddress({ street: '', city: '', zipcode: '', country: '' });
            setErrorMessage(null);
        } catch (error) {
            console.error('Failed to add/update address', error);
            setErrorMessage('Failed to add/update address. Please try again later.');
        }
    };

    const handleDeleteAddress = async (id: number) => {
        try {
            await AddressesService.deleteReturnAddressAddressesAddressIdDelete(id);
            setAddresses(addresses.filter(address => address.id !== id));
        } catch (error) {
            console.error('Failed to delete address', error);
            setErrorMessage('Failed to delete address. Please try again later.');
        }
    };

    const handleEditAddress = (address: Address) => {
        setEditAddressId(address.id);
        setNewAddress(address);
    };

    const openDialog = (address: Address) => {
        setSelectedAddress(address);
        setDialogOpen(true);
    };

    const closeDialog = () => {
        setDialogOpen(false);
        setSelectedAddress(null);
    };

    const confirmDelete = async () => {
        if (selectedAddress) {
            await handleDeleteAddress(selectedAddress.id);
            closeDialog();
        }
    };

    return (
        <Container>
            <Typography variant="h4" gutterBottom>
                Addresses Management
            </Typography>
            <Box display="flex" justifyContent="center" alignItems="center" mb={3}>
                <TextField label="Street" name="street" value={newAddress.street || ''} onChange={handleInputChange} />
                <TextField label="City" name="city" value={newAddress.city || ''} onChange={handleInputChange} />
                <TextField label="Zipcode" name="zipcode" value={newAddress.zipcode || ''} onChange={handleInputChange} />
                <TextField label="Country" name="country" value={newAddress.country || ''} onChange={handleInputChange} />
                <IconButton color="primary" onClick={handleAddOrUpdateAddress}>
                    {editAddressId !== null ? <SaveIcon /> : <AddIcon />}
                </IconButton>
            </Box>
            {errorMessage && <Typography color="error">{errorMessage}</Typography>}
            <List>
                {addresses.length > 0 ? (
                    addresses.map((address) => (
                        <ListItem key={address.id} button>
                            <ListItemText
                                primary={`${address.street}, ${address.city}`}
                                secondary={`${address.zipcode} - ${address.country}`}
                            />
                            <ListItemSecondaryAction>
                                <IconButton edge="end" color="primary" onClick={() => handleEditAddress(address)}>
                                    <EditIcon />
                                </IconButton>
                                <IconButton edge="end" color="secondary" onClick={() => openDialog(address)}>
                                    <DeleteIcon />
                                </IconButton>
                            </ListItemSecondaryAction>
                        </ListItem>
                    ))
                ) : (
                    <Typography>No addresses found</Typography>
                )}
            </List>
            <Dialog
                open={dialogOpen}
                onClose={closeDialog}
                aria-labelledby="alert-dialog-title"
                aria-describedby="alert-dialog-description"
            >
                <DialogTitle id="alert-dialog-title">{"Confirm Delete"}</DialogTitle>
                <DialogContent>
                    <DialogContentText id="alert-dialog-description">
                        Are you sure you want to delete this address?
                    </DialogContentText>
                </DialogContent>
                <DialogActions>
                    <Button onClick={closeDialog} color="primary">
                        Cancel
                    </Button>
                    <Button onClick={confirmDelete} color="secondary" autoFocus>
                        Delete
                    </Button>
                </DialogActions>
            </Dialog>
        </Container>
    );
};

export default AddressManager;