import { useState, useMemo, useEffect, useCallback, CSSProperties } from 'react';
import { Layout, Button, Typography, Space, Card, Descriptions, Tabs, Table, Timeline, Modal, Drawer, Form, Input, InputNumber, message } from 'antd';
import { ArrowLeftOutlined, EditOutlined, CloseCircleOutlined, PlusOutlined, DeleteOutlined } from '@ant-design/icons';
import { request } from '../api/client';
import { useNavigate, useParams } from 'react-router-dom';
import { useAppContext } from '../store/AppContext';

const { TextArea } = Input;

interface AsnLineItem {
  id: string;
  submenu_id: number;
  sku: string | null;
  cases: number | null;
  asn_id: string;
  notes: string | null;
  metadata: string | null;
  version: number;
  deleted_at: string | null;
  created_at: string;
  updated_at: string;
}

interface AsnDetail {
  id: string;
  submenu_id: number;
  inbound_shipment_no: string;
  total_skus: number;
  notes: string | null;
  metadata: string | null;
  version: number;
  deleted_at: string | null;
  created_at: string;
  updated_at: string;
  line_items?: AsnLineItem[];
}

interface AsnHistory {
  id: string;
  submenu_id: number;
  asn_id: string | null;
  change_date: string;
  change_description: string | null;
  changed_by: string | null;
  change_type: string;
  created_at: string;
  updated_at: string;
}

