import React from 'react';
import {
  Stack,
  Button,
  Grid,
  InputLabel,
  TextField,
  Typography,
  IconButton,
  Tooltip,
  Dialog,
  DialogTitle,
  DialogContent,
  DialogActions,
  Box
} from '@mui/material';
import { ArrowLeftOutlined, PlusOutlined } from '@ant-design/icons';
import { useLocation, useNavigate } from 'react-router';
import { useFormik } from 'formik';
import * as Yup from 'yup';
import PropTypes from 'prop-types';
import OpenToast from 'components/third-party/OpenToast';
import MainCard from 'components/MainCard';
import AddressAutocomplete from 'components/third-party/AddressAutocomplete';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import { TimePicker } from '@mui/x-date-pickers/TimePicker';
import dayjs from 'dayjs';
import axios from 'axios';
import TitleCard from 'components/TitleCard';
import { getLoginUser } from 'supportFuctions/getLoginUser';

const normalizeTimeString = (value, fallback) => {
  if (!value) return fallback;

  if (typeof value === 'string') {
    const timeMatch = value.match(/(\d{1,2}):(\d{2})/);
    if (timeMatch) {
      const hours = timeMatch[1].padStart(2, '0');
      const minutes = timeMatch[2];
      return `${hours}:${minutes}`;
    }
  }

  const parsed = dayjs(value);
  return parsed.isValid() ? parsed.format('HH:mm') : fallback;
};

const getTimePickerValue = (timeString) => {
  if (!timeString) return null;
  const [hours, minutes] = String(timeString).split(':').map(Number);
  if (Number.isNaN(hours) || Number.isNaN(minutes)) return null;
  return dayjs().hour(hours).minute(minutes).second(0).millisecond(0);
};

