import { useState, useMemo, useEffect, useCallback, CSSProperties } from 'react';
import { Form, Input, InputNumber, Button, Card, Row, Col, Typography, Space, Radio, Alert, Tag, Progress, Statistic, message } from 'antd';
import { CalculatorOutlined, SaveOutlined, ClearOutlined } from '@ant-design/icons';
import { useNavigate } from 'react-router-dom';
import { useApi } from '@/hooks/useApi';
import { BmiService } from '@/services/bmi';
import { ROUTES } from '@/constants/routes';
import { MESSAGES } from '@/constants/messages';
import { parseError } from '@/utils/errorHandler';
import { useAppContext } from '@/store/AppStore';

interface BmiCalculationResult {
  bmi_value: number;
  bmi_category: string;
  category_id: string | null;
  height_cm: number;
  weight_kg: number;
  unit: string;
  color_code: string | null;
  health_risk: string | null;
  recommendations: string | null;
  calculation_id: string | null;
  calculated_at: string | null;
}

interface BmiCalculation {
  id: string;
  calculation_id: string;
  user_id: string | null;
  height_cm: number;
  weight_kg: number;
  bmi_value: number;
  bmi_category: string;
  category_id: string | null;
  unit: string;
  calculated_at: string;
  notes: string | null;
  is_deleted: boolean;
  created_at: string;
  updated_at: string;
}