export default function AsnDetailPage() {
  const { asnId } = useParams<{ asnId: string }>();
  const navigate = useNavigate();
  const { currentUser } = useAppContext();
  const [messageApi, contextHolder] = message.useMessage();

  const [asnDetail, setAsnDetail] = useState<AsnDetail | null>(null);
  const [lineItems, setLineItems] = useState<AsnLineItem[]>([]);
  const [asnHistories, setAsnHistories] = useState<AsnHistory[]>([]);
  const [loading, setLoading] = useState<boolean>(true);
  const [addLineItemModalVisible, setAddLineItemModalVisible] = useState<boolean>(false);
  const [editAsnDrawerVisible, setEditAsnDrawerVisible] = useState<boolean>(false);
  const [batchUpdateDrawerVisible, setBatchUpdateDrawerVisible] = useState<boolean>(false);
  const [activeTab, setActiveTab] = useState<string>('line_items');
  const [selectedLineItemIds, setSelectedLineItemIds] = useState<string[]>([]);
  const [selectedLineItemId, setSelectedLineItemId] = useState<string>('');

  const [addLineItemForm] = Form.useForm();
  const [editAsnForm] = Form.useForm();
  const [batchUpdateForm] = Form.useForm();

  const totalLineItems = useMemo(() => lineItems.length, [lineItems]);

  const fetchAsnDetails = useCallback(async () => {
    if (!asnId) return;
    try {
      const result = await request<AsnDetail>({
        method: 'GET',
        path: '/asns/{asn_id}/details',
        pathParams: { asn_id: asnId }
      });
      setAsnDetail(result.data);
    } catch (error) {
      messageApi.error('Failed to load ASN details');
    }
  }, [asnId, messageApi]);

  const fetchLineItems = useCallback(async () => {
    if (!asnId) return;
    try {
      const result = await request<AsnLineItem[]>({
        method: 'GET',
        path: '/asns/line-items',
        query: { asn_id: asnId, limit: 100 }
      });
      setLineItems(result.data);
    } catch (error) {
      messageApi.error('Failed to load line items');
    }
  }, [asnId, messageApi]);

  const fetchAsnHistories = useCallback(async () => {
    if (!asnId) return;
    try {
      const result = await request<AsnHistory[]>({
        method: 'GET',
        path: '/asns/histories',
        query: { asn_id: asnId, limit: 50 }
      });
      setAsnHistories(result.data);
    } catch (error) {
      messageApi.error('Failed to load ASN histories');
    }
  }, [asnId, messageApi]);

  useEffect(() => {
    const loadData = async () => {
      setLoading(true);
      await Promise.all([fetchAsnDetails(), fetchLineItems(), fetchAsnHistories()]);
      setLoading(false);
    };
    loadData();
  }, [fetchAsnDetails, fetchLineItems, fetchAsnHistories]);

  const openAddLineItemModal = useCallback(() => {
    setAddLineItemModalVisible(true);
  }, []);

  const closeAddLineItemModal = useCallback(() => {
    setAddLineItemModalVisible(false);
    addLineItemForm.resetFields();
  }, [addLineItemForm]);

  const openEditAsnDrawer = useCallback(() => {
    if (asnDetail) {
      editAsnForm.setFieldsValue({
        inbound_shipment_no: asnDetail.inbound_shipment_no,
        total_skus: asnDetail.total_skus,
        notes: asnDetail.notes,
        metadata: asnDetail.metadata
      });
    }
    setEditAsnDrawerVisible(true);
  }, [asnDetail, editAsnForm]);

  const closeEditAsnDrawer = useCallback(() => {
    setEditAsnDrawerVisible(false);
    editAsnForm.resetFields();
  }, [editAsnForm]);

  const openBatchUpdateDrawer = useCallback(() => {
    setBatchUpdateDrawerVisible(true);
  }, []);

  const closeBatchUpdateDrawer = useCallback(() => {
    setBatchUpdateDrawerVisible(false);
    batchUpdateForm.resetFields();
  }, [batchUpdateForm]);

  const changeTab = useCallback((key: string) => {
    setActiveTab(key);
  }, []);

  const submitEditAsn = useCallback(async () => {
    if (!asnId || !asnDetail) return;
    try {
      const formValues = await editAsnForm.validateFields();
      
      if (!formValues.inbound_shipment_no) {
        messageApi.error('Inbound shipment number is required');
        return;
      }
      if (formValues.total_skus === undefined || formValues.total_skus === null) {
        messageApi.error('Total SKUs is required');
        return;
      }

      const result = await request<AsnDetail>({
        method: 'PUT',
        path: '/asns/{asn_id}',
        pathParams: { asn_id: asnId },
        body: {
          submenu_id: asnDetail.submenu_id,
          inbound_shipment_no: formValues.inbound_shipment_no,
          total_skus: formValues.total_skus,
          notes: formValues.notes,
          metadata: formValues.metadata
        }
      });
      setAsnDetail(result.data);
      setEditAsnDrawerVisible(false);
      messageApi.success('ASN updated successfully');
      await fetchAsnDetails();
    } catch (error) {
      messageApi.error('Failed to update ASN');
    }
  }, [asnId, asnDetail, editAsnForm, messageApi, fetchAsnDetails]);

  const closeAsnAction = useCallback(async () => {
    if (!asnId || !currentUser) return;
    Modal.confirm({
      title: 'Close ASN',
      content: 'Are you sure you want to close this ASN?',
      onOk: async () => {
        try {
          const result = await request<AsnDetail>({
            method: 'POST',
            path: '/asns/{asn_id}/close',
            pathParams: { asn_id: asnId },
            query: { changed_by: currentUser.id || '' }
          });
          setAsnDetail(result.data);
          messageApi.success('ASN closed successfully');
          await fetchAsnDetails();
        } catch (error) {
          messageApi.error('Failed to close ASN');
        }
      }
    });
  }, [asnId, currentUser, messageApi, fetchAsnDetails]);

  const submitAddLineItem = useCallback(async () => {
    if (!asnId || !asnDetail) return;
    try {
      const formValues = await addLineItemForm.validateFields();
      
      if (!formValues.sku) {
        messageApi.error('SKU is required');
        return;
      }
      if (formValues.cases === undefined || formValues.cases === null) {
        messageApi.error('Cases quantity is required');
        return;
      }

      await request<AsnLineItem>({
        method: 'POST',
        path: '/asns/line-items',
        body: {
          submenu_id: asnDetail.submenu_id,
          sku: formValues.sku,
          cases: formValues.cases,
          asn_id: asnId,
          notes: formValues.notes,
          metadata: formValues.metadata
        }
      });
      setAddLineItemModalVisible(false);
      addLineItemForm.resetFields();
      messageApi.success('Line item added successfully');
      await fetchLineItems();
    } catch (error) {
      messageApi.error('Failed to add line item');
    }
  }, [asnId, asnDetail, addLineItemForm, messageApi, fetchLineItems]);

  const deleteLineItem = useCallback(async (lineItemId: string) => {
    Modal.confirm({
      title: 'Delete Line Item',
      content: 'Are you sure you want to delete this line item?',
      onOk: async () => {
        try {
          await request({
            method: 'DELETE',
            path: '/asns/line-items/{lineitem_id}',
            pathParams: { lineitem_id: lineItemId }
          });
          messageApi.success('Line item deleted');
          await fetchLineItems();
        } catch (error) {
          messageApi.error('Failed to delete line item');
        }
      }
    });
  }, [messageApi, fetchLineItems]);

  const submitBatchUpdate = useCallback(async () => {
    if (!asnId) return;
    try {
      const formValues = await batchUpdateForm.validateFields();
      const result = await request<AsnDetail>({
        method: 'POST',
        path: '/asns/{asn_id}/line-items/batch',
        pathParams: { asn_id: asnId },
        body: formValues
      });
      setAsnDetail(result.data);
      setBatchUpdateDrawerVisible(false);
      batchUpdateForm.resetFields();
      messageApi.success('Batch update completed successfully');
      await fetchAsnDetails();
      await fetchLineItems();
    } catch (error) {
      messageApi.error('Failed to batch update line items');
    }
  }, [asnId, batchUpdateForm, messageApi, fetchAsnDetails, fetchLineItems]);

  const navigateBack = useCallback(() => {
    navigate('/asns');
  }, [navigate]);

  const lineItemColumns = useMemo(() => [
    {
      title: 'Line Item ID',
      dataIndex: 'id',
      key: 'id'
    },
    {
      title: 'SKU',
      dataIndex: 'sku',
      key: 'sku'
    },
    {
      title: 'Cases',
      dataIndex: 'cases',
      key: 'cases'
    },
    {
      title: 'Notes',
      dataIndex: 'notes',
      key: 'notes'
    },
    {
      title: 'Created At',
      dataIndex: 'created_at',
      key: 'created_at'
    },
    {
      title: 'Actions',
      key: 'actions',
      render: (_: unknown, record: AsnLineItem) => (
        <Button
          type="link"
          danger
          icon={<DeleteOutlined />}
          onClick={() => deleteLineItem(record.id)}
        >
          Delete
        </Button>
      )
    }
  ], [deleteLineItem]);

  const timelineItems = useMemo(() => {
    return asnHistories.map((history) => ({
      children: (
        <div>
          <div><strong>{history.change_date}</strong></div>
          <div>{history.change_description}</div>
          <div><em>Type: {history.change_type}</em></div>
          <div><small>Changed by: {history.changed_by}</small></div>
        </div>
      )
    }));
  }, [asnHistories]);

  const descriptionsItems = useMemo(() => {
    if (!asnDetail) return [];
    return [
      { label: 'ASN ID', children: asnDetail.id },
      { label: 'Inbound Shipment No', children: asnDetail.inbound_shipment_no },
      { label: 'Total SKUs', children: asnDetail.total_skus },
      { label: 'Version', children: asnDetail.version },
      { label: 'Created At', children: asnDetail.created_at },
      { label: 'Updated At', children: asnDetail.updated_at },
      { label: 'Notes', children: asnDetail.notes, span: 2 }
    ];
  }, [asnDetail]);

  const tabItems = useMemo(() => [
    {
      key: 'line_items',
      label: 'Line Items',
      children: (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
          <Space size="middle" style={{ marginBottom: 16 }}>
            <Button type="primary" icon={<PlusOutlined />} onClick={openAddLineItemModal}>
              Add Line Item
            </Button>
            <Button type="default" icon={<EditOutlined />} onClick={openBatchUpdateDrawer}>
              Batch Update
            </Button>
          </Space>
          <Table
            columns={lineItemColumns}
            dataSource={lineItems}
            rowKey="id"
            pagination={{ pageSize: 10 }}
            rowSelection={{
              selectedRowKeys: selectedLineItemIds,
              onChange: (keys) => setSelectedLineItemIds(keys as string[])
            }}
          />
        </div>
      )
    },
    {
      key: 'history',
      label: 'History',
      children: (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
          <Timeline items={timelineItems} />
        </div>
      )
    }
  ], [lineItemColumns, lineItems, selectedLineItemIds, openAddLineItemModal, openBatchUpdateDrawer, timelineItems]);

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

  return (
    <div style={rootStyle}>
      {contextHolder}
      <div style={{ marginBottom: 24, display: 'flex', flexDirection: 'column', gap: 8 }}>
        <Button type="link" icon={<ArrowLeftOutlined />} onClick={navigateBack} style={{ marginBottom: 8, alignSelf: 'flex-start' }}>
          Back to ASN List
        </Button>
        <Typography.Title level={2} style={{ marginBottom: 0 }}>
          ASN Details
        </Typography.Title>
        <Space size="middle" style={{ marginTop: 16 }}>
          <Button type="default" icon={<EditOutlined />} onClick={openEditAsnDrawer}>
            Edit ASN
          </Button>
          <Button type="primary" danger icon={<CloseCircleOutlined />} onClick={closeAsnAction}>
            Close ASN
          </Button>
        </Space>
      </div>

      <Card title="ASN Information" style={{ marginBottom: 24 }}>
        <Descriptions bordered column={2} items={descriptionsItems} />
      </Card>

      <Tabs activeKey={activeTab} items={tabItems} onChange={changeTab} />

      <Modal
        title="Add Line Item"
        open={addLineItemModalVisible}
        onOk={submitAddLineItem}
        onCancel={closeAddLineItemModal}
        okText="Add"
        cancelText="Cancel"
        width={520}
      >
        <Form form={addLineItemForm} layout="vertical">
          <Form.Item name="sku" label="SKU" rules={[{ required: true, message: 'SKU is required' }]}>
            <Input placeholder="Enter SKU" />
          </Form.Item>
          <Form.Item name="cases" label="Cases (Quantity)" rules={[{ required: true, message: 'Cases quantity is required' }]}>
            <InputNumber placeholder="Enter quantity" min={1} style={{ width: '100%' }} />
          </Form.Item>
          <Form.Item name="notes" label="Notes">
            <TextArea placeholder="Optional notes" />
          </Form.Item>
          <Form.Item name="metadata" label="Metadata">
            <TextArea placeholder="Optional metadata" />
          </Form.Item>
        </Form>
      </Modal>

      <Drawer
        title="Edit ASN"
        open={editAsnDrawerVisible}
        onClose={closeEditAsnDrawer}
        width={520}
        placement="right"
      >
        <Form form={editAsnForm} layout="vertical">
          <Form.Item name="inbound_shipment_no" label="Inbound Shipment No" rules={[{ required: true }]}>
            <Input />
          </Form.Item>
          <Form.Item name="total_skus" label="Total SKUs" rules={[{ required: true }]}>
            <InputNumber min={0} style={{ width: '100%' }} />
          </Form.Item>
          <Form.Item name="notes" label="Notes">
            <TextArea />
          </Form.Item>
          <Form.Item name="metadata" label="Metadata">
            <TextArea />
          </Form.Item>
        </Form>
        <Button type="primary" htmlType="submit" block style={{ marginTop: 16 }} onClick={submitEditAsn}>
          Save Changes
        </Button>
      </Drawer>

      <Drawer
        title="Batch Update Line Items"
        open={batchUpdateDrawerVisible}
        onClose={closeBatchUpdateDrawer}
        width={640}
        placement="right"
      >
        <Form form={batchUpdateForm} layout="vertical">
          <Form.Item name="line_items" label="Line Items (JSON)" rules={[{ required: true }]}>
            <TextArea placeholder="Enter line items data for batch update" rows={10} />
          </Form.Item>
        </Form>
        <Button type="primary" htmlType="submit" block style={{ marginTop: 16 }} onClick={submitBatchUpdate}>
          Apply Batch Update
        </Button>
      </Drawer>
    </div>
  );
}