import { useCallback, useEffect, useMemo, useState } from 'react'
import { Link, useNavigate, useParams } from 'react-router-dom'
import { useApolloClient, useQuery } from '@apollo/client/react'
import { Building2, Pencil, Trash2 } from 'lucide-react'

import {
  GET_ORGANISATION_QUERY,
  GET_USERS_PAGE_QUERY,
} from '../../entities/employee/api/employee.graphql'
import type {
  Employee,
  GetOrganisationData,
  GetOrganisationVariables,
  GetUsersPageData,
  GetUsersPageVariables,
  Organisation,
} from '../../entities/employee/model/types'
import { ConfirmDangerDialog } from '../../widgets/ConfirmDangerDialog/ConfirmDangerDialog'
import { AddOrganisationModal } from '../EmployeesPage/components/AddOrganisationModal/AddOrganisationModal'
import { OrganisationPolicyCard } from './components/OrganisationPolicyCard/OrganisationPolicyCard'

import './OrganisationPage.scss'

type LoadStatus = 'idle' | 'loading' | 'success' | 'error'

function getEmployeeFullName(employee: Employee) {
  return [employee.lastName, employee.firstName, employee.middleName]
    .filter(Boolean)
    .join(' ')
}

function getEmployeeRoleLabel(role: string) {
  if (role === 'Admin') return 'Администратор'
  if (role === 'User') return 'Пользователь'

  return role
}

function getOrganisationInitials(name: string) {
  const words = name.trim().split(/\s+/).filter(Boolean)

  if (words.length === 0) return 'ОР'

  return words
    .slice(0, 2)
    .map((word) => word[0])
    .join('')
    .toUpperCase()
}

function formatCreationDate(timestamp: number) {
  if (!timestamp) return 'Нет данных'

  return new Intl.DateTimeFormat('ru-RU', {
    day: '2-digit',
    month: '2-digit',
    year: 'numeric',
    hour: '2-digit',
    minute: '2-digit',
  }).format(new Date(timestamp))
}

