import { useState, useEffect, useMemo, CSSProperties } from 'react';
import { Card, Button, InputNumber, Typography, Tooltip, message, Modal, Alert, Form } from 'antd';
import { ArrowLeftOutlined, UndoOutlined, QuestionCircleOutlined } from '@ant-design/icons';
import { request } from '../api/client';
import { useNavigate } from 'react-router-dom';

interface SystemConfigurationResponse {
  id: string;
  config_key: string;
  config_value: string;
  data_type: 'STRING' | 'INTEGER' | 'DECIMAL' | 'BOOLEAN' | 'JSON';
  description: string | null;
  is_editable: string;
  created_at: string;
  updated_at: string;
}

interface ConfigMap {
  [key: string]: SystemConfigurationResponse;
}

export default function SystemConfigPage() {
  const [messageApi, contextHolder] = message.useMessage();
  const navigate = useNavigate();
  const [form] = Form.useForm();

  const [configurations, setConfigurations] = useState<SystemConfigurationResponse[]>([]);
  const [loading, setLoading] = useState<boolean>(true);
  const [savingKey, setSavingKey] = useState<string>('');
  const [error, setError] = useState<string>('');

  const configMap = useMemo<ConfigMap>(() => {
    const map: ConfigMap = {};
    configurations.forEach(config => {
      map[config.config_key] = config;
    });
    return map;
  }, [configurations]);

  useEffect(() => {
    const fetchConfigurations = async () => {
      setLoading(true);
      setError('');
      try {
        const result = await request<SystemConfigurationResponse[]>({
          method: 'GET',
          path: '/system/configurations',
          query: { limit: 50 }
        });
        setConfigurations(result.data);
        
        const initialValues: Record<string, number> = {};
        result.data.forEach(config => {
          if (config.data_type === 'INTEGER' || config.data_type === 'DECIMAL') {
            initialValues[config.config_key] = parseFloat(config.config_value);
          }
        });
        form.setFieldsValue(initialValues);
      } catch (err) {
        const errorMsg = 'Failed to load system configurations';
        setError(errorMsg);
        messageApi.error(errorMsg);
      } finally {
        setLoading(false);
      }
    };

    fetchConfigurations();
  }, [form, messageApi]);

  const updateConfiguration = async (configKey: string, configValue: string, dataType: string) => {
    const config = configMap[configKey];
    if (!config) {
      messageApi.error(`Configuration ${configKey} not found`);
      return;
    }

    setSavingKey(configKey);
    try {
      const result = await request<SystemConfigurationResponse>({
        method: 'PUT',
        path: '/system/configurations/{config_id}',
        pathParams: { config_id: config.id },
        body: {
          config_value: configValue,
          config_key: configKey,
          data_type: dataType
        }
      });

      setConfigurations(prev =>
        prev.map(c => (c.id === result.data.id ? result.data : c))
      );

      messageApi.success(`${configKey.replace(/_/g, ' ')} updated successfully`);
    } catch (err) {
      messageApi.error(`Failed to update ${configKey.replace(/_/g, ' ')}`);
    } finally {
      setSavingKey('');
    }
  };

  const saveLoanPeriod = async () => {
    try {
      const values = await form.validateFields(['loan_period_days']);
      if (!values.loan_period_days) {
        messageApi.error('Loan period is required');
        return;
      }
      if (values.loan_period_days < 1) {
        messageApi.error('Loan period must be at least 1 day');
        return;
      }
      await updateConfiguration('loan_period_days', String(values.loan_period_days), 'INTEGER');
    } catch (err) {
      messageApi.error('Please enter a valid loan period');
    }
  };

  const saveMaxRenewals = async () => {
    try {
      const values = await form.validateFields(['max_renewals']);
      if (values.max_renewals === undefined || values.max_renewals === null) {
        messageApi.error('Maximum renewals is required');
        return;
      }
      if (values.max_renewals < 0) {
        messageApi.error('Must be at least 0');
        return;
      }
      await updateConfiguration('max_renewals', String(values.max_renewals), 'INTEGER');
    } catch (err) {
      messageApi.error('Please enter a valid maximum renewals value');
    }
  };

  const saveMaxConcurrentLoans = async () => {
    try {
      const values = await form.validateFields(['max_concurrent_loans']);
      if (!values.max_concurrent_loans) {
        messageApi.error('Maximum concurrent loans is required');
        return;
      }
      if (values.max_concurrent_loans < 1) {
        messageApi.error('Must be at least 1');
        return;
      }
      await updateConfiguration('max_concurrent_loans', String(values.max_concurrent_loans), 'INTEGER');
    } catch (err) {
      messageApi.error('Please enter a valid maximum concurrent loans value');
    }
  };

  const saveMaxReservations = async () => {
    try {
      const values = await form.validateFields(['max_reservations']);
      if (!values.max_reservations) {
        messageApi.error('Maximum reservations is required');
        return;
      }
      if (values.max_reservations < 1) {
        messageApi.error('Must be at least 1');
        return;
      }
      await updateConfiguration('max_reservations', String(values.max_reservations), 'INTEGER');
    } catch (err) {
      messageApi.error('Please enter a valid maximum reservations value');
    }
  };

  const savePickupExpiration = async () => {
    try {
      const values = await form.validateFields(['pickup_expiration_hours']);
      if (!values.pickup_expiration_hours) {
        messageApi.error('Pickup expiration is required');
        return;
      }
      if (values.pickup_expiration_hours < 1) {
        messageApi.error('Must be at least 1 hour');
        return;
      }
      await updateConfiguration('pickup_expiration_hours', String(values.pickup_expiration_hours), 'INTEGER');
    } catch (err) {
      messageApi.error('Please enter a valid pickup expiration value');
    }
  };

  const saveDailyFineRate = async () => {
    try {
      const values = await form.validateFields(['daily_fine_rate']);
      if (values.daily_fine_rate === undefined || values.daily_fine_rate === null) {
        messageApi.error('Daily fine rate is required');
        return;
      }
      if (values.daily_fine_rate < 0) {
        messageApi.error('Must be at least 0');
        return;
      }
      await updateConfiguration('daily_fine_rate', String(values.daily_fine_rate), 'DECIMAL');
    } catch (err) {
      messageApi.error('Please enter a valid daily fine rate');
    }
  };

  const saveMaxFine = async () => {
    try {
      const values = await form.validateFields(['max_fine_per_item']);
      if (values.max_fine_per_item === undefined || values.max_fine_per_item === null) {
        messageApi.error('Maximum fine is required');
        return;
      }
      if (values.max_fine_per_item < 0) {
        messageApi.error('Must be at least 0');
        return;
      }
      await updateConfiguration('max_fine_per_item', String(values.max_fine_per_item), 'DECIMAL');
    } catch (err) {
      messageApi.error('Please enter a valid maximum fine value');
    }
  };

  const saveFineThreshold = async () => {
    try {
      const values = await form.validateFields(['fine_threshold']);
      if (values.fine_threshold === undefined || values.fine_threshold === null) {
        messageApi.error('Fine threshold is required');
        return;
      }
      if (values.fine_threshold < 0) {
        messageApi.error('Must be at least 0');
        return;
      }
      await updateConfiguration('fine_threshold', String(values.fine_threshold), 'DECIMAL');
    } catch (err) {
      messageApi.error('Please enter a valid fine threshold value');
    }
  };

  const saveGracePeriod = async () => {
    try {
      const values = await form.validateFields(['grace_period_days']);
      if (values.grace_period_days === undefined || values.grace_period_days === null) {
        messageApi.error('Grace period is required');
        return;
      }
      if (values.grace_period_days < 0) {
        messageApi.error('Must be at least 0');
        return;
      }
      await updateConfiguration('grace_period_days', String(values.grace_period_days), 'INTEGER');
    } catch (err) {
      messageApi.error('Please enter a valid grace period value');
    }
  };

  const resetToDefaults = () => {
    Modal.confirm({
      title: 'Reset to Defaults',
      content: 'Are you sure you want to reset all settings to their default values?',
      okText: 'Reset',
      okType: 'danger',
      cancelText: 'Cancel',
      onOk: async () => {
        const defaults: Record<string, { value: string; type: string }> = {
          loan_period_days: { value: '14', type: 'INTEGER' },
          max_renewals: { value: '2', type: 'INTEGER' },
          max_concurrent_loans: { value: '5', type: 'INTEGER' },
          max_reservations: { value: '3', type: 'INTEGER' },
          pickup_expiration_hours: { value: '48', type: 'INTEGER' },
          daily_fine_rate: { value: '0.5', type: 'DECIMAL' },
          max_fine_per_item: { value: '10', type: 'DECIMAL' },
          fine_threshold: { value: '10', type: 'DECIMAL' },
          grace_period_days: { value: '1', type: 'INTEGER' }
        };

        try {
          for (const [key, { value, type }] of Object.entries(defaults)) {
            const config = configMap[key];
            if (config) {
              await request<SystemConfigurationResponse>({
                method: 'PUT',
                path: '/system/configurations/{config_id}',
                pathParams: { config_id: config.id },
                body: {
                  config_value: value,
                  config_key: key,
                  data_type: type
                }
              });
            }
          }
          messageApi.success('All settings reset to defaults');
          window.location.reload();
        } catch (err) {
          messageApi.error('Failed to reset settings');
        }
      }
    });
  };

  const navigateBack = () => {
    navigate('/admin/dashboard');
  };

  const mainContainerStyle: CSSProperties = {
    minHeight: '100vh',
    height: '100%',
    width: '100%',
    display: 'flex',
    flexDirection: 'column',
    padding: '24px',
    backgroundColor: '#f5f5f5'
  };

  const pageHeaderStyle: CSSProperties = {
    display: 'flex',
    justifyContent: 'space-between',
    alignItems: 'center',
    marginBottom: '24px'
  };

  const headerLeftStyle: CSSProperties = {
    display: 'flex',
    alignItems: 'center',
    gap: '12px'
  };

  const rowStyle: CSSProperties = {
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'space-between',
    padding: '12px 0',
    borderBottom: '1px solid #f0f0f0'
  };

  const lastRowStyle: CSSProperties = {
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'space-between',
    padding: '12px 0'
  };

  const labelGroupStyle: CSSProperties = {
    display: 'flex',
    alignItems: 'center',
    gap: '8px',
    flex: 1
  };

  const cardStyle: CSSProperties = {
    marginBottom: '24px'
  };

  return (
    <div style={mainContainerStyle}>
      {contextHolder}
      {error && (
        <Alert
          message="Error"
          description={error}
          type="error"
          closable
          onClose={() => setError('')}
          style={{ marginBottom: '24px' }}
        />
      )}
      <div style={pageHeaderStyle}>
        <div style={headerLeftStyle}>
          <Button type="text" icon={<ArrowLeftOutlined />} onClick={navigateBack}>
            Back
          </Button>
          <Typography.Title level={2} style={{ margin: 0 }}>
            System Configuration
          </Typography.Title>
        </div>
        <Button type="default" danger icon={<UndoOutlined />} onClick={resetToDefaults}>
          Reset to Defaults
        </Button>
      </div>

      <Form form={form}>
        <Card title="Loan Settings" bordered style={cardStyle} loading={loading}>
          <div style={rowStyle}>
            <div style={labelGroupStyle}>
              <Typography.Text strong>Loan Period (days)</Typography.Text>
              <Tooltip title="Number of days a member can keep a borrowed book before it becomes overdue">
                <QuestionCircleOutlined />
              </Tooltip>
            </div>
            <Form.Item name="loan_period_days" noStyle>
              <InputNumber min={1} max={90} style={{ width: '120px' }} />
            </Form.Item>
            <Button
              type="primary"
              size="small"
              onClick={saveLoanPeriod}
              loading={savingKey === 'loan_period_days'}
              style={{ marginLeft: '12px' }}
            >
              Save
            </Button>
          </div>

          <div style={rowStyle}>
            <div style={labelGroupStyle}>
              <Typography.Text strong>Maximum Renewals</Typography.Text>
              <Tooltip title="Maximum number of times a member can renew a single loan">
                <QuestionCircleOutlined />
              </Tooltip>
            </div>
            <Form.Item name="max_renewals" noStyle>
              <InputNumber min={0} max={10} style={{ width: '120px' }} />
            </Form.Item>
            <Button
              type="primary"
              size="small"
              onClick={saveMaxRenewals}
              loading={savingKey === 'max_renewals'}
              style={{ marginLeft: '12px' }}
            >
              Save
            </Button>
          </div>

          <div style={lastRowStyle}>
            <div style={labelGroupStyle}>
              <Typography.Text strong>Maximum Concurrent Loans</Typography.Text>
              <Tooltip title="Maximum number of books a member can have checked out at the same time">
                <QuestionCircleOutlined />
              </Tooltip>
            </div>
            <Form.Item name="max_concurrent_loans" noStyle>
              <InputNumber min={1} max={20} style={{ width: '120px' }} />
            </Form.Item>
            <Button
              type="primary"
              size="small"
              onClick={saveMaxConcurrentLoans}
              loading={savingKey === 'max_concurrent_loans'}
              style={{ marginLeft: '12px' }}
            >
              Save
            </Button>
          </div>
        </Card>

        <Card title="Reservation Settings" bordered style={cardStyle} loading={loading}>
          <div style={rowStyle}>
            <div style={labelGroupStyle}>
              <Typography.Text strong>Maximum Concurrent Reservations</Typography.Text>
              <Tooltip title="Maximum number of active reservations a member can have at one time">
                <QuestionCircleOutlined />
              </Tooltip>
            </div>
            <Form.Item name="max_reservations" noStyle>
              <InputNumber min={1} max={10} style={{ width: '120px' }} />
            </Form.Item>
            <Button
              type="primary"
              size="small"
              onClick={saveMaxReservations}
              loading={savingKey === 'max_reservations'}
              style={{ marginLeft: '12px' }}
            >
              Save
            </Button>
          </div>

          <div style={lastRowStyle}>
            <div style={labelGroupStyle}>
              <Typography.Text strong>Pickup Expiration (hours)</Typography.Text>
              <Tooltip title="Number of hours a member has to pick up a reserved book after notification">
                <QuestionCircleOutlined />
              </Tooltip>
            </div>
            <Form.Item name="pickup_expiration_hours" noStyle>
              <InputNumber min={1} max={168} style={{ width: '120px' }} />
            </Form.Item>
            <Button
              type="primary"
              size="small"
              onClick={savePickupExpiration}
              loading={savingKey === 'pickup_expiration_hours'}
              style={{ marginLeft: '12px' }}
            >
              Save
            </Button>
          </div>
        </Card>

        <Card title="Fine Settings" bordered style={cardStyle} loading={loading}>
          <div style={rowStyle}>
            <div style={labelGroupStyle}>
              <Typography.Text strong>Daily Overdue Rate ($)</Typography.Text>
              <Tooltip title="Amount charged per day for each overdue book">
                <QuestionCircleOutlined />
              </Tooltip>
            </div>
            <Form.Item name="daily_fine_rate" noStyle>
              <InputNumber min={0} max={10} step={0.1} precision={2} prefix="$" style={{ width: '120px' }} />
            </Form.Item>
            <Button
              type="primary"
              size="small"
              onClick={saveDailyFineRate}
              loading={savingKey === 'daily_fine_rate'}
              style={{ marginLeft: '12px' }}
            >
              Save
            </Button>
          </div>

          <div style={rowStyle}>
            <div style={labelGroupStyle}>
              <Typography.Text strong>Maximum Fine Per Item ($)</Typography.Text>
              <Tooltip title="Maximum total fine that can be charged for a single overdue item">
                <QuestionCircleOutlined />
              </Tooltip>
            </div>
            <Form.Item name="max_fine_per_item" noStyle>
              <InputNumber min={0} max={100} step={1} precision={2} prefix="$" style={{ width: '120px' }} />
            </Form.Item>
            <Button
              type="primary"
              size="small"
              onClick={saveMaxFine}
              loading={savingKey === 'max_fine_per_item'}
              style={{ marginLeft: '12px' }}
            >
              Save
            </Button>
          </div>

          <div style={rowStyle}>
            <div style={labelGroupStyle}>
              <Typography.Text strong>Fine Threshold for Suspension ($)</Typography.Text>
              <Tooltip title="Total outstanding fine amount that triggers borrowing suspension for a member">
                <QuestionCircleOutlined />
              </Tooltip>
            </div>
            <Form.Item name="fine_threshold" noStyle>
              <InputNumber min={0} max={100} step={1} precision={2} prefix="$" style={{ width: '120px' }} />
            </Form.Item>
            <Button
              type="primary"
              size="small"
              onClick={saveFineThreshold}
              loading={savingKey === 'fine_threshold'}
              style={{ marginLeft: '12px' }}
            >
              Save
            </Button>
          </div>

          <div style={lastRowStyle}>
            <div style={labelGroupStyle}>
              <Typography.Text strong>Grace Period (days)</Typography.Text>
              <Tooltip title="Number of days after the due date before overdue fines start accruing">
                <QuestionCircleOutlined />
              </Tooltip>
            </div>
            <Form.Item name="grace_period_days" noStyle>
              <InputNumber min={0} max={14} style={{ width: '120px' }} />
            </Form.Item>
            <Button
              type="primary"
              size="small"
              onClick={saveGracePeriod}
              loading={savingKey === 'grace_period_days'}
              style={{ marginLeft: '12px' }}
            >
              Save
            </Button>
          </div>
        </Card>
      </Form>
    </div>
  );
}