import { useState, useMemo, useEffect, useCallback, CSSProperties } from 'react';
import { Table, Button, Input, Modal, Form, Typography, Space, message } from 'antd';
import { ArrowLeftOutlined, PlusOutlined, EditOutlined, StopOutlined } from '@ant-design/icons';
import { request } from '../api/client';
import { useNavigate } from 'react-router-dom';

interface LibraryBranch {
  id: string;
  name: string;
  address: string;
  phone: string | null;
  email: string | null;
  operating_hours: string | null;
  created_at: string;
  updated_at: string;
}

interface Librarian {
  id: string;
  user_id: string;
  employee_id: string;
  hire_date: string;
  library_branch_id: string | null;
  created_at: string;
  updated_at: string;
}

interface LibraryBranchCreate {
  name?: string;
  address?: string;
  phone?: string | null;
  email?: string | null;
  operating_hours?: string | null;
}

interface LibraryBranchUpdate {
  name?: string | null;
  address?: string | null;
  phone?: string | null;
  email?: string | null;
  operating_hours?: string | null;
}

interface LibrarianUpdate {
  user_id?: string | null;
  employee_id?: string | null;
  hire_date?: string | null;
  library_branch_id?: string | null;
}

export default function BranchManagementPage() {
  const [messageApi, contextHolder] = message.useMessage();
  const navigate = useNavigate();
  const [form] = Form.useForm();

  const [branches, setBranches] = useState<LibraryBranch[]>([]);
  const [librarians, setLibrarians] = useState<Librarian[]>([]);
  const [branchModalVisible, setBranchModalVisible] = useState<boolean>(false);
  const [editingBranch, setEditingBranch] = useState<LibraryBranch | null>(null);
  const [expandedRowKeys, setExpandedRowKeys] = useState<string[]>([]);
  const [searchText, setSearchText] = useState<string>('');
  const [loading, setLoading] = useState<boolean>(false);
  const [submitting, setSubmitting] = useState<boolean>(false);

  const filteredBranches = useMemo(() => {
    return branches.filter(b => 
      !searchText || 
      b.name.toLowerCase().includes(searchText.toLowerCase()) || 
      b.address.toLowerCase().includes(searchText.toLowerCase())
    );
  }, [branches, searchText]);

  const fetchBranches = useCallback(async () => {
    setLoading(true);
    try {
      const result = await request<LibraryBranch[]>({
        method: 'GET',
        path: '/library-branches/',
        query: {
          limit: 100,
          offset: 0,
          search: searchText
        }
      });
      setBranches(result.data);
    } catch (error) {
      messageApi.error('Failed to load branches');
    } finally {
      setLoading(false);
    }
  }, [searchText, messageApi]);

  const fetchLibrarians = useCallback(async () => {
    try {
      const result = await request<Librarian[]>({
        method: 'GET',
        path: '/auth/librarians',
        query: {
          limit: 100,
          offset: 0
        }
      });
      setLibrarians(result.data);
    } catch (error) {
      messageApi.error('Failed to load librarians');
    }
  }, [messageApi]);

  useEffect(() => {
    fetchBranches();
  }, [fetchBranches]);

  useEffect(() => {
    fetchLibrarians();
  }, [fetchLibrarians]);

  const openAddBranchModal = useCallback(() => {
    setBranchModalVisible(true);
    setEditingBranch(null);
    form.resetFields();
  }, [form]);

  const openEditBranchModal = useCallback((record: LibraryBranch) => {
    setBranchModalVisible(true);
    setEditingBranch(record);
    form.setFieldsValue(record);
  }, [form]);

  const handleModalCancel = useCallback(() => {
    setBranchModalVisible(false);
    setEditingBranch(null);
    form.resetFields();
  }, [form]);

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

      if (editingBranch) {
        const updateBody: LibraryBranchUpdate = {
          name: values.name,
          address: values.address,
          phone: values.phone || null,
          email: values.email || null,
          operating_hours: values.operating_hours || null
        };

        await request<LibraryBranch>({
          method: 'PATCH',
          path: '/library-branches/{branch_id}',
          pathParams: { branch_id: editingBranch.id },
          body: updateBody
        });

        messageApi.success('Branch updated successfully!');
      } else {
        const createBody: LibraryBranchCreate = {
          name: values.name,
          address: values.address,
          phone: values.phone || null,
          email: values.email || null,
          operating_hours: values.operating_hours || null
        };

        await request<LibraryBranch>({
          method: 'POST',
          path: '/library-branches/',
          body: createBody
        });

        messageApi.success('Branch saved successfully!');
      }

      setBranchModalVisible(false);
      setEditingBranch(null);
      form.resetFields();
      fetchBranches();
    } catch (error) {
      if (error instanceof Error && 'errorFields' in error) {
        return;
      }
      messageApi.error(editingBranch ? 'Failed to update branch. Please try again.' : 'Failed to save branch. Please try again.');
    } finally {
      setSubmitting(false);
    }
  }, [form, editingBranch, messageApi, fetchBranches]);

  const deactivateBranch = useCallback((record: LibraryBranch) => {
    Modal.confirm({
      title: 'Deactivate Branch',
      content: 'Are you sure you want to deactivate this branch?',
      okText: 'Yes',
      cancelText: 'No',
      onOk: async () => {
        setLoading(true);
        try {
          await request({
            method: 'DELETE',
            path: '/library-branches/{branch_id}',
            pathParams: { branch_id: record.id }
          });
          messageApi.success('Branch deactivated successfully!');
          fetchBranches();
        } catch (error) {
          messageApi.error('Failed to deactivate branch.');
        } finally {
          setLoading(false);
        }
      }
    });
  }, [messageApi, fetchBranches]);

  const reassignLibrarian = useCallback((librarianId: string, newBranchId: string) => {
    Modal.confirm({
      title: 'Reassign Librarian',
      content: 'Are you sure you want to reassign this librarian?',
      okText: 'Yes',
      cancelText: 'No',
      onOk: async () => {
        try {
          const updateBody: LibrarianUpdate = {
            library_branch_id: newBranchId
          };

          await request<Librarian>({
            method: 'PUT',
            path: '/auth/librarians/{librarian_id}',
            pathParams: { librarian_id: librarianId },
            body: updateBody
          });

          messageApi.success('Librarian reassigned successfully!');
          fetchLibrarians();
        } catch (error) {
          messageApi.error('Failed to reassign librarian.');
        }
      }
    });
  }, [messageApi, fetchLibrarians]);

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

  const columns = useMemo(() => [
    {
      title: 'Branch Name',
      dataIndex: 'name',
      key: 'name',
      sorter: (a: LibraryBranch, b: LibraryBranch) => a.name.localeCompare(b.name)
    },
    {
      title: 'Address',
      dataIndex: 'address',
      key: 'address'
    },
    {
      title: 'Phone',
      dataIndex: 'phone',
      key: 'phone'
    },
    {
      title: 'Email',
      dataIndex: 'email',
      key: 'email'
    },
    {
      title: 'Operating Hours',
      dataIndex: 'operating_hours',
      key: 'operating_hours'
    },
    {
      title: 'Actions',
      key: 'actions',
      render: (_: unknown, record: LibraryBranch) => (
        <Space size="small">
          <Button
            type="link"
            icon={<EditOutlined />}
            size="small"
            onClick={() => openEditBranchModal(record)}
          >
            Edit
          </Button>
          <Button
            type="link"
            danger
            icon={<StopOutlined />}
            size="small"
            onClick={() => deactivateBranch(record)}
          >
            Deactivate
          </Button>
        </Space>
      )
    }
  ], [openEditBranchModal, deactivateBranch]);

  const librarianColumns = useMemo(() => [
    {
      title: 'Employee ID',
      dataIndex: 'employee_id',
      key: 'employee_id'
    },
    {
      title: 'Hire Date',
      dataIndex: 'hire_date',
      key: 'hire_date'
    },
    {
      title: 'Actions',
      key: 'actions',
      render: (_: unknown, record: Librarian) => (
        <Button
          type="link"
          size="small"
          onClick={() => reassignLibrarian(record.id, '')}
        >
          Reassign
        </Button>
      )
    }
  ], [reassignLibrarian]);

  const expandedRowRender = useCallback((record: LibraryBranch) => {
    const branchLibrarians = librarians.filter(l => l.library_branch_id === record.id);

    return (
      <div style={{ padding: '16px', background: '#fafafa', borderRadius: '4px' }}>
        <Typography.Text strong style={{ marginBottom: '12px', display: 'block' }}>
          Assigned Librarians
        </Typography.Text>
        <Table
          columns={librarianColumns}
          dataSource={branchLibrarians}
          rowKey="id"
          size="small"
          pagination={false}
        />
      </div>
    );
  }, [librarians, librarianColumns]);

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

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

  const headerLeftStyle: CSSProperties = {
    display: 'flex',
    alignItems: 'center',
    gap: '16px'
  };

  const headerActionsStyle: CSSProperties = {
    display: 'flex',
    gap: '12px',
    alignItems: 'center'
  };

  const tableStyle: CSSProperties = {
    background: '#fff',
    borderRadius: '6px'
  };

  return (
    <div style={mainContainerStyle}>
      {contextHolder}
      <div style={pageHeaderStyle}>
        <div style={headerLeftStyle}>
          <Button
            type="text"
            icon={<ArrowLeftOutlined />}
            onClick={navigateToAdmin}
          >
            Back
          </Button>
          <Typography.Title level={3} style={{ margin: 0 }}>
            Branch Management
          </Typography.Title>
        </div>
        <div style={headerActionsStyle}>
          <Input.Search
            placeholder="Search by name or address..."
            allowClear
            value={searchText}
            onChange={(e) => setSearchText(e.target.value)}
            style={{ width: '280px' }}
          />
          <Button
            type="primary"
            icon={<PlusOutlined />}
            onClick={openAddBranchModal}
          >
            Add Branch
          </Button>
        </div>
      </div>

      <Table
        columns={columns}
        dataSource={filteredBranches}
        rowKey="id"
        loading={loading}
        pagination={{ pageSize: 10 }}
        expandable={{
          expandedRowRender,
          expandedRowKeys,
          onExpandedRowsChange: (keys) => setExpandedRowKeys(keys as string[])
        }}
        style={tableStyle}
      />

      <Modal
        title={editingBranch ? 'Edit Branch' : 'Add Branch'}
        open={branchModalVisible}
        onCancel={handleModalCancel}
        onOk={handleFormSubmit}
        width={640}
        destroyOnClose
        okText="Save"
        cancelText="Cancel"
        confirmLoading={submitting}
      >
        <Form
          form={form}
          layout="vertical"
          initialValues={editingBranch || undefined}
        >
          <Form.Item
            label="Branch Name"
            name="name"
            rules={[{ required: true, message: 'Branch name is required' }]}
          >
            <Input placeholder="Enter branch name" />
          </Form.Item>

          <Form.Item
            label="Address"
            name="address"
            rules={[{ required: true, message: 'Address is required' }]}
          >
            <Input.TextArea placeholder="Street, City, State, ZIP" rows={3} />
          </Form.Item>

          <Form.Item label="Phone" name="phone">
            <Input placeholder="Enter phone number" />
          </Form.Item>

          <Form.Item
            label="Email"
            name="email"
            rules={[{ type: 'email', message: 'Please enter a valid email' }]}
          >
            <Input placeholder="Enter email address" />
          </Form.Item>

          <Form.Item label="Operating Hours" name="operating_hours">
            <Input.TextArea
              placeholder="e.g., Mon-Fri: 9AM-8PM, Sat: 10AM-6PM, Sun: Closed"
              rows={4}
            />
          </Form.Item>
        </Form>
      </Modal>
    </div>
  );
}