import { useState, useEffect, useCallback, useMemo } from 'react';
import { Table, Button, Modal, Form, Input, Select, Typography, Space, message, Grid } from 'antd';
import { PlusOutlined, EditOutlined, DeleteOutlined, UserAddOutlined, ArrowLeftOutlined } from '@ant-design/icons';
import { useNavigate } from 'react-router-dom';
import { useApi } from '@/hooks/useApi';
import { OrganizationService } from '@/services/organization';
import { UsersService } from '@/services/users';
import { parseError } from '@/utils/errorHandler';
import { ROUTES } from '@/constants/routes';

const { Title, Text } = Typography;
const { useBreakpoint } = Grid;

interface Department {
  id: string;
  name: string;
  description?: string | null;
  created_at: string;
  updated_at: string;
}

interface Team {
  id: string;
  name: string;
  description?: string | null;
  department_id: string;
  created_at: string;
  updated_at: string;
}

interface UserTeam {
  id: string;
  user_id: string;
  team_id: string;
  created_at: string;
  updated_at: string;
}

interface User {
  id: string;
  email: string;
  first_name: string;
  last_name: string;
  role: string;
  department_id?: string | null;
  phone?: string | null;
  is_active: boolean;
  created_at: string;
  updated_at: string;
}

interface DepartmentListResponse {
  items: Department[];
  total: number;
  limit: number;
  offset: number;
}

interface TeamListResponse {
  items: Team[];
  total: number;
  limit: number;
  offset: number;
}

interface UserTeamListResponse {
  items: UserTeam[];
  total: number;
  limit: number;
  offset: number;
}

interface UserListResponse {
  items: User[];
  total: number;
  limit: number;
  offset: number;
}

