import { useState, useMemo, useEffect, useCallback, CSSProperties } from 'react';
import { Row, Col, Space, Button, Typography, Card, Tag, Statistic, Progress, Alert, Empty, Spin, Modal, Form, Select, InputNumber, DatePicker, message } from 'antd';
import { PlusOutlined, EditOutlined, StopOutlined } from '@ant-design/icons';
import { useNavigate } from 'react-router-dom';
import { GoalService } from '@/services/goal';
import { ROUTES } from '@/constants/routes';
import { parseError } from '@/utils/errorHandler';
import { useAppContext } from '@/store/AppStore';
import dayjs, { Dayjs } from 'dayjs';

interface GoalResponse {
  id: string;
  goal_id: string;
  user_id: string;
  goal_type: string;
  target_value: number;
  current_value: number | null;
  start_date: string;
  target_date: string;
  status: string;
  created_at: string;
  updated_at: string;
}

interface CreateGoalFormValues {
  goal_type: string;
  target_value: number;
  target_date: Dayjs;
}

interface EditGoalFormValues {
  target_value: number;
  target_date: Dayjs;
}

const GoalsPage = () => {
  const [messageApi, contextHolder] = message.useMessage();
  const navigate = useNavigate();
  const { currentUser, userProfile } = useAppContext();

  const [goals, setGoals] = useState<GoalResponse[]>([]);
  const [loading, setLoading] = useState<boolean>(true);
  const [createModalVisible, setCreateModalVisible] = useState<boolean>(false);
  const [editModalVisible, setEditModalVisible] = useState<boolean>(false);
  const [selectedGoalId, setSelectedGoalId] = useState<string | null>(null);
  const [submitting, setSubmitting] = useState<boolean>(false);

  const [createForm] = Form.useForm<CreateGoalFormValues>();
  const [editForm] = Form.useForm<EditGoalFormValues>();

  const activeGoalsCount = useMemo(() => {
    return goals.filter(g => g.status === 'ACTIVE').length;
  }, [goals]);

  const canCreateGoal = useMemo(() => {
    return goals.filter(g => g.status === 'ACTIVE').length < 3;
  }, [goals]);

  const selectedGoal = useMemo(() => {
    return goals.find(g => g.goal_id === selectedGoalId) || null;
  }, [goals, selectedGoalId]);

  const fetchUserGoals = useCallback(async () => {
    if (!currentUser?.userId) return;
    setLoading(true);
    try {
      const response = await GoalService.getUserGoals(currentUser.userId, { limit: 50, offset: 0 });
      setGoals(response.data);
    } catch (e) {
      const { message: errorMessage } = parseError(e);
      messageApi.error(errorMessage);
    } finally {
      setLoading(false);
    }
  }, [currentUser, messageApi]);

  useEffect(() => {
    void fetchUserGoals();
  }, [fetchUserGoals]);

  const openCreateModal = useCallback(() => {
    setCreateModalVisible(true);
  }, []);

  const closeCreateModal = useCallback(() => {
    setCreateModalVisible(false);
    createForm.resetFields();
  }, [createForm]);

  const openEditModal = useCallback((goalId: string) => {
    setEditModalVisible(true);
    setSelectedGoalId(goalId);
    const goal = goals.find(g => g.goal_id === goalId);
    if (goal) {
      editForm.setFieldsValue({
        target_value: goal.target_value,
        target_date: dayjs(goal.target_date)
      });
    }
  }, [goals, editForm]);

  const closeEditModal = useCallback(() => {
    setEditModalVisible(false);
    setSelectedGoalId(null);
    editForm.resetFields();
  }, [editForm]);

  const handleCreateGoal = useCallback(async () => {
    try {
      const values = await createForm.validateFields();
      setSubmitting(true);
      const payload = {
        goal_type: values.goal_type,
        target_value: values.target_value,
        current_value: userProfile?.currentWeightKg || null,
        start_date: new Date().toISOString().split('T')[0],
        target_date: values.target_date.format('YYYY-MM-DD'),
        status: 'ACTIVE',
        user_id: currentUser.userId
      };
      await GoalService.create(payload);
      messageApi.success('Goal created successfully!');
      closeCreateModal();
      await fetchUserGoals();
    } catch (e) {
      const { message: errorMessage } = parseError(e);
      messageApi.error(errorMessage || 'Failed to create goal. Please try again.');
    } finally {
      setSubmitting(false);
    }
  }, [createForm, currentUser, userProfile, messageApi, closeCreateModal, fetchUserGoals]);

  const handleUpdateGoal = useCallback(async () => {
    if (!selectedGoalId) return;
    try {
      const values = await editForm.validateFields();
      setSubmitting(true);
      const payload = {
        target_value: values.target_value,
        target_date: values.target_date.format('YYYY-MM-DD')
      };
      await GoalService.update(selectedGoalId, payload);
      messageApi.success('Goal updated successfully!');
      closeEditModal();
      await fetchUserGoals();
    } catch (e) {
      const { message: errorMessage } = parseError(e);
      messageApi.error(errorMessage || 'Failed to update goal. Please try again.');
    } finally {
      setSubmitting(false);
    }
  }, [selectedGoalId, editForm, messageApi, closeEditModal, fetchUserGoals]);

  const handleAbandonGoal = useCallback((goalId: string) => {
    Modal.confirm({
      title: 'Abandon Goal',
      content: 'Are you sure you want to abandon this goal?',
      okText: 'Yes, Abandon',
      cancelText: 'Cancel',
      okButtonProps: { danger: true },
      onOk: async () => {
        try {
          setSelectedGoalId(goalId);
          await GoalService.abandon(goalId);
          messageApi.info('Goal abandoned.');
          await fetchUserGoals();
        } catch (e) {
          const { message: errorMessage } = parseError(e);
          messageApi.error(errorMessage || 'Failed to abandon goal. Please try again.');
        }
      }
    });
  }, [messageApi, fetchUserGoals]);

  const navigateToCalculator = useCallback(() => {
    navigate(ROUTES.HOME);
  }, [navigate]);

  const navigateToDashboard = useCallback(() => {
    navigate(ROUTES.DASHBOARD);
  }, [navigate]);

  const navigateToHistory = useCallback(() => {
    navigate(ROUTES.HISTORY);
  }, [navigate]);

  const navigateToProfile = useCallback(() => {
    navigate(ROUTES.PROFILE);
  }, [navigate]);

  const calculateProgress = useCallback((goal: GoalResponse): number => {
    if (!goal.current_value) return 0;
    const startValue = goal.current_value;
    const targetValue = goal.target_value;
    const currentValue = goal.current_value;
    
    if (goal.goal_type === 'WEIGHT') {
      const totalChange = Math.abs(targetValue - startValue);
      const currentChange = Math.abs(currentValue - startValue);
      return totalChange > 0 ? Math.min(100, (currentChange / totalChange) * 100) : 0;
    }
    
    return 0;
  }, []);

  const calculateDaysRemaining = useCallback((targetDate: string): number => {
    const today = dayjs();
    const target = dayjs(targetDate);
    return target.diff(today, 'day');
  }, []);

  const calculateWeeklyChange = useCallback((goal: GoalResponse): number => {
    if (!goal.current_value) return 0;
    const daysRemaining = calculateDaysRemaining(goal.target_date);
    if (daysRemaining <= 0) return 0;
    const totalChange = Math.abs(goal.target_value - goal.current_value);
    const weeksRemaining = daysRemaining / 7;
    return weeksRemaining > 0 ? totalChange / weeksRemaining : 0;
  }, [calculateDaysRemaining]);

  const isOverdue = useCallback((targetDate: string): boolean => {
    return calculateDaysRemaining(targetDate) < 0;
  }, [calculateDaysRemaining]);

  const isAchieved = useCallback((goal: GoalResponse): boolean => {
    if (!goal.current_value) return false;
    if (goal.goal_type === 'WEIGHT') {
      return Math.abs(goal.current_value - goal.target_value) < 0.5;
    }
    return false;
  }, []);

  const getStatusColor = useCallback((status: string): string => {
    switch (status) {
      case 'ACTIVE':
        return 'green';
      case 'ACHIEVED':
        return 'blue';
      case 'ABANDONED':
        return 'red';
      default:
        return 'default';
    }
  }, []);

  const getBorderColor = useCallback((goal: GoalResponse): string => {
    if (goal.status === 'ACHIEVED') return '#52c41a';
    if (goal.status === 'ABANDONED') return '#ff4d4f';
    if (isOverdue(goal.target_date)) return '#faad14';
    return '#1677ff';
  }, [isOverdue]);

  const rootStyle: CSSProperties = {
    minHeight: '100vh',
    height: '100%',
    width: '100%',
    display: 'flex',
    flexDirection: 'column',
    background: '#f5f5f5'
  };

  return (
    <div style={rootStyle}>
      {contextHolder}
      <div style={{ padding: '24px 24px 0 24px' }}>
        <Row justify="space-between" align="middle" style={{ marginBottom: '24px' }}>
          <Typography.Title level={2} style={{ margin: 0 }}>
            My Goals
          </Typography.Title>
          <div style={{ display: 'flex', flexDirection: 'column', gap: '4px', alignItems: 'flex-end' }}>
            <Typography.Text type="secondary" style={{ display: 'block', marginBottom: '8px' }}>
              {activeGoalsCount} / 3 active goals
            </Typography.Text>
            <Button
              type="primary"
              icon={<PlusOutlined />}
              onClick={openCreateModal}
              disabled={!canCreateGoal}
            >
              Set New Goal
            </Button>
          </div>
        </Row>
        <Space size="middle">
          <Button type="default" onClick={navigateToCalculator}>
            Calculator
          </Button>
          <Button type="default" onClick={navigateToDashboard}>
            Dashboard
          </Button>
          <Button type="default" onClick={navigateToHistory}>
            History
          </Button>
          <Button type="default" onClick={navigateToProfile}>
            Profile
          </Button>
        </Space>
      </div>

      <div style={{ padding: '0 24px 24px 24px' }}>
        {loading ? (
          <div style={{ display: 'flex', justifyContent: 'center', padding: '48px' }}>
            <Spin size="large" tip="Loading goals..." />
          </div>
        ) : goals.length === 0 ? (
          <div style={{ padding: '48px' }}>
            <Empty description="No goals yet. Set your first goal to start tracking your progress!" />
          </div>
        ) : (
          <Row gutter={[16, 16]}>
            {goals.map((goal) => {
              const progress = calculateProgress(goal);
              const daysRemaining = calculateDaysRemaining(goal.target_date);
              const weeklyChange = calculateWeeklyChange(goal);
              const overdue = isOverdue(goal.target_date);
              const achieved = isAchieved(goal);

              return (
                <Col xs={24} sm={24} md={12} lg={8} xl={8} key={goal.goal_id}>
                  <Card
                    hoverable
                    style={{
                      height: '100%',
                      borderLeft: `4px solid ${getBorderColor(goal)}`,
                      display: 'flex',
                      flexDirection: 'column'
                    }}
                    bodyStyle={{ display: 'flex', flexDirection: 'column', height: '100%' }}
                  >
                    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '12px' }}>
                      <Tag color="blue">{goal.goal_type}</Tag>
                      <Tag color={getStatusColor(goal.status)}>{goal.status}</Tag>
                    </div>

                    <Statistic
                      title="Target"
                      value={goal.target_value}
                      precision={1}
                      style={{ marginBottom: '8px' }}
                    />

                    <Statistic
                      title="Current"
                      value={goal.current_value || 0}
                      precision={1}
                      style={{ marginBottom: '12px' }}
                    />

                    <div style={{ marginBottom: '12px' }}>
                      <div style={{ marginBottom: '4px', fontSize: '12px', color: '#8c8c8c' }}>Progress</div>
                      <Progress
                        percent={Math.round(progress)}
                        size="small"
                        status="active"
                      />
                    </div>

                    <Typography.Text style={{ display: 'block', marginBottom: '4px' }}>
                      {daysRemaining > 0 ? `${daysRemaining} days remaining` : overdue ? 'Overdue' : 'Target date reached'}
                    </Typography.Text>

                    <Typography.Text type="secondary" style={{ display: 'block', marginBottom: '12px' }}>
                      Required weekly change: {weeklyChange.toFixed(1)} {goal.goal_type === 'WEIGHT' ? 'kg' : 'BMI'}
                    </Typography.Text>

                    {overdue && goal.status === 'ACTIVE' && (
                      <Alert
                        type="warning"
                        message="This goal is overdue"
                        showIcon
                        banner
                        style={{ marginBottom: '12px' }}
                      />
                    )}

                    {achieved && goal.status === 'ACTIVE' && (
                      <Alert
                        type="success"
                        message="Congratulations! Goal achieved! 🎉"
                        description="Consider setting a new goal to continue your progress."
                        showIcon
                        style={{ marginBottom: '12px' }}
                      />
                    )}

                    {goal.status === 'ACTIVE' && (
                      <Space style={{ marginTop: 'auto' }}>
                        <Button
                          type="link"
                          size="small"
                          icon={<EditOutlined />}
                          onClick={() => openEditModal(goal.goal_id)}
                        >
                          Edit
                        </Button>
                        <Button
                          type="link"
                          danger
                          size="small"
                          icon={<StopOutlined />}
                          onClick={() => handleAbandonGoal(goal.goal_id)}
                        >
                          Abandon
                        </Button>
                      </Space>
                    )}
                  </Card>
                </Col>
              );
            })}
          </Row>
        )}
      </div>

      <Modal
        title="Set New Goal"
        open={createModalVisible}
        onOk={handleCreateGoal}
        onCancel={closeCreateModal}
        okText="Create Goal"
        cancelText="Cancel"
        confirmLoading={submitting}
        destroyOnClose
      >
        <Form form={createForm} layout="vertical">
          {!canCreateGoal && (
            <Alert
              type="info"
              message="You already have 3 active goals. Please complete or abandon an existing goal before creating a new one."
              showIcon
              style={{ marginBottom: '16px' }}
            />
          )}

          <Form.Item
            label="Goal Type"
            name="goal_type"
            rules={[{ required: true, message: 'Please select a goal type' }]}
          >
            <Select
              placeholder="Select goal type"
              options={[
                { value: 'BMI', label: 'BMI Goal' },
                { value: 'WEIGHT', label: 'Weight Goal' }
              ]}
            />
          </Form.Item>

          <Form.Item
            label="Target Value"
            name="target_value"
            rules={[{ required: true, message: 'Please enter a target value' }]}
            tooltip="For BMI: 18.5-30.0, For Weight: in kg"
          >
            <InputNumber
              placeholder="Enter target value"
              min={10}
              max={500}
              step={0.1}
              style={{ width: '100%' }}
            />
          </Form.Item>

          <Form.Item
            label="Target Date"
            name="target_date"
            rules={[{ required: true, message: 'Please select a target date' }]}
          >
            <DatePicker
              style={{ width: '100%' }}
              placeholder="Select target date"
              disabledDate={(current) => current && current < dayjs().add(7, 'day')}
            />
          </Form.Item>
        </Form>
      </Modal>

      <Modal
        title="Edit Goal"
        open={editModalVisible}
        onOk={handleUpdateGoal}
        onCancel={closeEditModal}
        okText="Update Goal"
        cancelText="Cancel"
        confirmLoading={submitting}
        destroyOnClose
      >
        <Form form={editForm} layout="vertical">
          <Form.Item
            label="Target Value"
            name="target_value"
            rules={[{ required: true, message: 'Please enter a target value' }]}
          >
            <InputNumber
              placeholder="Enter target value"
              min={10}
              max={500}
              step={0.1}
              style={{ width: '100%' }}
            />
          </Form.Item>

          <Form.Item
            label="Target Date"
            name="target_date"
            rules={[{ required: true, message: 'Please select a target date' }]}
          >
            <DatePicker
              style={{ width: '100%' }}
              placeholder="Select target date"
            />
          </Form.Item>
        </Form>
      </Modal>
    </div>
  );
};

export default GoalsPage;