const CalculatorPage = () => {
  const [messageApi, contextHolder] = message.useMessage();
  const [form] = Form.useForm();
  const navigate = useNavigate();
  const { currentUser, preferredUnit } = useAppContext();

  const [calculationResult, setCalculationResult] = useState<BmiCalculationResult | null>(null);
  const [lastCalculation, setLastCalculation] = useState<BmiCalculation | null>(null);
  const [isCalculating, setIsCalculating] = useState<boolean>(false);
  const [showResult, setShowResult] = useState<boolean>(false);

  const isLoggedIn = useMemo(() => currentUser !== null, [currentUser]);
  const activeUnit = useMemo(() => preferredUnit || 'metric', [preferredUnit]);

  const bmiDifference = useMemo(() => {
    if (calculationResult && lastCalculation) {
      return (calculationResult.bmi_value - lastCalculation.bmi_value).toFixed(1);
    }
    return null;
  }, [calculationResult, lastCalculation]);

  const categoryColor = useMemo(() => {
    if (!calculationResult) return '#d9d9d9';
    if (calculationResult.color_code) return calculationResult.color_code;
    if (calculationResult.bmi_category === 'Underweight') return '#1890ff';
    if (calculationResult.bmi_category === 'Normal') return '#52c41a';
    if (calculationResult.bmi_category === 'Overweight') return '#fa8c16';
    return '#f5222d';
  }, [calculationResult]);

  const { data: lastCalcData, execute: fetchLastCalculation } = useApi(BmiService.listCalculations);

  useEffect(() => {
    if (isLoggedIn && currentUser?.userId) {
      void fetchLastCalculation({
        user_id: currentUser.userId,
        is_deleted: false,
        limit: 1,
        offset: 0
      }).then((response) => {
        if (response?.data && Array.isArray(response.data) && response.data.length > 0) {
          setLastCalculation(response.data[0]);
        }
      }).catch((e) => {
        const { message: errMsg } = parseError(e);
        messageApi.error(errMsg);
      });
    }
  }, [isLoggedIn, currentUser, fetchLastCalculation, messageApi]);

  const handleUnitToggle = useCallback((e: { target: { value: string } }) => {
    setShowResult(false);
    setCalculationResult(null);
  }, []);

  const calculateBmi = useCallback(async () => {
    try {
      const values = await form.validateFields();
      setIsCalculating(true);

      let heightCm = values.height_cm;
      let weightKg = values.weight_kg;

      if (activeUnit === 'imperial') {
        heightCm = (values.feet || 0) * 30.48 + (values.inches || 0) * 2.54;
        weightKg = (values.weight_lbs || 0) * 0.453592;
      }

      const payload = {
        height_cm: heightCm,
        weight_kg: weightKg,
        unit: activeUnit === 'metric' ? 'METRIC' : 'IMPERIAL',
        user_id: currentUser?.userId || null,
        notes: values.notes || null
      };

      const response = await BmiService.calculate(payload);
      setCalculationResult(response.data);
      setShowResult(true);
      messageApi.success('BMI calculated successfully!');
    } catch (e) {
      const { message: errMsg } = parseError(e);
      messageApi.error(errMsg);
    } finally {
      setIsCalculating(false);
    }
  }, [form, activeUnit, currentUser, messageApi]);

  const calculateAndSave = useCallback(async () => {
    try {
      const values = await form.validateFields();
      setIsCalculating(true);

      let heightCm = values.height_cm;
      let weightKg = values.weight_kg;

      if (activeUnit === 'imperial') {
        heightCm = (values.feet || 0) * 30.48 + (values.inches || 0) * 2.54;
        weightKg = (values.weight_lbs || 0) * 0.453592;
      }

      const payload = {
        height_cm: heightCm,
        weight_kg: weightKg,
        unit: activeUnit === 'metric' ? 'METRIC' : 'IMPERIAL',
        notes: values.notes || null,
        user_id: currentUser?.userId
      };

      const response = await BmiService.createCalculation(payload);
      setLastCalculation(response.data);
      setCalculationResult({
        bmi_value: response.data.bmi_value,
        bmi_category: response.data.bmi_category,
        category_id: response.data.category_id,
        height_cm: response.data.height_cm,
        weight_kg: response.data.weight_kg,
        unit: response.data.unit,
        color_code: null,
        health_risk: null,
        recommendations: null,
        calculation_id: response.data.calculation_id,
        calculated_at: response.data.calculated_at
      });
      setShowResult(true);
      messageApi.success('BMI calculated and saved to your history!');
    } catch (e) {
      const { message: errMsg } = parseError(e);
      messageApi.error(errMsg);
    } finally {
      setIsCalculating(false);
    }
  }, [form, activeUnit, currentUser, messageApi]);

  const resetCalculator = useCallback(() => {
    setCalculationResult(null);
    setShowResult(false);
    form.resetFields();
  }, [form]);

  const navigateToRegister = useCallback(() => {
    navigate('/register');
  }, [navigate]);

  const navigateToHistory = useCallback(() => {
    navigate('/history');
  }, [navigate]);

  const navigateToLogin = useCallback(() => {
    navigate('/login');
  }, [navigate]);

  const navigateToDashboard = useCallback(() => {
    navigate('/dashboard');
  }, [navigate]);

  const rootStyle: CSSProperties = {
    minHeight: '100vh',
    width: '100%',
    background: 'linear-gradient(135deg, #f0f5ff 0%, #e6fffb 100%)',
    padding: '24px'
  };

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

      <Space size="middle" style={{ display: 'flex', justifyContent: 'center', marginBottom: '16px' }}>
        <Button type="link" size="small" onClick={navigateToDashboard}>
          Dashboard
        </Button>
        <Button type="link" size="small" onClick={navigateToLogin}>
          Login
        </Button>
      </Space>

      <Row gutter={[24, 24]} justify="center" style={{ maxWidth: '1200px', margin: '0 auto', width: '100%' }}>
        <Col xs={24} sm={24} md={12} lg={10}>
          <Card
            title="Enter Your Measurements"
            bordered
            style={{ borderRadius: '8px', boxShadow: '0 2px 8px rgba(0,0,0,0.08)' }}
          >
            <div style={{ marginBottom: '20px', textAlign: 'center' }}>
              <Typography.Text strong style={{ marginRight: '12px' }}>
                Unit System
              </Typography.Text>
              <Radio.Group
                value={activeUnit}
                onChange={handleUnitToggle}
                optionType="button"
                buttonStyle="solid"
                options={[
                  { label: 'Metric (cm/kg)', value: 'metric' },
                  { label: 'Imperial (ft/lbs)', value: 'imperial' }
                ]}
              />
            </div>

            <Form form={form} layout="vertical" name="bmi_form" requiredMark>
              {activeUnit === 'metric' && (
                <Form.Item
                  label="Height (cm)"
                  name="height_cm"
                  rules={[
                    { required: true, message: 'Please enter your height' },
                    { type: 'number', min: 50, max: 300, message: 'Height must be between 50 and 300 cm' }
                  ]}
                >
                  <InputNumber
                    placeholder="Enter height in cm"
                    min={50}
                    max={300}
                    step={1}
                    addonAfter="cm"
                    style={{ width: '100%' }}
                  />
                </Form.Item>
              )}

              {activeUnit === 'imperial' && (
                <div>
                  <Space size="middle" direction="horizontal" style={{ width: '100%', display: 'flex' }}>
                    <Form.Item
                      label="Feet"
                      name="feet"
                      rules={[{ required: true, message: 'Feet required' }]}
                      style={{ flex: 1 }}
                    >
                      <InputNumber
                        placeholder="Feet"
                        min={1}
                        max={9}
                        step={1}
                        addonAfter="ft"
                        style={{ width: '100%' }}
                      />
                    </Form.Item>
                    <Form.Item
                      label="Inches"
                      name="inches"
                      rules={[{ required: false }]}
                      style={{ flex: 1 }}
                    >
                      <InputNumber
                        placeholder="Inches"
                        min={0}
                        max={11}
                        step={1}
                        addonAfter="in"
                        style={{ width: '100%' }}
                      />
                    </Form.Item>
                  </Space>
                </div>
              )}

              {activeUnit === 'metric' && (
                <Form.Item
                  label="Weight (kg)"
                  name="weight_kg"
                  rules={[
                    { required: true, message: 'Please enter your weight' },
                    { type: 'number', min: 10, max: 500, message: 'Weight must be between 10 and 500 kg' }
                  ]}
                >
                  <InputNumber
                    placeholder="Enter weight in kg"
                    min={10}
                    max={500}
                    step={0.1}
                    precision={1}
                    addonAfter="kg"
                    style={{ width: '100%' }}
                  />
                </Form.Item>
              )}

              {activeUnit === 'imperial' && (
                <Form.Item
                  label="Weight (lbs)"
                  name="weight_lbs"
                  rules={[
                    { required: true, message: 'Please enter your weight' },
                    { type: 'number', min: 22, max: 1100, message: 'Weight must be between 22 and 1100 lbs' }
                  ]}
                >
                  <InputNumber
                    placeholder="Enter weight in lbs"
                    min={22}
                    max={1100}
                    step={0.1}
                    precision={1}
                    addonAfter="lbs"
                    style={{ width: '100%' }}
                  />
                </Form.Item>
              )}

              {isLoggedIn && (
                <Form.Item label="Notes (optional)" name="notes">
                  <Input.TextArea
                    placeholder="e.g., morning weight, after workout..."
                    rows={2}
                    maxLength={200}
                    showCount
                  />
                </Form.Item>
              )}

              <Space
                size="middle"
                direction="horizontal"
                style={{ width: '100%', display: 'flex', justifyContent: 'center', marginTop: '8px' }}
              >
                {!isLoggedIn && (
                  <Button
                    type="primary"
                    size="large"
                    htmlType="submit"
                    icon={<CalculatorOutlined />}
                    loading={isCalculating}
                    onClick={calculateBmi}
                  >
                    Calculate BMI
                  </Button>
                )}
                {isLoggedIn && (
                  <Button
                    type="primary"
                    size="large"
                    htmlType="submit"
                    icon={<SaveOutlined />}
                    loading={isCalculating}
                    onClick={calculateAndSave}
                  >
                    Calculate & Save
                  </Button>
                )}
                <Button size="large" icon={<ClearOutlined />} onClick={resetCalculator}>
                  Reset
                </Button>
              </Space>
            </Form>
          </Card>
        </Col>

        <Col xs={24} sm={24} md={12} lg={10}>
          {showResult && calculationResult && (
            <Card
              title="Your BMI Result"
              bordered
              style={{ borderRadius: '8px', boxShadow: '0 2px 8px rgba(0,0,0,0.08)' }}
            >
              <div style={{ textAlign: 'center', padding: '16px 0' }}>
                <Typography.Title level={1} style={{ fontSize: '64px', marginBottom: '0', color: categoryColor }}>
                  {calculationResult.bmi_value.toFixed(1)}
                </Typography.Title>
                <Tag color={categoryColor} style={{ fontSize: '16px', padding: '4px 16px', marginTop: '8px' }}>
                  {calculationResult.bmi_category}
                </Tag>
              </div>

              <Progress
                percent={Math.min((calculationResult.bmi_value / 40) * 100, 100)}
                strokeColor={categoryColor}
                showInfo={false}
                strokeLinecap="round"
                style={{ margin: '16px 0' }}
              />

              <div
                style={{
                  display: 'flex',
                  justifyContent: 'space-between',
                  fontSize: '11px',
                  color: '#999',
                  marginBottom: '16px'
                }}
              >
                <Typography.Text type="secondary" style={{ fontSize: '11px', color: '#1890ff' }}>
                  Underweight
                </Typography.Text>
                <Typography.Text type="secondary" style={{ fontSize: '11px', color: '#52c41a' }}>
                  Normal
                </Typography.Text>
                <Typography.Text type="secondary" style={{ fontSize: '11px', color: '#fa8c16' }}>
                  Overweight
                </Typography.Text>
                <Typography.Text type="secondary" style={{ fontSize: '11px', color: '#f5222d' }}>
                  Obese
                </Typography.Text>
              </div>

              <Alert
                message="Healthy BMI Range: 18.5 – 24.9"
                type="info"
                showIcon
                style={{ marginBottom: '16px' }}
              />

              {calculationResult.health_risk && (
                <div style={{ marginBottom: '12px' }}>
                  <Typography.Text strong style={{ display: 'block', marginBottom: '4px' }}>
                    Health Risk
                  </Typography.Text>
                  <Typography.Paragraph type="secondary">
                    {calculationResult.health_risk}
                  </Typography.Paragraph>
                </div>
              )}

              {calculationResult.recommendations && (
                <div style={{ marginBottom: '12px' }}>
                  <Typography.Text strong style={{ display: 'block', marginBottom: '4px' }}>
                    Recommendations
                  </Typography.Text>
                  <Typography.Paragraph type="secondary">
                    {calculationResult.recommendations}
                  </Typography.Paragraph>
                </div>
              )}

              {isLoggedIn && lastCalculation && calculationResult && (
                <Card
                  size="small"
                  title="Compared to Last Calculation"
                  style={{ marginTop: '16px', borderRadius: '8px' }}
                >
                  <div style={{ display: 'flex', justifyContent: 'space-around', textAlign: 'center' }}>
                    <Statistic title="Previous BMI" value={lastCalculation.bmi_value} precision={1} />
                    <Statistic
                      title="Current BMI"
                      value={calculationResult.bmi_value}
                      precision={1}
                      valueStyle={{ color: categoryColor }}
                    />
                    {bmiDifference && (
                      <Statistic
                        title="Change"
                        value={bmiDifference}
                        precision={1}
                        prefix={parseFloat(bmiDifference) > 0 ? '+' : ''}
                        valueStyle={{ color: parseFloat(bmiDifference) > 0 ? '#f5222d' : '#52c41a' }}
                      />
                    )}
                  </div>
                </Card>
              )}

              {isLoggedIn && showResult && (
                <Button type="link" block onClick={navigateToHistory} style={{ marginTop: '8px' }}>
                  View Full History
                </Button>
              )}
            </Card>
          )}

          {(!showResult || !calculationResult) && (
            <Card
              bordered
              style={{
                borderRadius: '8px',
                boxShadow: '0 2px 8px rgba(0,0,0,0.08)',
                textAlign: 'center',
                minHeight: '300px',
                display: 'flex',
                alignItems: 'center',
                justifyContent: 'center'
              }}
            >
              <div style={{ textAlign: 'center', padding: '40px' }}>
                <Typography.Title level={1} style={{ fontSize: '64px', marginBottom: '16px' }}>
                  ⚖️
                </Typography.Title>
                <Typography.Text type="secondary" style={{ fontSize: '16px' }}>
                  Enter your height and weight to calculate your BMI
                </Typography.Text>
              </div>
            </Card>
          )}

          {!isLoggedIn && showResult && (
            <>
              <Alert
                message="Want to track your BMI over time?"
                description="Create a free account to save your calculations, view trends, and set health goals."
                type="info"
                showIcon
                style={{ marginTop: '16px', borderRadius: '8px' }}
              />
              <Button type="primary" onClick={navigateToRegister} style={{ marginTop: '12px' }}>
                Sign Up for Free
              </Button>
            </>
          )}
        </Col>
      </Row>
    </div>
  );
};

export default CalculatorPage;