const DepartmentsPage = () => {
  const [messageApi, contextHolder] = message.useMessage();
  const navigate = useNavigate();
  const screens = useBreakpoint();

  const [departments, setDepartments] = useState<Department[]>([]);
  const [selectedDepartmentId, setSelectedDepartmentId] = useState<string | null>(null);
  const [teams, setTeams] = useState<Team[]>([]);
  const [teamMembers, setTeamMembers] = useState<UserTeam[]>([]);
  const [users, setUsers] = useState<User[]>([]);
  const [expandedTeamId, setExpandedTeamId] = useState<string | null>(null);

  const [createDepartmentModalVisible, setCreateDepartmentModalVisible] = useState(false);
  const [editDepartmentModalVisible, setEditDepartmentModalVisible] = useState(false);
  const [editingDepartment, setEditingDepartment] = useState<Department | null>(null);

  const [createTeamModalVisible, setCreateTeamModalVisible] = useState(false);
  const [editTeamModalVisible, setEditTeamModalVisible] = useState(false);
  const [editingTeam, setEditingTeam] = useState<Team | null>(null);

  const [addMemberModalVisible, setAddMemberModalVisible] = useState(false);
  const [selectedMembershipId, setSelectedMembershipId] = useState<string | null>(null);

  const [createDepartmentForm] = Form.useForm();
  const [editDepartmentForm] = Form.useForm();
  const [createTeamForm] = Form.useForm();
  const [editTeamForm] = Form.useForm();
  const [addMemberForm] = Form.useForm();

  const { data: departmentsData, loading: departmentsLoading, error: departmentsError, execute: fetchDepartments } = useApi<DepartmentListResponse>(OrganizationService.getDepartments);
  const { data: teamsData, loading: teamsLoading, error: teamsError, execute: fetchTeams } = useApi<TeamListResponse>(OrganizationService.getTeams);
  const { data: teamMembersData, loading: teamMembersLoading, error: teamMembersError, execute: fetchTeamMembers } = useApi<UserTeamListResponse>(OrganizationService.getUserTeams);
  const { data: usersData, loading: usersLoading, error: usersError, execute: fetchUsers } = useApi<UserListResponse>(UsersService.list);

  useEffect(() => {
    void fetchDepartments({ limit: 50, offset: 0 });
  }, [fetchDepartments]);

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

  useEffect(() => {
    if (selectedDepartmentId) {
      void fetchTeams({ limit: 50, offset: 0, department_id: selectedDepartmentId });
    }
  }, [selectedDepartmentId, fetchTeams]);

  useEffect(() => {
    if (expandedTeamId) {
      void fetchTeamMembers({ limit: 50, offset: 0, team_id: expandedTeamId });
    }
  }, [expandedTeamId, fetchTeamMembers]);

  useEffect(() => {
    if (departmentsData) {
      setDepartments(departmentsData.items ?? []);
    }
  }, [departmentsData]);

  useEffect(() => {
    if (teamsData) {
      setTeams(teamsData.items ?? []);
    }
  }, [teamsData]);

  useEffect(() => {
    if (teamMembersData) {
      setTeamMembers(teamMembersData.items ?? []);
    }
  }, [teamMembersData]);

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

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

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

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

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

  const handleOpenCreateDepartmentModal = useCallback(() => {
    setCreateDepartmentModalVisible(true);
  }, []);

  const handleCloseCreateDepartmentModal = useCallback(() => {
    setCreateDepartmentModalVisible(false);
    createDepartmentForm.resetFields();
  }, [createDepartmentForm]);

  const handleOpenEditDepartmentModal = useCallback((record: Department) => {
    setEditingDepartment(record);
    setEditDepartmentModalVisible(true);
    editDepartmentForm.setFieldsValue({
      name: record.name,
      description: record.description
    });
  }, [editDepartmentForm]);

  const handleCloseEditDepartmentModal = useCallback(() => {
    setEditDepartmentModalVisible(false);
    setEditingDepartment(null);
    editDepartmentForm.resetFields();
  }, [editDepartmentForm]);

  const handleSelectDepartment = useCallback((departmentId: string) => {
    setSelectedDepartmentId(departmentId);
  }, []);

  const handleOpenCreateTeamModal = useCallback(() => {
    setCreateTeamModalVisible(true);
  }, []);

  const handleCloseCreateTeamModal = useCallback(() => {
    setCreateTeamModalVisible(false);
    createTeamForm.resetFields();
  }, [createTeamForm]);

  const handleOpenEditTeamModal = useCallback((record: Team) => {
    setEditingTeam(record);
    setEditTeamModalVisible(true);
    editTeamForm.setFieldsValue({
      name: record.name,
      description: record.description,
      department_id: record.department_id
    });
  }, [editTeamForm]);

  const handleCloseEditTeamModal = useCallback(() => {
    setEditTeamModalVisible(false);
    setEditingTeam(null);
    editTeamForm.resetFields();
  }, [editTeamForm]);

  const handleExpandTeamMembers = useCallback((teamId: string) => {
    setExpandedTeamId(teamId);
  }, []);

  const handleOpenAddMemberModal = useCallback(() => {
    setAddMemberModalVisible(true);
  }, []);

  const handleCloseAddMemberModal = useCallback(() => {
    setAddMemberModalVisible(false);
    addMemberForm.resetFields();
  }, [addMemberForm]);

  const handleCreateDepartment = useCallback(async () => {
    try {
      const values = await createDepartmentForm.validateFields();
      await OrganizationService.createDepartments({
        name: values.name,
        description: values.description
      });
      messageApi.success('Department created successfully');
      setCreateDepartmentModalVisible(false);
      createDepartmentForm.resetFields();
      void fetchDepartments({ limit: 50, offset: 0 });
    } catch (e) {
      const { message: errorMessage } = parseError(e);
      messageApi.error(errorMessage);
    }
  }, [createDepartmentForm, messageApi, fetchDepartments]);

  const handleUpdateDepartment = useCallback(async () => {
    if (!editingDepartment) return;
    try {
      const values = await editDepartmentForm.validateFields();
      await OrganizationService.updateDepartmentsById(editingDepartment.id, {
        name: values.name,
        description: values.description
      });
      messageApi.success('Department updated successfully');
      setEditDepartmentModalVisible(false);
      setEditingDepartment(null);
      editDepartmentForm.resetFields();
      void fetchDepartments({ limit: 50, offset: 0 });
    } catch (e) {
      const { message: errorMessage } = parseError(e);
      messageApi.error(errorMessage);
    }
  }, [editingDepartment, editDepartmentForm, messageApi, fetchDepartments]);

  const handleDeleteDepartment = useCallback((departmentId: string) => {
    Modal.confirm({
      title: 'Delete Department',
      content: 'Are you sure you want to delete this department?',
      okText: 'Delete',
      okType: 'danger',
      cancelText: 'Cancel',
      onOk: async () => {
        try {
          await OrganizationService.deleteDepartmentsById(departmentId);
          messageApi.success('Department deleted successfully');
          void fetchDepartments({ limit: 50, offset: 0 });
        } catch (e) {
          const { message: errorMessage } = parseError(e);
          messageApi.error(errorMessage);
        }
      }
    });
  }, [messageApi, fetchDepartments]);

  const handleCreateTeam = useCallback(async () => {
    try {
      const values = await createTeamForm.validateFields();
      await OrganizationService.createTeams({
        name: values.name,
        description: values.description,
        department_id: values.department_id
      });
      messageApi.success('Team created successfully');
      setCreateTeamModalVisible(false);
      createTeamForm.resetFields();
      if (selectedDepartmentId) {
        void fetchTeams({ limit: 50, offset: 0, department_id: selectedDepartmentId });
      }
    } catch (e) {
      const { message: errorMessage } = parseError(e);
      messageApi.error(errorMessage);
    }
  }, [createTeamForm, messageApi, selectedDepartmentId, fetchTeams]);

  const handleUpdateTeam = useCallback(async () => {
    if (!editingTeam) return;
    try {
      const values = await editTeamForm.validateFields();
      await OrganizationService.updateTeamsById(editingTeam.id, {
        name: values.name,
        description: values.description,
        department_id: values.department_id
      });
      messageApi.success('Team updated successfully');
      setEditTeamModalVisible(false);
      setEditingTeam(null);
      editTeamForm.resetFields();
      if (selectedDepartmentId) {
        void fetchTeams({ limit: 50, offset: 0, department_id: selectedDepartmentId });
      }
    } catch (e) {
      const { message: errorMessage } = parseError(e);
      messageApi.error(errorMessage);
    }
  }, [editingTeam, editTeamForm, messageApi, selectedDepartmentId, fetchTeams]);

  const handleDeleteTeam = useCallback((teamId: string) => {
    Modal.confirm({
      title: 'Delete Team',
      content: 'Are you sure you want to delete this team?',
      okText: 'Delete',
      okType: 'danger',
      cancelText: 'Cancel',
      onOk: async () => {
        try {
          await OrganizationService.deleteTeamsById(teamId);
          messageApi.success('Team deleted successfully');
          if (selectedDepartmentId) {
            void fetchTeams({ limit: 50, offset: 0, department_id: selectedDepartmentId });
          }
        } catch (e) {
          const { message: errorMessage } = parseError(e);
          messageApi.error(errorMessage);
        }
      }
    });
  }, [messageApi, selectedDepartmentId, fetchTeams]);

  const handleAddMember = useCallback(async () => {
    if (!expandedTeamId) return;
    try {
      const values = await addMemberForm.validateFields();
      await OrganizationService.createUserTeams({
        user_id: values.user_id,
        team_id: expandedTeamId
      });
      messageApi.success('Member added to team successfully');
      setAddMemberModalVisible(false);
      addMemberForm.resetFields();
      void fetchTeamMembers({ limit: 50, offset: 0, team_id: expandedTeamId });
    } catch (e) {
      const { message: errorMessage } = parseError(e);
      messageApi.error(errorMessage);
    }
  }, [expandedTeamId, addMemberForm, messageApi, fetchTeamMembers]);

  const handleRemoveMember = useCallback((membershipId: string) => {
    Modal.confirm({
      title: 'Remove Member',
      content: 'Are you sure you want to remove this member from the team?',
      okText: 'Remove',
      okType: 'danger',
      cancelText: 'Cancel',
      onOk: async () => {
        try {
          await OrganizationService.deleteUserTeamsById(membershipId);
          messageApi.success('Member removed from team');
          if (expandedTeamId) {
            void fetchTeamMembers({ limit: 50, offset: 0, team_id: expandedTeamId });
          }
        } catch (e) {
          const { message: errorMessage } = parseError(e);
          messageApi.error(errorMessage);
        }
      }
    });
  }, [expandedTeamId, messageApi, fetchTeamMembers]);

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

  const departmentOptions = useMemo(() => {
    return (departments ?? []).map(dept => ({
      label: dept.name,
      value: dept.id
    }));
  }, [departments]);

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

  const departmentColumns = useMemo(() => [
    {
      title: 'Name',
      dataIndex: 'name',
      key: 'name'
    },
    {
      title: 'Description',
      dataIndex: 'description',
      key: 'description',
      responsive: ['md' as const]
    },
    {
      title: 'Actions',
      key: 'actions',
      render: (_: unknown, record: Department) => (
        <Space size="small">
          <Button type="link" size="small" onClick={() => handleOpenEditDepartmentModal(record)}>
            Edit
          </Button>
          <Button type="link" danger size="small" onClick={() => handleDeleteDepartment(record.id)}>
            Delete
          </Button>
        </Space>
      )
    }
  ], [handleOpenEditDepartmentModal, handleDeleteDepartment]);

  const teamColumns = useMemo(() => [
    {
      title: 'Team Name',
      dataIndex: 'name',
      key: 'name'
    },
    {
      title: 'Description',
      dataIndex: 'description',
      key: 'description',
      responsive: ['md' as const]
    },
    {
      title: 'Actions',
      key: 'actions',
      render: (_: unknown, record: Team) => (
        <Space size="small">
          <Button type="link" size="small" onClick={() => handleOpenEditTeamModal(record)}>
            Edit
          </Button>
          <Button type="link" danger size="small" onClick={() => handleDeleteTeam(record.id)}>
            Delete
          </Button>
          <Button type="link" size="small" onClick={() => handleExpandTeamMembers(record.id)}>
            View Members
          </Button>
        </Space>
      )
    }
  ], [handleOpenEditTeamModal, handleDeleteTeam, handleExpandTeamMembers]);

  const enrichedTeamMembers = useMemo(() => {
    return (teamMembers ?? []).map(member => {
      const user = (users ?? []).find(u => u.id === member.user_id);
      return {
        ...member,
        name: user ? `${user.first_name ?? ''} ${user.last_name ?? ''}`.trim() : '—',
        email: user?.email ?? '—',
        role: user?.role ?? '—'
      };
    });
  }, [teamMembers, users]);

  const memberColumns = useMemo(() => [
    {
      title: 'Name',
      dataIndex: 'name',
      key: 'name'
    },
    {
      title: 'Role',
      dataIndex: 'role',
      key: 'role',
      responsive: ['md' as const]
    },
    {
      title: 'Email',
      dataIndex: 'email',
      key: 'email',
      responsive: ['lg' as const]
    },
    {
      title: 'Actions',
      key: 'actions',
      render: (_: unknown, record: UserTeam & { name: string; email: string; role: string }) => (
        <Button type="link" danger size="small" onClick={() => handleRemoveMember(record.id)}>
          Remove
        </Button>
      )
    }
  ], [handleRemoveMember]);

  const expandedRowRender = useCallback((record: Team) => {
    if (expandedTeamId !== record.id) return null;

    return (
      <div style={{ padding: '12px 16px', background: '#fafafa', borderRadius: '4px' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '8px' }}>
          <Text strong>Team Members</Text>
          <Button type="dashed" size="small" icon={<UserAddOutlined />} onClick={handleOpenAddMemberModal}>
            Add Member
          </Button>
        </div>
        <Table
          columns={memberColumns}
          dataSource={enrichedTeamMembers}
          rowKey="id"
          loading={teamMembersLoading}
          pagination={false}
          size="small"
          scroll={{ x: 'max-content' }}
        />
      </div>
    );
  }, [expandedTeamId, memberColumns, enrichedTeamMembers, teamMembersLoading, handleOpenAddMemberModal]);

  return (
    <div style={{ minHeight: '100vh', width: '100%', background: '#f5f5f5' }}>
      {contextHolder}
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: screens.xs ? '16px 16px 0 16px' : '24px 24px 0 24px' }}>
        <Button type="text" icon={<ArrowLeftOutlined />} onClick={handleNavigateToDashboard}>
          Back to Dashboard
        </Button>
        <Title level={2} style={{ margin: 0, fontSize: screens.xs ? 18 : 24 }}>
          Departments
        </Title>
        <Button type="primary" icon={<PlusOutlined />} onClick={handleOpenCreateDepartmentModal}>
          Create Department
        </Button>
      </div>

      <div style={{ padding: screens.xs ? 16 : 24 }}>
        <Table
          columns={departmentColumns}
          dataSource={departments}
          rowKey="id"
          loading={departmentsLoading}
          pagination={{ pageSize: 20 }}
          onRow={(record) => ({
            onClick: () => handleSelectDepartment(record.id)
          })}
          style={{ background: '#fff', borderRadius: '6px' }}
          scroll={{ x: 'max-content' }}
          size={screens.xs ? 'small' : 'middle'}
        />
      </div>

      {selectedDepartmentId && (
        <div style={{ padding: screens.xs ? '8px 16px' : '16px 24px' }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '16px' }}>
            <Title level={4} style={{ margin: 0 }}>
              Teams
            </Title>
            <Button type="primary" size="small" icon={<PlusOutlined />} onClick={handleOpenCreateTeamModal}>
              Create Team
            </Button>
          </div>
          <Table
            columns={teamColumns}
            dataSource={teams}
            rowKey="id"
            loading={teamsLoading}
            pagination={{ pageSize: 10 }}
            expandable={{
              expandedRowRender,
              expandedRowKeys: expandedTeamId ? [expandedTeamId] : [],
              onExpand: (expanded, record) => {
                if (expanded) {
                  handleExpandTeamMembers(record.id);
                } else {
                  setExpandedTeamId(null);
                }
              }
            }}
            style={{ background: '#fff', borderRadius: '6px' }}
            size="small"
            scroll={{ x: 'max-content' }}
          />
        </div>
      )}

      <Modal
        title="Create Department"
        open={createDepartmentModalVisible}
        onOk={handleCreateDepartment}
        onCancel={handleCloseCreateDepartmentModal}
        okText="Create"
        cancelText="Cancel"
        destroyOnClose
      >
        <Form form={createDepartmentForm} layout="vertical">
          <Form.Item
            name="name"
            label="Name"
            rules={[{ required: true, message: 'Department name is required' }]}
          >
            <Input placeholder="Enter department name" />
          </Form.Item>
          <Form.Item name="description" label="Description">
            <Input.TextArea placeholder="Enter department description" rows={4} />
          </Form.Item>
        </Form>
      </Modal>

      <Modal
        title="Edit Department"
        open={editDepartmentModalVisible}
        onOk={handleUpdateDepartment}
        onCancel={handleCloseEditDepartmentModal}
        okText="Save"
        cancelText="Cancel"
        destroyOnClose
      >
        <Form form={editDepartmentForm} layout="vertical">
          <Form.Item
            name="name"
            label="Name"
            rules={[{ required: true, message: 'Department name is required' }]}
          >
            <Input placeholder="Enter department name" />
          </Form.Item>
          <Form.Item name="description" label="Description">
            <Input.TextArea placeholder="Enter department description" rows={4} />
          </Form.Item>
        </Form>
      </Modal>

      <Modal
        title="Create Team"
        open={createTeamModalVisible}
        onOk={handleCreateTeam}
        onCancel={handleCloseCreateTeamModal}
        okText="Create"
        cancelText="Cancel"
        destroyOnClose
      >
        <Form form={createTeamForm} layout="vertical">
          <Form.Item
            name="name"
            label="Name"
            rules={[{ required: true, message: 'Team name is required' }]}
          >
            <Input placeholder="Enter team name" />
          </Form.Item>
          <Form.Item name="description" label="Description">
            <Input.TextArea placeholder="Enter team description" rows={3} />
          </Form.Item>
          <Form.Item name="department_id" label="Department">
            <Select
              placeholder="Select department"
              options={departmentOptions}
              style={{ width: '100%' }}
            />
          </Form.Item>
        </Form>
      </Modal>

      <Modal
        title="Edit Team"
        open={editTeamModalVisible}
        onOk={handleUpdateTeam}
        onCancel={handleCloseEditTeamModal}
        okText="Save"
        cancelText="Cancel"
        destroyOnClose
      >
        <Form form={editTeamForm} layout="vertical">
          <Form.Item
            name="name"
            label="Name"
            rules={[{ required: true, message: 'Team name is required' }]}
          >
            <Input placeholder="Enter team name" />
          </Form.Item>
          <Form.Item name="description" label="Description">
            <Input.TextArea placeholder="Enter team description" rows={3} />
          </Form.Item>
          <Form.Item name="department_id" label="Department">
            <Select
              placeholder="Select department"
              options={departmentOptions}
              style={{ width: '100%' }}
            />
          </Form.Item>
        </Form>
      </Modal>

      <Modal
        title="Add Member to Team"
        open={addMemberModalVisible}
        onOk={handleAddMember}
        onCancel={handleCloseAddMemberModal}
        okText="Add"
        cancelText="Cancel"
        destroyOnClose
      >
        <Form form={addMemberForm} layout="vertical">
          <Form.Item
            name="user_id"
            label="Select User"
            rules={[{ required: true, message: 'Please select a user' }]}
          >
            <Select
              placeholder="Search and select user"
              options={userOptions}
              showSearch
              optionFilterProp="label"
              filterOption
              style={{ width: '100%' }}
            />
          </Form.Item>
        </Form>
      </Modal>
    </div>
  );
};

export default DepartmentsPage;