import React, { useState, useEffect } from 'react';
import { Button, Input, Card, notification, Space, Typography, Alert, Row, Col } from 'antd';
import { ReadOutlined, EditOutlined, DeleteOutlined, WifiOutlined } from '@ant-design/icons';
import mqtt from 'mqtt';
import dayjs from 'dayjs';

const { Title, Text } = Typography;
const { TextArea } = Input;

function App() {
  const [lockNo, setLockNo] = useState('1');
  const [startTime, setStartTime] = useState(dayjs().format('YYYY-MM-DDTHH:mm'));
  const [endTime, setEndTime] = useState(
    dayjs().add(1, 'day').set('hour', 12).set('minute', 0).format('YYYY-MM-DDTHH:mm')
  );
  const [isConnected, setIsConnected] = useState(false);
  const [connectionError, setConnectionError] = useState('');
  const [client, setClient] = useState(null);
  const [receivedMessages, setReceivedMessages] = useState('No messages received yet');

  // MQTT connection options
  const mqttOptions = {
    host: `${import.meta.env.VITE_MQTT_SERVER}`,
    // host: 'mosquitto-apotek-2',
    port: Number(`${import.meta.env.VITE_MQTT_PORT}`),
    // protocol: "mqtt",
    username: 'morekmorekmorek',
    password: 'morek888',
    // connectTimeout: 5000,
    // reconnectPeriod: 5000,
  };
  // Update end time when start time changes
  useEffect(() => {
    const start = dayjs(startTime);
    const newEndTime = start.add(1, 'day').set('hour', 12).set('minute', 0).set('second', 0);
    setEndTime(newEndTime.format('YYYY-MM-DDTHH:mm'));
  }, [startTime]);

  // Connect to MQTT broker - and keep connection alive
  useEffect(() => {
    let mqttClient;
    
    const connectToMqtt = () => {
      try {
        const connectUrl = `mqtt://${mqttOptions.host}:${mqttOptions.port}`;
        console.log('Attempting to connect to:', connectUrl);
        
        mqttClient = mqtt.connect(connectUrl, {
          username: mqttOptions.username,
          password: mqttOptions.password,
          clientId: 'mqttjs_' + Math.random().toString(16).substring(2, 8),
          connectTimeout: mqttOptions.connectTimeout,
          reconnectPeriod: mqttOptions.reconnectPeriod,
          clean: false,
          keepalive: 30,
        });
        
        setClient(mqttClient);

        mqttClient.on('connect', () => {
          console.log('Connected to MQTT broker');
          setIsConnected(true);
          setConnectionError('');
          notification.success({
            message: 'MQTT Connected',
            description: 'Successfully connected to MQTT broker',
            duration: 2,
          });
          
          mqttClient.subscribe('hotel1/pc1', (err) => {
            if (err) {
              console.error('Subscription error:', err);
            } else {
              console.log('Subscribed to topic: hotel1/pc1');
            }
          });
        });

        mqttClient.on('error', (err) => {
          console.error('MQTT connection error:', err);
          setConnectionError(err.message);
          setIsConnected(false);
        });

        mqttClient.on('close', () => {
          console.log('MQTT connection closed');
          setIsConnected(false);
        });

        mqttClient.on('reconnect', () => {
          console.log('Attempting to reconnect to MQTT broker');
          setIsConnected(false);
          setConnectionError('Reconnecting...');
        });

        mqttClient.on('offline', () => {
          console.log('MQTT client is offline');
          setIsConnected(false);
          setConnectionError('Offline - attempting to reconnect');
        });

        mqttClient.on('message', (topic, message) => {
          console.log('Received message:', topic, message.toString());
          const newMessage = `[${new Date().toLocaleTimeString()}] ${topic}: ${message.toString()}\n`;
          setReceivedMessages(prev => prev === 'No messages received yet' ? newMessage : prev + newMessage);
        });
      } catch (err) {
        console.error('Failed to initialize MQTT client:', err);
        setConnectionError(err.message);
        setTimeout(connectToMqtt, 5000);
      }
    };

    connectToMqtt();

  }, []);

  const handleStartTimeChange = (e) => {
    const newStartTime = e.target.value;
    setStartTime(newStartTime);
  };

  const handleEndTimeChange = (e) => {
    const newEndTime = e.target.value;
    const start = dayjs(startTime);
    const end = dayjs(newEndTime);
    
    if (end.isBefore(start)) {
      notification.error({
        message: 'Invalid End Time',
        description: 'End time cannot be before start time',
        duration: 3,
      });
      return;
    }
    
    setEndTime(newEndTime);
  };

  // Format datetime to YYYY-MM-DD HH:mm:ss
  const formatDateTime = (dateTimeString) => {
    return dayjs(dateTimeString).format('YYYY-MM-DD HH:mm:ss');
  };

  const handleRead = () => {
    if (client && isConnected) {
      const payload = JSON.stringify({ cmd: "cek_kartu" });
      client.publish('hotel1/pc1', payload);
      notification.info({
        message: 'Read Command Sent',
        description: `Published: ${payload}`,
        duration: 2,
      });
    } else {
      notification.warning({
        message: 'Not Connected',
        description: 'Cannot publish message - not connected to MQTT',
        duration: 2,
      });
    }
  };

  const handleWrite = () => {
    if (client && isConnected) {
      if (!lockNo || !startTime || !endTime) {
        notification.error({
          message: 'Validation Error',
          description: 'Please fill in all fields',
          duration: 2,
        });
        return;
      }
      
      const start = dayjs(startTime);
      const end = dayjs(endTime);
      
      if (end.isBefore(start)) {
        notification.error({
          message: 'Validation Error',
          description: 'End time must be after start time',
          duration: 2,
        });
        return;
      }
      
      // Format the datetime values before sending
      const formattedStartTime = formatDateTime(startTime);
      const formattedEndTime = formatDateTime(endTime);
      
      const payload = JSON.stringify({
        cmd: "tulis_kartu",
        lock_no: parseInt(lockNo),
        start_time: formattedStartTime,
        end_time: formattedEndTime
      });
      
      client.publish('hotel1/pc1', payload);
      notification.info({
        message: 'Write Command Sent',
        description: `Published: ${payload}`,
        duration: 2,
      });
    } else {
      notification.warning({
        message: 'Not Connected',
        description: 'Cannot publish message - not connected to MQTT',
        duration: 2,
      });
    }
  };

  const handleDelete = () => {
    if (client && isConnected) {
      const payload = JSON.stringify({ cmd: "hapus_kartu" });
      client.publish('hotel1/pc1', payload);
      notification.info({
        message: 'Delete Command Sent',
        description: `Published: ${payload}`,
        duration: 2,
      });
    } else {
      notification.warning({
        message: 'Not Connected',
        description: 'Cannot publish message - not connected to MQTT',
        duration: 2,
      });
    }
  };

  const clearMessages = () => {
    setReceivedMessages('No messages received yet');
  };

  const disconnectMqtt = () => {
    if (client) {
      client.end(false, () => {
        console.log('Manually disconnected from MQTT');
        setIsConnected(false);
        setConnectionError('Manually disconnected');
      });
    }
  };

  const reconnectMqtt = () => {
    if (client) {
      client.reconnect();
    }
  };

  // Calculate min and max values for datetime inputs
  const minEndTime = startTime;
  const maxStartTime = endTime;

  return (
    <div style={{ padding: '24px', minHeight: '100vh', background: '#f0f2f5' }}>
      <Card 
        style={{ 
          maxWidth: 800, 
          margin: '0 auto', 
          boxShadow: '0 4px 8px rgba(0,0,0,0.1)',
          borderRadius: '8px'
        }}
      >
        <Title level={2} style={{ textAlign: 'center', color: '#1890ff' }}>
          Lock Management System
        </Title>
        
        <div style={{ display: 'flex', alignItems: 'center', marginBottom: '16px', justifyContent: 'space-between' }}>
          <div style={{ display: 'flex', alignItems: 'center' }}>
            <WifiOutlined 
              style={{ 
                color: isConnected ? '#52c41a' : '#ff4d4f', 
                fontSize: '20px', 
                marginRight: '8px' 
              }} 
            />
            <Text strong>
              Status: {isConnected ? 'Connected' : 'Disconnected'}
            </Text>
          </div>
          <Space>
            <Button size="small" onClick={reconnectMqtt} disabled={isConnected}>
              Reconnect
            </Button>
            <Button size="small" danger onClick={disconnectMqtt} disabled={!isConnected}>
              Disconnect
            </Button>
          </Space>
        </div>
        
        {connectionError && (
          <Alert
            message="Connection Status"
            description={connectionError}
            type={isConnected ? 'success' : 'warning'}
            showIcon
            style={{ marginBottom: '16px' }}
          />
        )}
        
        <Space direction="vertical" size="middle" style={{ width: '100%' }}>
          <Row gutter={16}>
            <Col span={8}>
              <Text strong>Lock Number:</Text>
              <Input
                type="number"
                min="1"
                value={lockNo}
                onChange={(e) => setLockNo(e.target.value)}
                size="large"
                style={{ marginTop: '8px' }}
                placeholder="Enter lock number"
              />
            </Col>
            <Col span={8}>
              <Text strong>Start Time:</Text>
              <Input
                type="datetime-local"
                value={startTime}
                onChange={handleStartTimeChange}
                size="large"
                style={{ marginTop: '8px' }}
                max={maxStartTime}
              />
              <Text type="secondary" style={{ fontSize: '12px', display: 'block', marginTop: '4px' }}>
                Will be formatted as: {formatDateTime(startTime)}
              </Text>
            </Col>
            <Col span={8}>
              <Text strong>End Time:</Text>
              <Input
                type="datetime-local"
                value={endTime}
                onChange={handleEndTimeChange}
                size="large"
                style={{ marginTop: '8px' }}
                min={minEndTime}
              />
              <Text type="secondary" style={{ fontSize: '12px', display: 'block', marginTop: '4px' }}>
                Will be formatted as: {formatDateTime(endTime)}
              </Text>
            </Col>
          </Row>
          
          <Space direction="horizontal" style={{ width: '100%', justifyContent: 'center' }}>
            <Button 
              type="primary" 
              icon={<ReadOutlined />} 
              size="large"
              onClick={handleRead}
              style={{ background: '#52c41a', borderColor: '#52c41a' }}
            >
              Read
            </Button>
            
            <Button 
              type="primary" 
              icon={<EditOutlined />} 
              size="large"
              onClick={handleWrite}
            >
              Write
            </Button>
            
            <Button 
              type="primary" 
              icon={<DeleteOutlined />} 
              size="large"
              onClick={handleDelete}
              danger
            >
              Delete
            </Button>
          </Space>

          <div>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '8px' }}>
              <Text strong>Received Messages:</Text>
              <Button 
                size="small" 
                onClick={clearMessages}
                style={{ marginLeft: '8px' }}
              >
                Clear
              </Button>
            </div>
            <TextArea
              rows={10}
              value={receivedMessages}
              readOnly
              style={{ 
                backgroundColor: '#f9f9f9',
                fontFamily: 'monospace',
                fontSize: '14px'
              }}
              placeholder="Messages from MQTT will appear here..."
            />
          </div>
        </Space>
        
        <div style={{ marginTop: '24px' }}>
          <Title level={5}>Connection Information</Title>
          <Text type="secondary">
            Broker: {mqttOptions.host}:{mqttOptions.port}<br />
            Topic: hotel1/pc1<br />
            Username: {mqttOptions.username}<br />
            Client ID: {client?.options?.clientId || 'Not connected'}
          </Text>
        </div>
        
        <div style={{ marginTop: '16px', padding: '12px', backgroundColor: '#f0f9ff', borderRadius: '6px' }}>
          <Title level={5}>Usage Instructions</Title>
          <Text type="secondary">
            1. Enter lock number (integer)<br />
            2. Select start time - end time will auto-set to next day at 12:00<br />
            3. Adjust end time if needed (cannot be before start time)<br />
            4. Click Write to send JSON: {"{"}lock_no: [value], start_time: "YYYY-MM-DD HH:mm:ss", end_time: "YYYY-MM-DD HH:mm:ss"{"}"}<br />
            5. Received messages will appear in the text area below
          </Text>
        </div>
        
        <div style={{ marginTop: '16px', padding: '12px', backgroundColor: '#fff7e6', borderRadius: '6px' }}>
          <Title level={5}>Output Format</Title>
          <Text type="secondary" style={{ fontFamily: 'monospace' }}>
            {`{
  "lock_no": ${lockNo},
  "start_time": "${formatDateTime(startTime)}",
  "end_time": "${formatDateTime(endTime)}"
}`}
          </Text>
        </div>
      </Card>
    </div>
  );
}

export default App;