import { useState, useMemo, useEffect, useCallback } from 'react';
import { Card, Form, InputNumber, Button, Radio, Typography, Statistic, Tag, Progress, List, Modal, Collapse, Table, message, Alert } from 'antd';
import { CalculatorOutlined, DeleteOutlined } from '@ant-design/icons';
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 CalculationWithCategoryResponse {
  id: string;
  height: number;
  weight: number;
  height_unit: string;
  weight_unit: string;
  bmi_value: number;
  category_id: string;
  timestamp: string;
  created_at: string;
  updated_at: string;
  category_name: string;
  category_color_code: string;
}

interface CalculationDetailResponse {
  id: string;
  height: number;
  weight: number;
  height_unit: string;
  weight_unit: string;
  bmi_value: number;
  category_id: string;
  timestamp: string;
  created_at: string;
  updated_at: string;
  category: BmiCategoryResponse;
}

export default function BmiCalculatorPage() {
  const [messageApi, contextHolder] = message.useMessage();
  const [form] = Form.useForm();
  const { measurementSystem, setMeasurementSystem } = useAppContext();

  const [bmiResult, setBmiResult] = useState<CalculationDetailResponse | null>(null);
  const [calculations, setCalculations] = useState<CalculationWithCategoryResponse[]>([]);
  const [loading, setLoading] = useState(false);
  const [bmiCategories, setBmiCategories] = useState<BmiCategoryResponse[]>([]);
  const [showClearConfirm, setShowClearConfirm] = useState(false);
  const [infoExpanded, setInfoExpanded] = useState(false);
  const [fetchError, setFetchError] = useState<string | null>(null);

  const recentCalculations = useMemo(() => {
    return calculations.slice(0, 10);
  }, [calculations]);

  const hasHistory = useMemo(() => {
    return calculations.length > 0;
  }, [calculations]);

  const isMetric = useMemo(() => {
    return measurementSystem === 'metric';
  }, [measurementSystem]);

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

    const fetchHistory = async () => {
      try {
        const result = await request<CalculationWithCategoryResponse[]>({
          method: 'GET',
          path: '/bmi/history',
          query: { limit: 10 }
        });
        setCalculations(result.data);
      } catch (error) {
        const errorMessage = error instanceof Error ? error.message : 'Failed to load calculation history';
        setFetchError(errorMessage);
        messageApi.error(errorMessage);
      }
    };

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

  const onSystemChange = useCallback((e: { target: { value: string } }) => {
    setMeasurementSystem(e.target.value);
  }, [setMeasurementSystem]);

  const onInfoToggle = useCallback(() => {
    setInfoExpanded(!infoExpanded);
  }, [infoExpanded]);

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

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

  const calculateBmi = useCallback(async () => {
    try {
      const values = await form.validateFields();
      
      let height = values.height;
      let weight = values.weight;
      let heightUnit = 'cm';
      let weightUnit = 'kg';

      if (!isMetric) {
        const feet = values.height_feet || 0;
        const inches = values.height_inches || 0;
        height = (feet * 12 + inches) * 2.54;
        weight = values.weight * 0.453592;
        heightUnit = 'in';
        weightUnit = 'lbs';
      }

      if (!height || height < 50 || height > 300) {
        messageApi.error('Height must be between 50-300 cm');
        return;
      }

      if (!weight || weight < 10 || weight > 500) {
        messageApi.error('Weight must be between 10-500 kg');
        return;
      }

      setLoading(true);

      const result = await request<CalculationDetailResponse>({
        method: 'POST',
        path: '/bmi/calculate',
        query: {
          height: height,
          weight: weight,
          height_unit: heightUnit,
          weight_unit: weightUnit
        }
      });

      setBmiResult(result.data);
      messageApi.success('BMI calculated successfully!');

      const historyResult = await request<CalculationWithCategoryResponse[]>({
        method: 'GET',
        path: '/bmi/history',
        query: { limit: 10 }
      });
      setCalculations(historyResult.data);

    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : 'Failed to calculate BMI. Please check your inputs.';
      messageApi.error(errorMessage);
    } finally {
      setLoading(false);
    }
  }, [form, isMetric, messageApi]);

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

      setCalculations([]);
      setShowClearConfirm(false);
      messageApi.success('Calculation history cleared.');
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : 'Failed to clear history.';
      messageApi.error(errorMessage);
    }
  }, [messageApi]);

  const categoryTableColumns = useMemo(() => [
    {
      title: 'Category',
      dataIndex: 'name',
      key: 'name'
    },
    {
      title: 'BMI Range',
      dataIndex: 'min_bmi',
      key: 'range',
      render: (minBmi: number, record: BmiCategoryResponse) => {
        if (record.max_bmi === null) {
          return `${minBmi}+`;
        }
        return `${minBmi} - ${record.max_bmi}`;
      }
    },
    {
      title: 'Description',
      dataIndex: 'description',
      key: 'description'
    }
  ], []);

  return (
    <div style={{ minHeight: '100vh', height: '100%', width: '100%', display: 'flex', flexDirection: 'column', padding: '24px', background: '#f5f5f5' }}>
      {contextHolder}
      
      {fetchError && (
        <Alert
          message="Error"
          description={fetchError}
          type="error"
          closable
          onClose={() => setFetchError(null)}
          style={{ maxWidth: '600px', margin: '0 auto 24px' }}
        />
      )}

      <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"
        bordered={true}
        style={{ maxWidth: '600px', margin: '0 auto', marginBottom: '24px' }}
      >
        <Radio.Group
          value={measurementSystem}
          onChange={onSystemChange}
          optionType="button"
          buttonStyle="solid"
          options={[
            { label: 'Metric', value: 'metric' },
            { label: 'Imperial', value: 'imperial' }
          ]}
          style={{ marginBottom: '16px', display: 'block' }}
        />

        <Form
          form={form}
          layout="vertical"
          name="bmi_form"
          onFinish={calculateBmi}
        >
          {isMetric ? (
            <Form.Item
              label="Height"
              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"
                addonAfter="cm"
                min={50}
                max={300}
                style={{ width: '100%' }}
                precision={1}
              />
            </Form.Item>
          ) : (
            <>
              <Form.Item
                label="Height (feet)"
                name="height_feet"
                rules={[{ required: true, message: 'Please enter feet' }]}
              >
                <InputNumber
                  placeholder="e.g. 5"
                  addonAfter="ft"
                  min={1}
                  max={9}
                  style={{ width: '100%' }}
                />
              </Form.Item>

              <Form.Item
                label="Height (inches)"
                name="height_inches"
                rules={[{ required: true, message: 'Please enter inches' }]}
              >
                <InputNumber
                  placeholder="e.g. 9"
                  addonAfter="in"
                  min={0}
                  max={11}
                  style={{ width: '100%' }}
                />
              </Form.Item>
            </>
          )}

          <Form.Item
            label="Weight"
            name="weight"
            rules={[
              { required: true, message: 'Please enter your weight' },
              { type: 'number', min: 10, max: 500, message: 'Weight must be between 10-500 kg', transform: (value) => Number(value) }
            ]}
          >
            <InputNumber
              placeholder={isMetric ? 'e.g. 70' : 'e.g. 154'}
              addonAfter={isMetric ? 'kg' : 'lbs'}
              min={10}
              max={500}
              style={{ width: '100%' }}
              precision={1}
            />
          </Form.Item>

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

      {bmiResult && (
        <Card
          title="Your BMI Result"
          bordered={true}
          style={{ maxWidth: '600px', margin: '0 auto', marginBottom: '24px' }}
        >
          <Statistic
            title="BMI Value"
            value={bmiResult.bmi_value}
            precision={1}
            valueStyle={{ fontSize: '48px', fontWeight: 'bold', textAlign: 'center' }}
            style={{ textAlign: 'center' }}
          />

          <div style={{ textAlign: 'center', marginTop: '12px' }}>
            <Tag
              color={bmiResult.category.color_code}
              style={{ fontSize: '16px', padding: '4px 16px' }}
            >
              {bmiResult.category.name}
            </Tag>
          </div>

          <Progress
            percent={(bmiResult.bmi_value / 40) * 100}
            showInfo={false}
            strokeLinecap="round"
            strokeColor={bmiResult.category.color_code}
            style={{ marginTop: '16px' }}
          />

          <Typography.Paragraph style={{ marginTop: '12px', textAlign: 'center' }}>
            {bmiResult.category.description}
          </Typography.Paragraph>
        </Card>
      )}

      {hasHistory && (
        <Card
          title="Calculation History"
          bordered={true}
          style={{ maxWidth: '600px', margin: '0 auto', marginBottom: '24px' }}
        >
          <List
            size="small"
            dataSource={recentCalculations}
            locale={{ emptyText: 'No calculations yet. Calculate your BMI to see history here.' }}
            renderItem={(item) => (
              <List.Item>
                <div style={{ width: '100%', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                  <div>
                    <Typography.Text strong>BMI: {item.bmi_value.toFixed(1)}</Typography.Text>
                    <Typography.Text type="secondary" style={{ marginLeft: '12px' }}>
                      {item.height.toFixed(1)} {item.height_unit} / {item.weight.toFixed(1)} {item.weight_unit}
                    </Typography.Text>
                  </div>
                  <Tag color={item.category_color_code}>{item.category_name}</Tag>
                </div>
              </List.Item>
            )}
          />

          <Button
            type="default"
            danger
            icon={<DeleteOutlined />}
            size="small"
            onClick={onShowClearConfirm}
            style={{ marginTop: '12px' }}
          >
            Clear History
          </Button>
        </Card>
      )}

      <Collapse
        items={[
          {
            key: 'bmi_info',
            label: 'BMI Information & Health Guidelines',
            children: (
              <div style={{ padding: '8px 0' }}>
                <Typography.Title level={5}>BMI Formula</Typography.Title>
                <Typography.Paragraph code style={{ marginBottom: '16px' }}>
                  BMI = weight (kg) / height (m)²
                </Typography.Paragraph>

                <Typography.Title level={5}>BMI Categories (WHO Standard)</Typography.Title>
                <Table
                  dataSource={bmiCategories}
                  columns={categoryTableColumns}
                  pagination={false}
                  size="small"
                  rowKey="id"
                  style={{ marginBottom: '16px' }}
                />

                <Typography.Title level={5}>Disclaimer</Typography.Title>
                <Typography.Paragraph type="secondary">
                  BMI is a general indicator and does not account for muscle mass, bone density, age, sex, or ethnicity. It should not be used as a sole diagnostic tool. Please consult a healthcare professional for personalized health advice.
                </Typography.Paragraph>
              </div>
            )
          }
        ]}
        bordered={true}
        style={{ maxWidth: '600px', margin: '0 auto', marginBottom: '24px' }}
      />

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