import { useState, useMemo, useEffect, useCallback } from 'react';
import {
  Layout,
  Typography,
  Button,
  Input,
  Select,
  Table,
  Modal,
  Form,
  Switch,
  Drawer,
  Descriptions,
  Space,
  message
} from 'antd';
import { PlusOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons';
import { useNavigate } from 'react-router-dom';
import { useApi } from '@/hooks/useApi';
import { NotesService } from '@/services/notes';
import { ProductionsService } from '@/services/productions';
import { UsersService } from '@/services/users';
import { parseError } from '@/utils/errorHandler';
import { useAppContext } from '@/store/AppStore';
import { ROUTES } from '@/constants/routes';

interface Note {
  id: string;
  created_by_user_id: string;
  production_id: string | null;
  venue_id: string | null;
  performance_id: string | null;
  rehearsal_id: string | null;
  content: string;
  is_private: boolean;
  created_at: string;
  updated_at: string;
}

interface NoteDetail extends Note {
  created_by_user_first_name?: string;
  created_by_user_last_name?: string;
  production_title?: string;
}

interface Production {
  id: string;
  title: string;
  venue_id: string;
  status: string;
}

interface User {
  id: string;
  first_name: string;
  last_name: string;
  email: string;
  role: string;
}

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

  const [notes, setNotes] = useState<Note[]>([]);
  const [productions, setProductions] = useState<Production[]>([]);
  const [users, setUsers] = useState<User[]>([]);
  const [searchText, setSearchText] = useState<string>('');
  const [filterProductionId, setFilterProductionId] = useState<string>('');
  const [filterAuthorId, setFilterAuthorId] = useState<string>('');
  const [addNoteModalVisible, setAddNoteModalVisible] = useState<boolean>(false);
  const [detailDrawerVisible, setDetailDrawerVisible] = useState<boolean>(false);
  const [selectedNote, setSelectedNote] = useState<NoteDetail | null>(null);
  const [editMode, setEditMode] = useState<boolean>(false);
  const [loading, setLoading] = useState<boolean>(false);

  const { data: notesData, loading: notesLoading, error: notesError, execute: fetchNotes } = useApi(NotesService.list);
  const { data: productionsData, loading: productionsLoading, error: productionsError, execute: fetchProductions } = useApi(ProductionsService.list);
  const { data: usersData, loading: usersLoading, error: usersError, execute: fetchUsers } = useApi(UsersService.list);

  useEffect(() => {
    void fetchNotes({ limit: 100 });
  }, [fetchNotes]);

  useEffect(() => {
    void fetchProductions({ limit: 100 });
  }, [fetchProductions]);

  useEffect(() => {
    void fetchUsers({ limit: 100 });
  }, [fetchUsers]);

  useEffect(() => {
    if (notesData) {
      setNotes(Array.isArray(notesData) ? notesData : []);
    }
  }, [notesData]);

  useEffect(() => {
    if (productionsData) {
      setProductions(Array.isArray(productionsData) ? productionsData : []);
    }
  }, [productionsData]);

  useEffect(() => {
    if (usersData) {
      setUsers(Array.isArray(usersData) ? usersData : []);
    }
  }, [usersData]);

  useEffect(() => {
    if (notesError) {
      const { message: errorMessage } = parseError(notesError);
      messageApi.error(errorMessage);
    }
  }, [notesError, messageApi]);

  useEffect(() => {
    if (productionsError) {
      const { message: errorMessage } = parseError(productionsError);
      messageApi.error(errorMessage);
    }
  }, [productionsError, messageApi]);

  useEffect(() => {
    if (usersError) {
      const { message: errorMessage } = parseError(usersError);
      messageApi.error(errorMessage);
    }
  }, [usersError, messageApi]);

  useEffect(() => {
    setLoading(notesLoading || productionsLoading || usersLoading);
  }, [notesLoading, productionsLoading, usersLoading]);

  const filteredNotes = useMemo(() => {
    return notes.filter(n => {
      const matchesSearch = !searchText || n.content.toLowerCase().includes(searchText.toLowerCase());
      const matchesProduction = !filterProductionId || n.production_id === filterProductionId;
      const matchesAuthor = !filterAuthorId || n.created_by_user_id === filterAuthorId;
      return matchesSearch && matchesProduction && matchesAuthor;
    });
  }, [notes, searchText, filterProductionId, filterAuthorId]);

  const productionOptions = useMemo(() => {
    return productions.map(p => ({ label: p.title, value: p.id }));
  }, [productions]);

  const userOptions = useMemo(() => {
    return users.map(u => ({ label: `${u.first_name} ${u.last_name}`, value: u.id }));
  }, [users]);

  const handleSearchChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
    setSearchText(e.target.value);
  }, []);

  const handleFilterProductionChange = useCallback((value: string) => {
    setFilterProductionId(value || '');
  }, []);

  const handleFilterAuthorChange = useCallback((value: string) => {
    setFilterAuthorId(value || '');
  }, []);

  const openAddNoteModal = useCallback(() => {
    setAddNoteModalVisible(true);
  }, []);

  const closeAddNoteModal = useCallback(() => {
    setAddNoteModalVisible(false);
    form.resetFields();
  }, [form]);

  const openDetailDrawer = useCallback(() => {
    setDetailDrawerVisible(true);
    setEditMode(false);
  }, []);

  const closeDetailDrawer = useCallback(() => {
    setDetailDrawerVisible(false);
    setSelectedNote(null);
    setEditMode(false);
    editForm.resetFields();
  }, [editForm]);

  const enableEditMode = useCallback(() => {
    setEditMode(true);
    if (selectedNote) {
      editForm.setFieldsValue({
        content: selectedNote.content,
        production_id: selectedNote.production_id,
        is_private: selectedNote.is_private
      });
    }
  }, [selectedNote, editForm]);

  const handleCreateNote = useCallback(async () => {
    try {
      const values = await form.validateFields();
      const payload = {
        created_by_user_id: currentUser?.id || '',
        production_id: values.production_id || null,
        content: values.content,
        is_private: values.is_private || false
      };
      await NotesService.create(payload);
      messageApi.success('Note created successfully');
      setAddNoteModalVisible(false);
      form.resetFields();
      void fetchNotes({ limit: 100 });
    } catch (e) {
      const { message: errorMessage } = parseError(e);
      messageApi.error(errorMessage);
    }
  }, [form, currentUser, messageApi, fetchNotes]);

  const handleRowClick = useCallback(async (record: Note) => {
    try {
      setSelectedNote(record);
      setDetailDrawerVisible(true);
      setEditMode(false);
      const response = await NotesService.getDetails(record.id);
      setSelectedNote(response.data as NoteDetail);
    } catch (e) {
      const { message: errorMessage } = parseError(e);
      messageApi.error(errorMessage);
    }
  }, [messageApi]);

  const handleUpdateNote = useCallback(async () => {
    if (!selectedNote) return;
    try {
      const values = await editForm.validateFields();
      const payload = {
        content: values.content,
        production_id: values.production_id || null,
        is_private: values.is_private
      };
      const response = await NotesService.update(selectedNote.id, payload);
      messageApi.success('Note updated successfully');
      setEditMode(false);
      setSelectedNote(response.data as NoteDetail);
      void fetchNotes({ limit: 100 });
    } catch (e) {
      const { message: errorMessage } = parseError(e);
      messageApi.error(errorMessage);
    }
  }, [selectedNote, editForm, messageApi, fetchNotes]);

  const handleDeleteNote = useCallback(() => {
    if (!selectedNote) return;
    Modal.confirm({
      title: 'Delete Note',
      content: 'Are you sure you want to delete this note?',
      okText: 'Delete',
      okType: 'danger',
      cancelText: 'Cancel',
      onOk: async () => {
        try {
          await NotesService.delete(selectedNote.id);
          messageApi.success('Note deleted successfully');
          setDetailDrawerVisible(false);
          setSelectedNote(null);
          void fetchNotes({ limit: 100 });
        } catch (e) {
          const { message: errorMessage } = parseError(e);
          messageApi.error(errorMessage);
        }
      }
    });
  }, [selectedNote, messageApi, fetchNotes]);

  const handleNavigateToProduction = useCallback(() => {
    if (selectedNote?.production_id) {
      navigate(ROUTES.PRODUCTION_DETAIL.replace(':productionId', selectedNote.production_id));
    }
  }, [selectedNote, navigate]);

  const columns = useMemo(() => [
    {
      title: 'Content',
      dataIndex: 'content',
      key: 'content',
      ellipsis: true,
      width: '40%',
      render: (text: string) => text.length > 100 ? `${text.substring(0, 100)}...` : text
    },
    {
      title: 'Author',
      dataIndex: 'created_by_user_id',
      key: 'author',
      render: (userId: string) => {
        const u = users.find(user => user.id === userId);
        return u ? `${u.first_name} ${u.last_name}` : '-';
      }
    },
    {
      title: 'Production',
      dataIndex: 'production_id',
      key: 'production',
      render: (prodId: string | null) => {
        if (!prodId) return '-';
        const p = productions.find(prod => prod.id === prodId);
        return p ? p.title : '-';
      }
    },
    {
      title: 'Created',
      dataIndex: 'created_at',
      key: 'created_at',
      render: (date: string) => new Date(date).toLocaleDateString()
    },
    {
      title: 'Private',
      dataIndex: 'is_private',
      key: 'is_private',
      render: (val: boolean) => val ? 'Yes' : 'No'
    }
  ], [users, productions]);

  const descriptionsItems = useMemo(() => {
    if (!selectedNote) return [];
    return [
      {
        label: 'Author',
        children: selectedNote.created_by_user_first_name && selectedNote.created_by_user_last_name
          ? `${selectedNote.created_by_user_first_name} ${selectedNote.created_by_user_last_name}`
          : '-'
      },
      {
        label: 'Production',
        children: selectedNote.production_title || 'N/A'
      },
      {
        label: 'Created',
        children: selectedNote.created_at ? new Date(selectedNote.created_at).toLocaleString() : ''
      },
      {
        label: 'Updated',
        children: selectedNote.updated_at ? new Date(selectedNote.updated_at).toLocaleString() : ''
      },
      {
        label: 'Private',
        children: selectedNote.is_private ? 'Yes' : 'No'
      }
    ];
  }, [selectedNote]);

  return (
    <Layout style={{ minHeight: '100vh', height: '100%', width: '100%', display: 'flex', flexDirection: 'column', background: '#f5f5f5' }}>
      {contextHolder}
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '24px 24px 0 24px' }}>
        <Typography.Title level={2} style={{ margin: 0 }}>Notes</Typography.Title>
        <Button type="primary" icon={<PlusOutlined />} onClick={openAddNoteModal}>
          Add Note
        </Button>
      </div>
      <div style={{ display: 'flex', gap: '16px', padding: '16px 24px', flexWrap: 'wrap', alignItems: 'center' }}>
        <Input.Search
          placeholder="Search by content..."
          allowClear
          value={searchText}
          onChange={handleSearchChange}
          style={{ width: '280px' }}
        />
        <Select
          placeholder="All Productions"
          allowClear
          value={filterProductionId || undefined}
          onChange={handleFilterProductionChange}
          options={productionOptions}
          style={{ width: '220px' }}
        />
        <Select
          placeholder="All Authors"
          allowClear
          value={filterAuthorId || undefined}
          onChange={handleFilterAuthorChange}
          options={userOptions}
          style={{ width: '220px' }}
        />
      </div>
      <div style={{ padding: '0 24px 24px 24px' }}>
        <Table
          dataSource={filteredNotes}
          columns={columns}
          rowKey="id"
          pagination={{ pageSize: 20 }}
          loading={loading}
          onRow={(record) => ({
            onClick: () => handleRowClick(record),
            style: { cursor: 'pointer' }
          })}
        />
      </div>
      <Modal
        title="Add Note"
        open={addNoteModalVisible}
        onOk={handleCreateNote}
        onCancel={closeAddNoteModal}
        okText="Save"
        cancelText="Cancel"
        destroyOnClose
      >
        <Form form={form} layout="vertical">
          <Form.Item
            name="content"
            label="Content"
            rules={[{ required: true, message: 'Note content is required' }]}
          >
            <Input.TextArea rows={6} placeholder="Write your note here..." />
          </Form.Item>
          <Form.Item name="production_id" label="Production">
            <Select
              placeholder="Select production (optional)"
              allowClear
              options={productionOptions}
            />
          </Form.Item>
          <Form.Item name="is_private" label="Private Note" valuePropName="checked">
            <Switch />
          </Form.Item>
        </Form>
      </Modal>
      <Drawer
        title="Note Details"
        width={520}
        open={detailDrawerVisible}
        onClose={closeDetailDrawer}
        destroyOnClose
      >
        <div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
          {!editMode ? (
            <>
              <Descriptions column={1} size="small" bordered items={descriptionsItems} />
              <Typography.Paragraph
                style={{
                  whiteSpace: 'pre-wrap',
                  padding: '16px',
                  background: '#fafafa',
                  borderRadius: '8px'
                }}
              >
                {selectedNote?.content}
              </Typography.Paragraph>
              <Space style={{ marginTop: '16px' }}>
                <Button type="primary" icon={<EditOutlined />} onClick={enableEditMode}>
                  Edit
                </Button>
                <Button danger icon={<DeleteOutlined />} onClick={handleDeleteNote}>
                  Delete
                </Button>
                <Button
                  type="link"
                  disabled={!selectedNote?.production_id}
                  onClick={handleNavigateToProduction}
                >
                  View Production
                </Button>
              </Space>
            </>
          ) : (
            <Form form={editForm} layout="vertical">
              <Form.Item
                name="content"
                label="Content"
                rules={[{ required: true, message: 'Note content is required' }]}
              >
                <Input.TextArea rows={6} placeholder="Write your note here..." />
              </Form.Item>
              <Form.Item name="production_id" label="Production">
                <Select
                  placeholder="Select production (optional)"
                  allowClear
                  options={productionOptions}
                />
              </Form.Item>
              <Form.Item name="is_private" label="Private Note" valuePropName="checked">
                <Switch />
              </Form.Item>
              <Space>
                <Button type="primary" onClick={handleUpdateNote}>
                  Save
                </Button>
                <Button onClick={() => setEditMode(false)}>
                  Cancel
                </Button>
              </Space>
            </Form>
          )}
        </div>
      </Drawer>
    </Layout>
  );
};

export default NotesListPage;