import { useState, useMemo, useEffect, useCallback, CSSProperties } from 'react';
import { Card, Form, InputNumber, Button, Typography, Radio, Alert, Table, List, Modal, Collapse, Tag, Progress, message } from 'antd';
import { request } from '../api/network';
import { useAppContext } from '../context/AppContext';

interface BmiCategoryResponse {
  id: string;
  name?: string;
  min_bmi?: number;
  max_bmi?: number | null;
  description?: string;
  color_code?: string;
  created_at: string;
  updated_at: string;
}

interface ComputeBMIRequest {
  height?: number;
  weight?: number;
  height_unit: string;
  weight_unit: string;
}

interface BmiCategorySummary {
  name?: string;
  min_bmi?: number;
  max_bmi?: number | null;
  description?: string;
  color_code?: string;
}

interface ComputeBMIResponse {
  bmi_value: number;
  category: string;
  height: number;
  weight: number;
  height_unit: string;
  weight_unit: string;
  bmi_category?: BmiCategorySummary | null;
}

interface CalculationListItemResponse {
  id: string;
  height: number;
  weight: number;
  height_unit: string;
  weight_unit: string;
  bmi_value: number;
  category: string;
  timestamp: string;
  measurement_unit?: { system: string } | null;
  bmi_category?: BmiCategorySummary | null;
}