const CreateLocation = ({ open, onClose, onSuccess, editLocationData, dialogMode = false }) => {
  const navigate = useNavigate();
  const routeLocation = useLocation();
  const editLocation = editLocationData ?? routeLocation.state;
  const isDialogMode = dialogMode || typeof open === 'boolean';

  const userdata = getLoginUser();
  


  const initialValues = {
    locationname: editLocation?.locationname || '',
    email: editLocation?.email || '',
    contactno: editLocation?.contactno || '',
    address: editLocation?.address || '',
    suburb: editLocation?.suburb || '',
    city: editLocation?.city || '',
    state: editLocation?.state || '',
    postcode: editLocation?.postcode || '',
    latitude: editLocation?.latitude || '',
    longitude: editLocation?.longitude || '',
    opentime: normalizeTimeString(editLocation?.opentime, '09:00'),
    closetime: normalizeTimeString(editLocation?.closetime, '22:00'),
    tenantid: +userdata?.tenantid || 0,
    applocationid: +userdata?.applocationid || 0,
    moduleid: +userdata?.moduleid || 0
  };

  const validationSchema = Yup.object({
    locationname: Yup.string().required('Location Name Required'),
    contactno: Yup.string()
      .required('Required')
      .matches(/^\d+$/, 'Only numbers are allowed')
      .min(10, 'Contact number must  10 digits')
      .max(10, 'Contact number must be  10 digits'),
    email: Yup.string().email('Invalid email').required('Required'),
    address: Yup.string().required('Address required'),
    suburb: Yup.string().required('Suburb required'),
    city: Yup.string().required('City required'),
    state: Yup.string().required('State required'),
    postcode: Yup.string().required('Postcode required').matches(/^\d+$/, 'Only numbers are allowed'),
    latitude: Yup.string()
      .required('Latitude required')
      .matches(/^-?\d+(\.\d+)?$/, 'Must Enter be a valid latitude'),
    longitude: Yup.string()
      .required('Longitude required')
      .matches(/^-?\d+(\.\d+)?$/, 'Must Enter be a valid longitude'),
    opentime: Yup.string().required('Opentime is required'),
    closetime: Yup.string().nullable().required('Closetime required')
  });

  const formik = useFormik({
    initialValues,
    enableReinitialize: true,
    validationSchema,
    onSubmit: async (values) => {
      if (editLocation) {
        const changedFields = {};
        Object.keys(values).forEach((key) => {
          if (values[key] !== formik.initialValues[key]) {
            changedFields[key] = values[key];
          }
        });
        changedFields.locationid = editLocation.locationid;

        try {
          const updateTenantLocation = await axios.put(`${process.env.REACT_APP_URL2}/tenants/updatetenantlocation`, changedFields);
          if (updateTenantLocation.data.status) {
            OpenToast(updateTenantLocation.data.message, 'success', 1500);
            onSuccess?.();
            if (isDialogMode) {
              onClose?.();
            } else {
              navigate('/locations');
            }
          } else {
            OpenToast(updateTenantLocation.data.message, 'error', 1500);
          }
        } catch (err) {
          OpenToast(err.message, 'error', 1500);
        }
      } else {
        try {
          const createTenantLocation = await axios.post(`${process.env.REACT_APP_URL2}/tenants/createtenantlocation`, values);
          if (createTenantLocation.data.status) {
            OpenToast(createTenantLocation.data.message, 'success', 1500);
            onSuccess?.();
            if (isDialogMode) {
              onClose?.();
            } else {
              navigate('/locations');
            }
          } else {
            OpenToast(createTenantLocation.data.message, 'error', 1500);
          }
        } catch (err) {
          OpenToast(err.message, 'error', 1500);
        }
      }
    }
  });

  const handleAddressSelect = (data) => {
    if (!data || !data.address) return;
    formik.setFieldValue('address', data?.address);
    formik.setFieldValue('suburb', data?.suburb);
    formik.setFieldValue('city', data?.city);
    formik.setFieldValue('state', data?.state);
    formik.setFieldValue('postcode', data?.postcode);
    formik.setFieldValue('latitude', data?.latitude);
    formik.setFieldValue('longitude', data?.longitude);
  };

  const formContent = (
    <Grid container spacing={2}>
      <Grid item xs={12} sm={4}>
        <InputLabel sx={{ mb: 1 }}>Location Name</InputLabel>
        <TextField
          name="locationname"
          placeholder="Enter Location name"
          fullWidth
          value={formik.values.locationname}
          onChange={formik.handleChange}
          error={formik.touched.locationname && Boolean(formik.errors.locationname)}
          helperText={formik.touched.locationname && formik.errors.locationname}
        />
      </Grid>
      <Grid item xs={12} sm={4}>
        <InputLabel sx={{ mb: 1 }}>Contact Number</InputLabel>
        <TextField
          name="contactno"
          type="number"
          placeholder="Enter Contact Number "
          fullWidth
          value={formik.values.contactno}
          onChange={(e) => {
            formik.setFieldValue('contactno', e.target.value.toString());
          }}
          error={formik.touched.contactno && Boolean(formik.errors.contactno)}
          helperText={formik.touched.contactno && formik.errors.contactno}
        />
      </Grid>
      <Grid item xs={12} sm={4}>
        <InputLabel sx={{ mb: 1 }}>Email</InputLabel>
        <TextField
          name="email"
          placeholder="Enter Email Id"
          fullWidth
          value={formik.values.email}
          onChange={formik.handleChange}
          error={formik.touched.email && Boolean(formik.errors.email)}
          helperText={formik.touched.email && formik.errors.email}
        />
      </Grid>
      <Grid item xs={12} sm={12}>
        <InputLabel sx={{ mb: 1 }}>Address</InputLabel>
        <AddressAutocomplete
          key={editLocation?.locationid || 'create-location-address'}
          onSelect={handleAddressSelect}
          addressvalue={editLocation?.address || null}
        />
        {formik.touched.address && formik.errors.address && (
          <Typography variant="caption" color="error">
            {formik.errors.address}
          </Typography>
        )}
      </Grid>
      <Grid item xs={12} sm={4}>
        <InputLabel sx={{ mb: 1 }}>Location</InputLabel>
        <TextField
          name="suburb"
          placeholder="Enter Location"
          fullWidth
          value={formik.values.suburb}
          onChange={formik.handleChange}
          error={formik.touched.suburb && Boolean(formik.errors.suburb)}
          helperText={formik.touched.suburb && formik.errors.suburb}
        />
      </Grid>
      <Grid item xs={12} sm={4}>
        <InputLabel sx={{ mb: 1 }}>City</InputLabel>
        <TextField
          name="city"
          placeholder="Enter City "
          fullWidth
          value={formik.values.city}
          onChange={formik.handleChange}
          error={formik.touched.city && Boolean(formik.errors.city)}
          helperText={formik.touched.city && formik.errors.city}
        />
      </Grid>
      <Grid item xs={12} sm={4}>
        <InputLabel sx={{ mb: 1 }}>State</InputLabel>
        <TextField
          name="state"
          placeholder="Enter State "
          fullWidth
          value={formik.values.state}
          onChange={formik.handleChange}
          error={formik.touched.state && Boolean(formik.errors.state)}
          helperText={formik.touched.state && formik.errors.state}
        />
      </Grid>
      <Grid item xs={12} sm={4}>
        <InputLabel sx={{ mb: 1 }}>PostCode</InputLabel>
        <TextField
          name="postcode"
          type="number"
          placeholder="Enter PostCode "
          fullWidth
          value={formik.values.postcode}
          onChange={(e) => {
            formik.setFieldValue('postcode', e.target.value.toString());
          }}
          error={formik.touched.postcode && Boolean(formik.errors.postcode)}
          helperText={formik.touched.postcode && formik.errors.postcode}
        />
      </Grid>

      <Grid item xs={12} sm={4}>
        <InputLabel sx={{ mb: 1 }}>Latitude</InputLabel>
        <TextField
          name="latitude"
          type="number"
          placeholder="Enter Latitude "
          fullWidth
          value={formik.values.latitude}
          onChange={(e) => {
            formik.setFieldValue('latitude', e.target.value.toString());
          }}
          error={formik.touched.latitude && Boolean(formik.errors.latitude)}
          helperText={formik.touched.latitude && formik.errors.latitude}
        />
      </Grid>
      <Grid item xs={12} sm={4}>
        <InputLabel sx={{ mb: 1 }}>Longitude</InputLabel>
        <TextField
          name="longitude"
          type="number"
          placeholder="Enter Longitude "
          fullWidth
          value={formik.values.longitude}
          onChange={(e) => {
            formik.setFieldValue('longitude', e.target.value.toString());
          }}
          error={formik.touched.longitude && Boolean(formik.errors.longitude)}
          helperText={formik.touched.longitude && formik.errors.longitude}
        />
      </Grid>
      <Grid item xs={12} sm={6}>
        <InputLabel sx={{ mb: 1 }}>Opentime</InputLabel>
        <LocalizationProvider dateAdapter={AdapterDayjs}>
          <TimePicker
            ampm={false}
            views={['hours', 'minutes']}
            format="HH:mm"
            sx={{ width: '100%' }}
            value={getTimePickerValue(formik.values.opentime)}
            onChange={(newValue) => {
              if (newValue) {
                const formatted = dayjs(newValue).format('HH:mm');
                formik.setFieldValue('opentime', formatted);
              } else {
                formik.setFieldValue('opentime', '');
              }
            }}
            slotProps={{
              textField: {
                name: 'opentime',
                fullWidth: true,
                error: formik.touched.opentime && Boolean(formik.errors.opentime),
                helperText: formik.touched.opentime && formik.errors.opentime
              }
            }}
          />
        </LocalizationProvider>
      </Grid>

      <Grid item xs={12} sm={6}>
        <InputLabel sx={{ mb: 1 }}>Closetime</InputLabel>
        <LocalizationProvider dateAdapter={AdapterDayjs}>
          <TimePicker
            ampm={false}
            views={['hours', 'minutes']}
            format="HH:mm"
            sx={{ width: '100%' }}
            value={getTimePickerValue(formik.values.closetime)}
            onChange={(newValue) => {
              if (newValue) {
                const formatted = dayjs(newValue).format('HH:mm');
                formik.setFieldValue('closetime', formatted);
              } else {
                formik.setFieldValue('closetime', '');
              }
            }}
            slotProps={{
              textField: {
                name: 'closetime',
                fullWidth: true,
                error: formik.touched.closetime && Boolean(formik.errors.closetime),
                helperText: formik.touched.closetime && formik.errors.closetime
              }
            }}
          />
        </LocalizationProvider>
      </Grid>
    </Grid>
  );

  if (isDialogMode) {
    return (
      <Dialog open={Boolean(open)} onClose={onClose} fullWidth maxWidth="md">
        <DialogTitle>{`${editLocation ? 'Edit' : 'Create'} Location`}</DialogTitle>
        <Box component="form" id="location-form-dialog" onSubmit={formik.handleSubmit} noValidate>
          <DialogContent dividers>{formContent}</DialogContent>
          <DialogActions sx={{ p: 2 }}>
            <Button onClick={onClose} color="secondary">
              Cancel
            </Button>
            <Button
              type="submit"
              variant="contained"
              color="primary"
              startIcon={<PlusOutlined />}
              disabled={Boolean(editLocation) && (!formik.dirty || !formik.isValid)}
              sx={{
                '&.Mui-disabled': {
                  backgroundColor: (theme) => theme.palette.grey[300],
                  color: (theme) => theme.palette.grey[500]
                }
              }}
            >
              {`${editLocation ? 'Save Edits' : 'Create'}`}
            </Button>
          </DialogActions>
        </Box>
      </Dialog>
    );
  }

  return (
    <Stack>
      <form onSubmit={formik.handleSubmit} noValidate>
        <TitleCard
          title={`${editLocation ? 'Edit' : 'Create'} Location`}
          starticon={
            <Tooltip title="Back to Locations">
              <IconButton
                variant="contained"
                color="secondary"
                sx={{ backgroundColor: 'secondary.lighter', border: '1px solid', borderColor: 'secondary.light' }}
                onClick={() => navigate('/locations')}
              >
                <ArrowLeftOutlined style={{ fontSize: 20 }} />
              </IconButton>
            </Tooltip>
          }
        >
          <Button
            type="submit"
            variant="contained"
            color="primary"
            startIcon={<PlusOutlined />}
            disabled={Boolean(editLocation) && (!formik.dirty || !formik.isValid)}
            sx={{
              '&.Mui-disabled': {
                backgroundColor: (theme) => theme.palette.grey[300],
                color: (theme) => theme.palette.grey[500]
              }
            }}
          >
            {`${editLocation ? 'Save Edits' : 'Create'} `}
          </Button>
        </TitleCard>
        <MainCard>{formContent}</MainCard>
      </form>
    </Stack>
  );
};

CreateLocation.propTypes = {
  open: PropTypes.bool,
  onClose: PropTypes.func,
  onSuccess: PropTypes.func,
  editLocationData: PropTypes.object,
  dialogMode: PropTypes.bool
};

export default CreateLocation;
