import { useState, useMemo, useEffect, useCallback, CSSProperties } from 'react';
import { Table, Card, Button, Space, Input, DatePicker, Typography, Modal, Form, Tag, Dropdown, message } from 'antd';
import type { TableColumnsType, TablePaginationConfig } from 'antd';
import type { MenuProps } from 'antd';
import {
  CalculatorOutlined,
  DashboardOutlined,
  AimOutlined,
  UserOutlined,
  EditOutlined,
  DeleteOutlined,
  DownloadOutlined,
  FileExcelOutlined,
  FilePdfOutlined
} 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';
import dayjs, { Dayjs } from 'dayjs';

const { RangePicker } = DatePicker;
const { Title, Text } = Typography;

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;
}

interface BmiCategory {
  id: string;
  category_id: string;
  category_name: string;
  min_bmi: number;
  max_bmi: number | null;
  color_code: string | null;
  description: string | null;
  health_risk: string | null;
  recommendations: string | null;
  created_at: string;
  updated_at: string;
}

interface ChartDataPoint {
  date: string;
  bmi: number;
  weight: number;
  category: string;
}

type ChartMode = 'bmi' | 'weight';

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

  const [calculations, setCalculations] = useState<BmiCalculation[]>([]);
  const [calculationsTotal, setCalculationsTotal] = useState<number>(0);
  const [loading, setLoading] = useState<boolean>(false);
  const [currentPage, setCurrentPage] = useState<number>(1);
  const [pageSize, setPageSize] = useState<number>(10);
  const [sortField, setSortField] = useState<string>('calculated_at');
  const [sortOrder, setSortOrder] = useState<string>('descend');
  const [searchText, setSearchText] = useState<string>('');
  const [dateRange, setDateRange] = useState<[Dayjs, Dayjs] | null>(null);
  const [chartMode, setChartMode] = useState<ChartMode>('bmi');
  const [editModalVisible, setEditModalVisible] = useState<boolean>(false);
  const [deleteModalVisible, setDeleteModalVisible] = useState<boolean>(false);
  const [selectedCalculation, setSelectedCalculation] = useState<BmiCalculation | null>(null);
  const [categories, setCategories] = useState<BmiCategory[]>([]);

  const paginationOffset = useMemo(() => {
    return (currentPage - 1) * pageSize;
  }, [currentPage, pageSize]);

  const chartData = useMemo<ChartDataPoint[]>(() => {
    return calculations.map(c => ({
      date: c.calculated_at,
      bmi: c.bmi_value,
      weight: c.weight_kg,
      category: c.bmi_category
    }));
  }, [calculations]);

  const fetchCalculations = useCallback(async () => {
    if (!currentUser?.userId) return;
    setLoading(true);
    try {
      const response = await BmiService.listCalculations({
        limit: pageSize,
        offset: paginationOffset,
        user_id: currentUser.userId,
        is_deleted: false
      });
      setCalculations(response.data || []);
      setCalculationsTotal(response.data?.length || 0);
    } catch (e) {
      const { message: errorMessage } = parseError(e);
      messageApi.error(errorMessage || 'Failed to load calculation history');
    } finally {
      setLoading(false);
    }
  }, [currentUser, pageSize, paginationOffset, messageApi]);

  const fetchCategories = useCallback(async () => {
    try {
      const response = await BmiService.listCategories({ limit: 50, offset: 0 });
      setCategories(response.data || []);
    } catch (e) {
      const { message: errorMessage } = parseError(e);
      messageApi.error(errorMessage);
    }
  }, [messageApi]);

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

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

  const handlePageChange = (page: number, newPageSize: number) => {
    setCurrentPage(page);
    setPageSize(newPageSize);
  };

  const handleTableChange = (
    pagination: TablePaginationConfig,
    filters: Record<string, any>,
    sorter: any
  ) => {
    if (sorter.field) {
      setSortField(sorter.field);
      setSortOrder(sorter.order || 'ascend');
    }
  };

  const handleSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setSearchText(e.target.value);
    setCurrentPage(1);
  };

  const handleDateRangeChange = (dates: [Dayjs, Dayjs] | null) => {
    setDateRange(dates);
    setCurrentPage(1);
  };

  const handleChartModeToggle = (e: any) => {
    setChartMode(e.target.value);
  };

  const handleEditModalOpen = (record: BmiCalculation) => {
    setSelectedCalculation(record);
    setEditModalVisible(true);
    form.setFieldsValue({ notes: record.notes || '' });
  };

  const handleEditModalClose = () => {
    setEditModalVisible(false);
    setSelectedCalculation(null);
    form.resetFields();
  };

  const handleDeleteModalOpen = (record: BmiCalculation) => {
    setSelectedCalculation(record);
    setDeleteModalVisible(true);
  };

  const handleDeleteModalClose = () => {
    setDeleteModalVisible(false);
    setSelectedCalculation(null);
  };

  const handleSaveNotes = async () => {
    if (!selectedCalculation) return;
    try {
      const values = await form.validateFields();
      await BmiService.updateCalculation(selectedCalculation.calculation_id, {
        notes: values.notes
      });
      messageApi.success('Notes updated successfully');
      setEditModalVisible(false);
      setSelectedCalculation(null);
      form.resetFields();
      await fetchCalculations();
    } catch (e) {
      const { message: errorMessage } = parseError(e);
      messageApi.error(errorMessage || 'Failed to update notes');
    }
  };

  const handleDeleteCalculation = async () => {
    if (!selectedCalculation) return;
    try {
      await BmiService.deleteCalculation(selectedCalculation.calculation_id);
      messageApi.success('Calculation deleted');
      setDeleteModalVisible(false);
      setSelectedCalculation(null);
      await fetchCalculations();
    } catch (e) {
      const { message: errorMessage } = parseError(e);
      messageApi.error(errorMessage || 'Failed to delete calculation');
    }
  };

  const handleExportCSV = () => {
    const headers = ['Date', 'Height (cm)', 'Weight (kg)', 'BMI', 'Category', 'Notes'];
    const rows = calculations.map(c => [
      dayjs(c.calculated_at).format('YYYY-MM-DD HH:mm'),
      c.height_cm.toString(),
      c.weight_kg.toString(),
      c.bmi_value.toFixed(1),
      c.bmi_category,
      c.notes || ''
    ]);
    const csvContent = [headers, ...rows].map(row => row.join(',')).join('\n');
    const blob = new Blob([csvContent], { type: 'text/csv' });
    const url = URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = url;
    link.download = 'bmi_history_export.csv';
    link.click();
    URL.revokeObjectURL(url);
    messageApi.success('CSV export started');
  };

  const handleExportPDF = () => {
    messageApi.info('PDF export functionality requires additional library integration');
  };

  const navigateToCalculator = () => {
    navigate(ROUTES.HOME || '/');
  };

  const navigateToDashboard = () => {
    navigate(ROUTES.DASHBOARD || '/dashboard');
  };

  const navigateToGoals = () => {
    navigate(ROUTES.GOALS || '/goals');
  };

  const navigateToProfile = () => {
    navigate(ROUTES.PROFILE || '/profile');
  };

  const getCategoryColor = (categoryName: string): string => {
    const category = categories.find(c => c.category_name === categoryName);
    return category?.color_code || '#1677ff';
  };

  const exportMenuItems: MenuProps['items'] = [
    {
      key: 'csv',
      label: 'Export as CSV',
      icon: <FileExcelOutlined />,
      onClick: handleExportCSV
    },
    {
      key: 'pdf',
      label: 'Export as PDF',
      icon: <FilePdfOutlined />,
      onClick: handleExportPDF
    }
  ];

  const columns = useMemo<TableColumnsType<BmiCalculation>>(() => [
    {
      title: 'Date',
      dataIndex: 'calculated_at',
      key: 'calculated_at',
      sorter: true,
      defaultSortOrder: 'descend',
      render: (date: string) => dayjs(date).format('YYYY-MM-DD HH:mm')
    },
    {
      title: 'Height',
      dataIndex: 'height_cm',
      key: 'height_cm',
      render: (height: number, record: BmiCalculation) => 
        `${height.toFixed(1)} cm`
    },
    {
      title: 'Weight',
      dataIndex: 'weight_kg',
      key: 'weight_kg',
      render: (weight: number, record: BmiCalculation) => 
        `${weight.toFixed(1)} kg`
    },
    {
      title: 'BMI Value',
      dataIndex: 'bmi_value',
      key: 'bmi_value',
      sorter: true,
      render: (bmi: number) => bmi.toFixed(1)
    },
    {
      title: 'Category',
      dataIndex: 'bmi_category',
      key: 'bmi_category',
      render: (category: string) => (
        <Tag color={getCategoryColor(category)}>{category}</Tag>
      )
    },
    {
      title: 'Notes',
      dataIndex: 'notes',
      key: 'notes',
      ellipsis: true,
      render: (notes: string | null) => notes || '-'
    },
    {
      title: 'Actions',
      key: 'actions',
      render: (_: any, record: BmiCalculation) => (
        <Space size="small">
          <Button
            type="link"
            icon={<EditOutlined />}
            size="small"
            onClick={() => handleEditModalOpen(record)}
          >
            Edit
          </Button>
          <Button
            type="link"
            danger
            icon={<DeleteOutlined />}
            size="small"
            onClick={() => handleDeleteModalOpen(record)}
          >
            Delete
          </Button>
        </Space>
      )
    }
  ], [categories]);

  const mainContainerStyle: CSSProperties = {
    minHeight: '100vh',
    width: '100%',
    background: '#f5f5f5',
    padding: '24px'
  };

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

  const filterRowStyle: CSSProperties = {
    display: 'flex',
    justifyContent: 'space-between',
    alignItems: 'center',
    marginBottom: '16px',
    flexWrap: 'wrap',
    gap: '12px'
  };

  const chartHeaderRowStyle: CSSProperties = {
    display: 'flex',
    justifyContent: 'flex-end',
    marginBottom: '16px'
  };

  return (
    <div style={mainContainerStyle}>
      {contextHolder}
      
      <div style={pageHeaderStyle}>
        <Title level={2} style={{ margin: 0 }}>
          Calculation History
        </Title>
        <Space size="middle">
          <Button
            type="default"
            icon={<CalculatorOutlined />}
            onClick={navigateToCalculator}
          >
            Calculator
          </Button>
          <Button
            type="default"
            icon={<DashboardOutlined />}
            onClick={navigateToDashboard}
          >
            Dashboard
          </Button>
          <Button
            type="default"
            icon={<AimOutlined />}
            onClick={navigateToGoals}
          >
            Goals
          </Button>
          <Button
            type="default"
            icon={<UserOutlined />}
            onClick={navigateToProfile}
          >
            Profile
          </Button>
        </Space>
      </div>

      <Card title="BMI Trend" style={{ marginBottom: '24px' }}>
        <div style={chartHeaderRowStyle}>
          <Space>
            <Text>Chart View:</Text>
            <Button.Group>
              <Button
                type={chartMode === 'bmi' ? 'primary' : 'default'}
                onClick={() => setChartMode('bmi')}
              >
                BMI Trend
              </Button>
              <Button
                type={chartMode === 'weight' ? 'primary' : 'default'}
                onClick={() => setChartMode('weight')}
              >
                Weight Trend
              </Button>
            </Button.Group>
          </Space>
        </div>
        <div style={{ width: '100%', height: 300, display: 'flex', alignItems: 'center', justifyContent: 'center', background: '#fafafa', border: '1px dashed #d9d9d9' }}>
          <Text type="secondary">Chart visualization placeholder (requires charting library)</Text>
        </div>
      </Card>

      <Card>
        <div style={filterRowStyle}>
          <Space size="middle" wrap>
            <Input.Search
              placeholder="Search notes..."
              allowClear
              style={{ width: 250 }}
              value={searchText}
              onChange={handleSearchChange}
            />
            <RangePicker
              format="YYYY-MM-DD"
              allowClear
              placeholder={['Start Date', 'End Date']}
              value={dateRange}
              onChange={handleDateRangeChange}
            />
          </Space>
          <Dropdown menu={{ items: exportMenuItems }} trigger={['click']}>
            <Button type="primary" icon={<DownloadOutlined />}>
              Export
            </Button>
          </Dropdown>
        </div>

        <Table<BmiCalculation>
          rowKey="calculation_id"
          columns={columns}
          dataSource={calculations}
          loading={loading}
          onChange={handleTableChange}
          pagination={{
            current: currentPage,
            pageSize: pageSize,
            total: calculationsTotal,
            showSizeChanger: true,
            pageSizeOptions: ['10', '15', '20'],
            showTotal: (total) => `Total ${total} items`,
            onChange: handlePageChange
          }}
          scroll={{ x: 800 }}
        />
      </Card>

      <Modal
        title="Edit Calculation Notes"
        open={editModalVisible}
        onOk={handleSaveNotes}
        onCancel={handleEditModalClose}
        okText="Save"
        cancelText="Cancel"
        destroyOnClose
      >
        <Form form={form} layout="vertical">
          <Form.Item
            name="notes"
            label="Notes"
            rules={[
              { max: 500, message: 'Notes must be 500 characters or less' }
            ]}
          >
            <Input.TextArea
              rows={4}
              maxLength={500}
              showCount
              placeholder="Add notes about this calculation..."
            />
          </Form.Item>
        </Form>
      </Modal>

      <Modal
        title="Delete Calculation"
        open={deleteModalVisible}
        onOk={handleDeleteCalculation}
        onCancel={handleDeleteModalClose}
        okText="Delete"
        okButtonProps={{ danger: true }}
        cancelText="Cancel"
      >
        <div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>
          <Text>
            Are you sure you want to delete this calculation? This action can be undone by an administrator.
          </Text>
          {selectedCalculation && (
            <div style={{ marginTop: '16px' }}>
              <Space direction="vertical" style={{ width: '100%' }}>
                <div><strong>Date:</strong> {dayjs(selectedCalculation.calculated_at).format('YYYY-MM-DD HH:mm')}</div>
                <div><strong>BMI:</strong> {selectedCalculation.bmi_value.toFixed(1)}</div>
                <div><strong>Category:</strong> {selectedCalculation.bmi_category}</div>
              </Space>
            </div>
          )}
        </div>
      </Modal>
    </div>
  );
};

export default HistoryPage;