export default function BmiCalculatorPage() {
  const [messageApi, contextHolder] = message.useMessage();
  const [form] = Form.useForm();
  
  const { measurementSystem, calculationHistory, latestResult, setMeasurementSystem, setCalculationHistory, setLatestResult } = useAppContext();
  
  const [bmiCategories, setBmiCategories] = useState<BmiCategoryResponse[]>([]);
  const [isCalculating, setIsCalculating] = useState<boolean>(false);
  const [showClearConfirm, setShowClearConfirm] = useState<boolean>(false);
  const [aboutExpanded, setAboutExpanded] = useState<boolean>(false);

  const hasResult = useMemo(() => latestResult !== null, [latestResult]);
  const hasHistory = useMemo(() => calculationHistory.length > 0, [calculationHistory]);
  const isMetric = useMemo(() => measurementSystem === 'metric', [measurementSystem]);

  const categoryTableColumns = useMemo(() => [
    {
      title: 'Category',
      dataIndex: 'name',
      key: 'name',
    },
    {
      title: 'BMI Range',
      key: 'range',
      render: (record: BmiCategoryResponse) => {
        if (record.max_bmi === null) {
          return `≥ ${record.min_bmi}`;
        }
        return `${record.min_bmi} - ${record.max_bmi}`;
      },
    },
    {
      title: 'Color',
      dataIndex: 'color_code',
      key: 'color_code',
      render: (color: string) => (
        <div style={{ width: 24, height: 24, backgroundColor: color, borderRadius: 4 }} />
      ),
    },
  ], []);

  useEffect(() => {
    const fetchBmiCategories = async () => {
      try {
        const result = await request<BmiCategoryResponse[]>({
          method: 'GET',
          path: '/bmi-categories/',
          query: { limit: 50 },
        });
        setBmiCategories(result.data);
      } catch (error) {
        messageApi.error('Failed to load BMI categories');
      }
    };

    fetchBmiCategories();
  }, [messageApi]);

  useEffect(() => {
    const fetchHistory = async () => {
      try {
        const result = await request<CalculationListItemResponse[]>({
          method: 'GET',
          path: '/calculations/history/list',
          query: { limit: 10 },
        });
        setCalculationHistory(result.data);
      } catch (error) {
        messageApi.error('Failed to load calculation history');
      }
    };

    fetchHistory();
  }, [messageApi, setCalculationHistory]);

  const toggleMeasurementSystem = useCallback(() => {
    setMeasurementSystem(measurementSystem === 'metric' ? 'imperial' : 'metric');
    form.resetFields();
  }, [measurementSystem, setMeasurementSystem, form]);

  const openClearConfirm = useCallback(() => {
    setShowClearConfirm(true);
  }, []);

  const closeClearConfirm = useCallback(() => {
    setShowClearConfirm(false);
  }, []);

  const calculateBmi = useCallback(async () => {
    try {
      const formValues = await form.validateFields();
      
      let heightValue = 0;
      let weightValue = 0;
      let heightUnit = '';
      let weightUnit = '';

      if (isMetric) {
        heightValue = formValues.height;
        weightValue = formValues.weight;
        heightUnit = 'CM';
        weightUnit = 'KG';
      } else {
        const feet = formValues.height_feet || 0;
        const inches = formValues.height_inches || 0;
        heightValue = feet + inches / 12;
        weightValue = formValues.weight;
        heightUnit = 'FT';
        weightUnit = 'LBS';
      }

      if (heightValue <= 0) {
        messageApi.error('Height must be greater than 0');
        return;
      }
      if (weightValue <= 0) {
        messageApi.error('Weight must be greater than 0');
        return;
      }

      setIsCalculating(true);

      const requestBody: ComputeBMIRequest = {
        height: heightValue,
        weight: weightValue,
        height_unit: heightUnit,
        weight_unit: weightUnit,
      };

      const result = await request<ComputeBMIResponse>({
        method: 'POST',
        path: '/calculations/compute',
        body: requestBody,
      });

      setLatestResult(result.data);
      messageApi.success('BMI calculated successfully!');
      setIsCalculating(false);
    } catch (error) {
      setIsCalculating(false);
      messageApi.error('Failed to calculate BMI. Please check your inputs.');
    }
  }, [form, isMetric, messageApi, setLatestResult]);

  const clearHistory = useCallback(async () => {
    try {
      await request({
        method: 'DELETE',
        path: '/calculations/history/clear',
      });

      setShowClearConfirm(false);
      setCalculationHistory([]);
      setLatestResult(null);
      messageApi.success('Calculation history cleared');
    } catch (error) {
      messageApi.error('Failed to clear history');
    }
  }, [messageApi, setCalculationHistory, setLatestResult]);

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

  const cardStyle: CSSProperties = {
    maxWidth: '600px',
    margin: '0 auto 24px auto',
  };

  return (
    <div style={mainContainerStyle}>
      {contextHolder}
      
      <Typography.Title level={2} style={{ textAlign: 'center', marginBottom: '8px' }}>
        BMI Calculator
      </Typography.Title>
      
      <Typography.Text type="secondary" style={{ textAlign: 'center', display: 'block', marginBottom: '24px' }}>
        Calculate your Body Mass Index quickly and easily
      </Typography.Text>

      <Card title="Calculate Your BMI" style={cardStyle}>
        <div style={{ display: 'flex', justifyContent: 'center', marginBottom: '24px' }}>
          <Radio.Group
            value={measurementSystem}
            onChange={toggleMeasurementSystem}
            optionType="button"
            buttonStyle="solid"
            options={[
              { label: 'Metric', value: 'metric' },
              { label: 'Imperial', value: 'imperial' },
            ]}
          />
        </div>

        <Form form={form} layout="vertical" name="bmi_calculator_form" onFinish={calculateBmi}>
          {isMetric ? (
            <Form.Item
              label="Height (cm)"
              name="height"
              rules={[
                { required: true, message: 'Please enter your height' },
                { type: 'number', min: 50, max: 300, message: 'Height must be between 50-300 cm', transform: (value) => Number(value) },
              ]}
            >
              <InputNumber
                placeholder="e.g. 175"
                min={50}
                max={300}
                step={0.1}
                addonAfter="cm"
                style={{ width: '100%' }}
              />
            </Form.Item>
          ) : (
            <div style={{ display: 'flex', gap: '12px' }}>
              <Form.Item
                label="Height (ft)"
                name="height_feet"
                rules={[{ required: true, message: 'Enter feet' }]}
                style={{ flex: 1 }}
              >
                <InputNumber
                  placeholder="e.g. 5"
                  min={1}
                  max={10}
                  step={1}
                  addonAfter="ft"
                  style={{ width: '100%' }}
                />
              </Form.Item>
              <Form.Item
                label="Inches"
                name="height_inches"
                rules={[{ required: true, message: 'Enter inches' }]}
                style={{ flex: 1 }}
              >
                <InputNumber
                  placeholder="e.g. 10"
                  min={0}
                  max={11}
                  step={1}
                  addonAfter="in"
                  style={{ width: '100%' }}
                />
              </Form.Item>
            </div>
          )}

          <Form.Item
            label={isMetric ? 'Weight (kg)' : 'Weight (lbs)'}
            name="weight"
            rules={[{ required: true, message: 'Please enter your weight' }]}
          >
            <InputNumber
              placeholder={isMetric ? 'e.g. 70' : 'e.g. 154'}
              min={10}
              max={500}
              step={0.1}
              addonAfter={isMetric ? 'kg' : 'lbs'}
              style={{ width: '100%' }}
            />
          </Form.Item>

          <Button
            type="primary"
            htmlType="submit"
            block
            size="large"
            loading={isCalculating}
            style={{ marginTop: '16px' }}
          >
            Calculate BMI
          </Button>
        </Form>
      </Card>

      {hasResult && latestResult && (
        <Card title="Your BMI Result" style={cardStyle}>
          <Typography.Title level={1} style={{ textAlign: 'center', fontSize: '48px', margin: '0' }}>
            {latestResult.bmi_value.toFixed(1)}
          </Typography.Title>
          
          <div style={{ textAlign: 'center', marginTop: '8px' }}>
            <Tag
              color={latestResult.bmi_category?.color_code || '#3B82F6'}
              style={{ fontSize: '16px', padding: '4px 16px' }}
            >
              {latestResult.category}
            </Tag>
          </div>

          <div style={{ marginTop: '24px', marginBottom: '16px' }}>
            <Progress
              percent={Math.min((latestResult.bmi_value / 40) * 100, 100)}
              showInfo={false}
              strokeLinecap="round"
              strokeColor={latestResult.bmi_category?.color_code || '#3B82F6'}
              style={{ marginBottom: '8px' }}
            />
            <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: '12px' }}>
              <Typography.Text style={{ color: '#3B82F6' }}>Underweight (&lt;18.5)</Typography.Text>
              <Typography.Text style={{ color: '#10B981' }}>Normal (18.5-24.9)</Typography.Text>
              <Typography.Text style={{ color: '#F59E0B' }}>Overweight (25-29.9)</Typography.Text>
              <Typography.Text style={{ color: '#EF4444' }}>Obese (≥30)</Typography.Text>
            </div>
          </div>

          {latestResult.bmi_category?.description && (
            <Typography.Paragraph style={{ marginTop: '16px', textAlign: 'center' }}>
              {latestResult.bmi_category.description}
            </Typography.Paragraph>
          )}

          <Alert
            type="info"
            message="Medical Disclaimer"
            description="BMI is a general indicator and does not account for muscle mass, bone density, or overall body composition. Please consult a healthcare professional for a comprehensive health assessment."
            showIcon
            style={{ marginTop: '16px' }}
          />
        </Card>
      )}

      <Card title="BMI Category Reference" style={cardStyle}>
        <Table
          dataSource={bmiCategories}
          columns={categoryTableColumns}
          pagination={false}
          size="small"
          rowKey="id"
        />
      </Card>

      <Card title="Calculation History" style={cardStyle}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '16px' }}>
          <Typography.Text strong>Recent Calculations</Typography.Text>
          {hasHistory && (
            <Button type="default" danger size="small" onClick={openClearConfirm}>
              Clear History
            </Button>
          )}
        </div>
        <List
          dataSource={calculationHistory}
          size="small"
          locale={{ emptyText: 'No calculations yet. Use the calculator above to get started!' }}
          renderItem={(item: CalculationListItemResponse) => (
            <List.Item>
              <div style={{ width: '100%' }}>
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                  <div>
                    <Typography.Text strong>BMI: {item.bmi_value.toFixed(1)}</Typography.Text>
                    <Tag color={item.bmi_category?.color_code || '#3B82F6'} style={{ marginLeft: 8 }}>
                      {item.category}
                    </Tag>
                  </div>
                  <Typography.Text type="secondary" style={{ fontSize: '12px' }}>
                    {new Date(item.timestamp).toLocaleDateString()}
                  </Typography.Text>
                </div>
                <Typography.Text type="secondary" style={{ fontSize: '12px' }}>
                  Height: {item.height.toFixed(1)} {item.height_unit} | Weight: {item.weight.toFixed(1)} {item.weight_unit}
                </Typography.Text>
              </div>
            </List.Item>
          )}
        />
      </Card>

      <Collapse
        style={cardStyle}
        items={[
          {
            key: 'about_bmi',
            label: 'About BMI',
            children: (
              <div>
                <Typography.Title level={5}>BMI Formula</Typography.Title>
                <Typography.Paragraph code style={{ fontSize: '16px' }}>
                  BMI = weight (kg) ÷ height (m)²
                </Typography.Paragraph>

                <Typography.Title level={5} style={{ marginTop: '16px' }}>
                  What is BMI?
                </Typography.Title>
                <Typography.Paragraph>
                  Body Mass Index (BMI) is a simple measure using height and weight to estimate whether a person has a healthy body weight. It is widely used as a screening tool to identify potential weight-related health issues.
                </Typography.Paragraph>

                <Typography.Title level={5} style={{ marginTop: '16px' }}>
                  Limitations
                </Typography.Title>
                <Typography.Paragraph>
                  BMI does not distinguish between muscle and fat mass, does not account for age, sex, ethnicity, or body composition. Athletes may have a high BMI due to muscle mass. BMI may not be accurate for pregnant women, elderly, or children.
                </Typography.Paragraph>

                <Typography.Title level={5} style={{ marginTop: '16px' }}>
                  When to Consult a Professional
                </Typography.Title>
                <Typography.Paragraph>
                  If your BMI falls outside the normal range, or if you have concerns about your weight or health, please consult a healthcare professional for personalized advice and a comprehensive health assessment.
                </Typography.Paragraph>
              </div>
            ),
          },
        ]}
      />

      <Modal
        title="Clear Calculation History"
        open={showClearConfirm}
        onOk={clearHistory}
        onCancel={closeClearConfirm}
        okText="Confirm"
        cancelText="Cancel"
        okButtonProps={{ danger: true }}
      >
        <Typography.Paragraph>
          Are you sure you want to clear all calculation history? This action cannot be undone.
        </Typography.Paragraph>
      </Modal>
    </div>
  );
}