export function OrganisationPage() {
  const client = useApolloClient()
  const navigate = useNavigate()
  const { organisationId } = useParams()

  const [employees, setEmployees] = useState<Employee[]>([])
  const [employeesStatus, setEmployeesStatus] = useState<LoadStatus>('idle')
  const [editingOrganisation, setEditingOrganisation] =
    useState<Organisation | null>(null)
  const [deletingOrganisation, setDeletingOrganisation] =
    useState<Organisation | null>(null)

  const {
    data: organisationData,
    loading: organisationLoading,
    error: organisationError,
  } = useQuery<GetOrganisationData, GetOrganisationVariables>(
    GET_ORGANISATION_QUERY,
    {
      variables: {
        id: organisationId ?? '',
      },
      skip: !organisationId,
      fetchPolicy: 'network-only',
    },
  )

  const organisation = organisationData?.getOrganisation ?? null

  const organisationInitials = useMemo(() => {
    if (!organisation) return 'ОР'

    return getOrganisationInitials(organisation.name)
  }, [organisation])

  const loadEmployees = useCallback(async () => {
    if (!organisationId) {
      setEmployeesStatus('error')
      return
    }

    setEmployeesStatus('loading')

    try {
      let nextKey: string | null = null
      let pageCounter = 0
      const allEmployees: Employee[] = []

      do {
        const result = await client.query<
          GetUsersPageData,
          GetUsersPageVariables
        >({
          query: GET_USERS_PAGE_QUERY,
          variables: nextKey ? { key: nextKey } : {},
          fetchPolicy: 'network-only',
        })

        const pageData = result.data?.getUsersPage

        if (!pageData) break

        allEmployees.push(
          ...pageData.page.filter(
            (employee) => String(employee.orgId) === organisationId,
          ),
        )

        nextKey = pageData.nextKey
        pageCounter += 1
      } while (nextKey && pageCounter < 50)

      setEmployees(allEmployees)
      setEmployeesStatus('success')
    } catch {
      setEmployeesStatus('error')
    }
  }, [client, organisationId])

  useEffect(() => {
    void loadEmployees()
  }, [loadEmployees])

  function handleConfirmDeleteOrganisation() {
    if (!deletingOrganisation) return

    console.log('Удаление организации пока без мутации', deletingOrganisation)

    setDeletingOrganisation(null)
    navigate('/employees')
  }

  if (!organisationId) {
    return (
      <section className="organisation-page">
        <div className="organisation-page__empty">
          <h2>Некорректный ID организации</h2>
          <Link to="/employees">Вернуться к списку</Link>
        </div>
      </section>
    )
  }

  return (
    <section className="organisation-page">
      <div className="organisation-breadcrumbs">
        <Link to="/employees">Сотрудники</Link>
        <span>/</span>
        <span>{organisation?.name ?? 'Организация'}</span>
      </div>

      {organisationLoading && !organisation && (
        <div className="organisation-page__empty">Загрузка организации...</div>
      )}

      {organisationError && (
        <div className="organisation-page__empty organisation-page__empty--error">
          Не удалось загрузить организацию
        </div>
      )}

      {!organisationLoading && !organisationError && !organisation && (
        <div className="organisation-page__empty">
          <h2>Организация не найдена</h2>
          <Link to="/employees">Вернуться к списку</Link>
        </div>
      )}

      {organisation && (
        <>
          <div className="organisation-page__top">
            <div>
              <div className="organisation-card">
                <div className="organisation-card__main">
                  <div className="organisation-card__avatar" aria-hidden="true">
                    {organisationInitials}
                  </div>

                  <div className="organisation-card__info">
                    <h2>
                      {organisation.name}
                      <span>ID: {organisation.id}</span>
                    </h2>
                    <p>Создана {formatCreationDate(organisation.creationDate)}</p>
                    <div className="organisation-card__actions">
                      <button
                        className="organisation-action-btn organisation-action-btn--edit"
                        type="button"
                        onClick={() => setEditingOrganisation(organisation)}
                      >
                        <Pencil size={16} />
                        Редактировать
                      </button>

                      <button
                        className="organisation-action-btn organisation-action-btn--delete"
                        type="button"
                        onClick={() => setDeletingOrganisation(organisation)}
                      >
                        <Trash2 size={16} />
                        Удалить
                      </button>
                    </div>
                  </div>
                </div>
              </div>

              <OrganisationPolicyCard organisation={organisation} />
            </div>
            <div className="organisation-employees-card">

              <div className="organisation-employees-table-card">
                {employeesStatus === 'loading' && employees.length === 0 && (
                  <div className="organisation-page__state">
                    Загрузка сотрудников...
                  </div>
                )}

                {employeesStatus === 'error' && (
                  <div className="organisation-page__state organisation-page__state--error">
                    Не удалось загрузить сотрудников
                  </div>
                )}

                {employeesStatus === 'success' && employees.length === 0 && (
                  <div className="organisation-page__state">
                    В этой организации пока нет сотрудников
                  </div>
                )}

                {employees.length > 0 && (
                  <table className="organisation-employees-table">
                    <thead>
                      <tr>
                        <th>ID</th>
                        <th>ФИО</th>
                        <th>Организация</th>
                        <th>Роль</th>
                      </tr>
                    </thead>

                    <tbody>
                      {employees.map((employee) => (
                        <tr key={employee.id}>
                          <td>{employee.id}</td>

                          <td>
                            <div className="organisation-employee-person">
                              <span>
                                {getEmployeeFullName(employee) || 'ФИО не указано'}
                              </span>
                            </div>
                          </td>

                          <td>
                            <span className="organisation-employee-org">
                              {employee.org?.name || organisation.name}
                            </span>
                          </td>

                          <td>
                            <span
                              className={
                                employee.role === 'Admin'
                                  ? 'organisation-employee-role organisation-employee-role--admin'
                                  : 'organisation-employee-role'
                              }
                            >
                              {getEmployeeRoleLabel(employee.role)}
                            </span>
                          </td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                )}
              </div>
            </div>

          </div>



          <AddOrganisationModal
            open={Boolean(editingOrganisation)}
            mode="edit"
            organisation={editingOrganisation}
            onOpenChange={(open) => {
              if (!open) {
                setEditingOrganisation(null)
              }
            }}
          />

          <ConfirmDangerDialog
            open={Boolean(deletingOrganisation)}
            title="Удалить организацию?"
            description={
              deletingOrganisation
                ? `Организация «${deletingOrganisation.name}» будет удалена из системы. Это действие нельзя будет отменить.`
                : ''
            }
            confirmText="Удалить"
            onOpenChange={(open) => {
              if (!open) {
                setDeletingOrganisation(null)
              }
            }}
            onConfirm={handleConfirmDeleteOrganisation}
          />
        </>
      )}
    </section>
  )
}