import { useSessionStorageState } from 'ahooks'
import {
  Input,
  Space,
  Table,
  TableProps,
  Tag,
  Typography,
  Row,
  Col
} from 'antd'
import { ColumnsType } from 'antd/lib/table'
import { AxiosResponse } from 'axios'
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { Link } from 'react-router-dom'
import useProfileContext from 'useProfileContext'

import { listTenants } from 'apiClient/services/devops'
import {
  TenantTenantResponse,
  ListTenantsSortBy,
  ListTenantsKindItem,
  ListTenantsPlanItem,
  ListTenantsRegionItem,
  ListTenantsStatusItem
} from 'apiClient/services/devops/interface'
import { ListToolBar, useTable } from 'components/Table'
import { capitalize } from 'utils/string'

interface OrgsParams {
  page?: number
  per_page?: number
  alias?: string
  kind?: ListTenantsKindItem[]
  id?: number | undefined
  name?: string | undefined
  order?: 'asc' | 'desc'
  plan?: ListTenantsPlanItem[]
  sort_by?: ListTenantsSortBy
  status?: ListTenantsStatusItem[]
  email?: string
  search?: string
  region?: ListTenantsRegionItem[]
}

export const TenantList: React.FC<React.PropsWithChildren<unknown>> = () => {
  const [pageConfig, setPageConfig] = useSessionStorageState(
    'tenants_page_config',
    {
      defaultValue: {
        page: 1,
        pageSize: 0
      }
    }
  )
  const [tenantsFilter, setTenantsFilter] = useState<OrgsParams>({
    status: [ListTenantsStatusItem.active]
  })

  const [searchParams, setSearchParams] = useSessionStorageState<OrgsParams>(
    'search_params',
    {
      defaultValue: {
        search: ''
      }
    }
  )
  const [profileLoaded, setProfileLoaded] = useState(false)

  const isSelfProfileFetched = useRef(false)
  const { profile } = useProfileContext()

  const getData = (params?: Partial<PageInfo>): Promise<AxiosResponse> => {
    if (!profileLoaded) {
      return new Promise((resolve) => {
        // if profile is not loaded, return an empty structure
        resolve({
          data: {
            items: [],
            total: 0
          },
          status: 200,
          statusText: 'OK',
          headers: {},
          config: {},
          request: {}
        } as AxiosResponse)
      })
    }

    return listTenants({
      page: pageConfig.page,
      per_page: pageConfig.pageSize || params?.pageSize,
      ...searchParams,
      ...tenantsFilter
    })
  }

  const {
    dataSource,
    loading,
    reload,
    paginationProps
    // onTableChange
  } = useTable<ListData<TenantTenantResponse>>(getData, [], {
    pagination: true,
    current: pageConfig.page
  })

  useEffect(() => {
    const selfProfile = async () => {
      if (isSelfProfileFetched.current) return // if it has been loaded, it will not be called again
      try {
        isSelfProfileFetched.current = true
        const roleScope = profile.aggregatedRoleScope
        if (roleScope?.allowGlobalRegion === false) {
          setTenantsFilter({
            status: [ListTenantsStatusItem.active],
            region: roleScope.allowedRegions as ListTenantsRegionItem[]
          })
        }
      } catch (e) {
        console.error(e)
      } finally {
        setProfileLoaded(true)
        reload() // call getData here
      }
    }
    selfProfile()
  }, [profile, reload])

  const renderActionCell = useCallback(
    (_: any, record: TenantTenantResponse) => {
      return (
        <Space>
          <Link
            to={`/orgs/${record.id}?name=${record.name}`}
            // target='_blank'
          >
            Detail
          </Link>
        </Space>
      )
    },
    []
  )

  const renderStatusCell = useCallback(
    (_: any, record: TenantTenantResponse) => {
      let color
      const { status } = record
      switch (status) {
        case 'cleared':
          color = 'orange'
          break
        case 'deleted':
          color = 'red'
          break
        case 'active':
          color = 'green'
          break
        default:
          color = 'blue'
      }
      return (
        <Space>
          <Tag color={color} key={status}>
            {status}
          </Tag>
        </Space>
      )
    },
    []
  )

  const columns = useMemo(() => {
    const cols: ColumnsType<TenantTenantResponse> = [
      {
        title: 'Tenant',
        width: 210,
        fixed: 'left',
        dataIndex: 'id',
        render: (_, record) => (
          <Row>
            <Col span={24}>
              {record.name ? (
                <Typography.Text
                  style={{ width: 210 }}
                  ellipsis={{ tooltip: record.name }}
                >
                  {record.name}
                </Typography.Text>
              ) : (
                <span style={{ color: '#aaa' }}>-</span>
              )}
            </Col>
            <Col span={24}>
              <Typography.Text type="secondary">{record.id}</Typography.Text>
            </Col>
          </Row>
        )
      },
      {
        title: 'Status',
        dataIndex: 'status',
        width: 110,
        render: renderStatusCell,
        filters: [
          {
            text: 'pending',
            value: 'pending'
          },
          {
            text: 'active',
            value: 'active'
          },
          {
            text: 'cleared',
            value: 'cleared'
          },
          {
            text: 'deleted',
            value: 'deleted'
          }
        ],
        filterMultiple: true,
        filteredValue: tenantsFilter.status
      },
      {
        title: 'Account Alias',
        width: 170,
        render(_: any, record) {
          return record.alias || record.name
        }
      },
      {
        title: 'Region',
        dataIndex: 'region',
        width: 120,
        filterMultiple: true,
        filteredValue: tenantsFilter.region,
        filters: [
          {
            text: ListTenantsRegionItem.APAC,
            value: ListTenantsRegionItem.APAC
          },
          {
            text: ListTenantsRegionItem.EMEA,
            value: ListTenantsRegionItem.EMEA
          },
          {
            text: ListTenantsRegionItem.JAPAN,
            value: ListTenantsRegionItem.JAPAN
          },
          { text: ListTenantsRegionItem.NA, value: ListTenantsRegionItem.NA }
        ]
      },
      {
        title: 'Plan',
        dataIndex: 'plan',
        width: 120,
        render: (_: any, record: TenantTenantResponse) => {
          return record.plan?.split('_').map(capitalize).join(' ')
        },
        filterMultiple: true,
        filters: [
          { text: 'Free Trail', value: ListTenantsPlanItem.free_trial },
          { text: 'New User', value: ListTenantsPlanItem.new_user },
          { text: 'Poc', value: ListTenantsPlanItem.poc },
          { text: 'On Demand', value: ListTenantsPlanItem.on_demand }
        ]
      },
      {
        title: 'Kind',
        dataIndex: 'kind',
        width: 120,
        render: (_: any, record: TenantTenantResponse) => {
          let color = 'geekblue'
          if (record.kind === 'internal') {
            color = 'volcano'
          }
          return (
            <Tag color={color} key={record.kind}>
              {capitalize(record.kind || '')}
            </Tag>
          )
        },
        filterMultiple: true,
        filters: [
          { text: 'External', value: 'external' },
          { text: 'Internal', value: 'internal' }
        ]
      },
      {
        title: 'Segmentation',
        dataIndex: 'segmentation',
        filterMultiple: true,
        filters: [
          { text: 'SKA', value: 'SKA' },
          { text: 'KA', value: 'KA' },
          { text: 'SMB', value: 'SMB' }
        ],
        width: 130,
        render: (_, record) => {
          return record.segmentation || '-'
        }
      },
      {
        title: 'Email',
        width: 210,
        dataIndex: 'email'
      },
      {
        title: 'Sales Owner',
        width: 210,
        dataIndex: 'sales_owner_email',
        render: (_, record) => {
          return record.sales_owner_email || '-'
        }
      },
      {
        title: 'TAM',
        width: 210,
        dataIndex: 'tam_name',
        render: (_, record) => {
          return record.tam_name || '-'
        }
      },
      {
        title: 'Created At',
        dataIndex: 'created_at',
        width: 200,
        sorter: true
      },
      {
        title: 'Action',
        fixed: 'right',
        width: 100,
        dataIndex: 'action',
        render: renderActionCell
      }
    ]

    return cols
  }, [
    renderStatusCell,
    renderActionCell,
    tenantsFilter.status,
    tenantsFilter.region
    // roles
  ])

  const onSearch = (query: OrgsParams | null) => {
    setSearchParams({
      search: query?.search,
      id: query?.id,
      name: query?.name,
      alias: query?.alias,
      email: query?.email
    })
    setPageConfig({ page: 1, pageSize: 0 })
    setTenantsFilter({
      ...tenantsFilter
    })
    return reload()
  }

  const handleTabChange: TableProps<TenantTenantResponse>['onChange'] = (
    pagination,
    filters,
    sorter
  ) => {
    let sort: OrgsParams = {
      sort_by: undefined,
      order: undefined
    }
    if (!Array.isArray(sorter)) {
      sort.order =
        sorter.order === undefined
          ? undefined
          : sorter.order === 'ascend'
          ? 'asc'
          : 'desc'
      sort.sort_by =
        sorter.order === undefined
          ? undefined
          : (sorter.field as ListTenantsSortBy)
    }
    setTenantsFilter({
      ...tenantsFilter,
      ...filters,
      ...sort
    })
    return reload()
  }

  const onPaginationChange = (page: number, pageSize?: number) => {
    setPageConfig({ page, pageSize: pageSize || 0 })
  }

  return (
    <>
      <ListToolBar
        reload={reload}
        actions={[
          <Input.Group compact className="list-search-bar-container">
            <Input.Search
              placeholder="Search by ID/Name/Alias/Email"
              defaultValue={searchParams.search || ''}
              style={{ width: 300 }}
              onSearch={(value: string) => {
                onSearch(value ? { search: value.trim() } : null)
              }}
              allowClear
            />
          </Input.Group>
        ]}
      />

      <Table
        columns={columns}
        rowKey="id"
        dataSource={dataSource}
        loading={loading}
        size="small"
        // fix run time error
        // scroll={{ x: 1400 }}
        pagination={{
          ...paginationProps,
          current: pageConfig.page,
          pageSize: pageConfig.pageSize || paginationProps.pageSize,
          onChange: onPaginationChange,
          showTotal: (total) => `Total ${total} items`
        }}
        onChange={handleTabChange}
      />
    </>
  )
}
