import { useState, useEffect, useCallback } from 'react';
import { useOutletContext } from 'react-router-dom';
import {
  Typography,
  Table,
  Button,
  Space,
  Tag,
  Input,
  Tabs,
  Popconfirm,
  message,
} from 'antd';
import type { TableProps } from 'antd';
import {
  StarOutlined,
  StarFilled,
  DeleteOutlined,
  ArrowUpOutlined,
  ArrowDownOutlined,
  SearchOutlined,
  LinkOutlined,
  PlusOutlined,
  EditOutlined,
  CopyOutlined,
  GlobalOutlined,
  LockOutlined,
} from '@ant-design/icons';
import dayjs from 'dayjs';
import { mediaApi } from '@/lib/media-api';
import type { AppOutletContext } from '@/types/api';
import { useMobile } from '@/hooks/useMobile';
import CreatePlaylistModal from '@/components/media/CreatePlaylistModal';
import EditPlaylistModal from '@/components/media/EditPlaylistModal';
import axios from 'axios';

const { Text } = Typography;

interface PlaylistRow {
  id: number;
  name: string;
  description: string | null;
  isPublic: boolean;
  videoCount: number;
  totalDurationSeconds: number;
  viewCount: number;
  createdAt: string;
  creator: { id: string; name: string | null; email: string };
  isFeatured: boolean;
  featuredPosition: number | null;
  featuredAt: string | null;
}

interface FeaturedRow {
  id: number;
  playlistId: number;
  position: number;
  featuredAt: string | null;
  featuredBy: { id: string; name: string | null; email: string } | null;
  playlist: {
    id: number;
    name: string;
    isPublic: boolean;
    videoCount: number;
    totalDurationSeconds: number;
    viewCount: number;
    creator: { id: string; name: string | null; email: string };
  };
}

function formatDuration(totalSeconds: number): string {
  if (!totalSeconds) return '0:00';
  const hours = Math.floor(totalSeconds / 3600);
  const minutes = Math.floor((totalSeconds % 3600) / 60);
  if (hours > 0) return `${hours}h ${minutes}m`;
  return `${minutes}m`;
}

// Map Ant Design sorter field keys to backend sortBy values
const sorterFieldMap: Record<string, string> = {
  name: 'name',
  videoCount: 'videoCount',
  duration: 'totalDurationSeconds',
  viewCount: 'viewCount',
  createdAt: 'createdAt',
};

export default function PlaylistManagementPage() {
  const { setPageHeader } = useOutletContext<AppOutletContext>();
  const { isMobile } = useMobile();

  useEffect(() => {
    setPageHeader({ title: 'Playlist Management' });
    return () => setPageHeader(null);
  }, [setPageHeader]);

  // All Playlists tab state
  const [playlists, setPlaylists] = useState<PlaylistRow[]>([]);
  const [total, setTotal] = useState(0);
  const [loadingAll, setLoadingAll] = useState(false);
  const [search, setSearch] = useState('');
  const [pagination, setPagination] = useState({ current: 1, pageSize: 25 });
  const [sortBy, setSortBy] = useState('createdAt');
  const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>('desc');

  // Bulk selection state
  const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
  const [bulkLoading, setBulkLoading] = useState(false);

  // Featured tab state
  const [featured, setFeatured] = useState<FeaturedRow[]>([]);
  const [loadingFeatured, setLoadingFeatured] = useState(false);

  // Modal state
  const [createOpen, setCreateOpen] = useState(false);
  const [editPlaylistId, setEditPlaylistId] = useState<number | null>(null);

  const fetchAll = useCallback(async () => {
    try {
      setLoadingAll(true);
      const { data } = await mediaApi.get('/media/playlists', {
        params: {
          limit: pagination.pageSize,
          offset: (pagination.current - 1) * pagination.pageSize,
          search: search || undefined,
          sortBy,
          sortOrder,
        },
      });
      setPlaylists(data.data || []);
      setTotal(data.total || 0);
    } catch {
      message.error('Failed to load playlists');
    } finally {
      setLoadingAll(false);
    }
  }, [pagination, search, sortBy, sortOrder]);

  const fetchFeatured = useCallback(async () => {
    try {
      setLoadingFeatured(true);
      const { data } = await mediaApi.get('/media/playlists/featured');
      setFeatured(data.data || []);
    } catch {
      message.error('Failed to load featured playlists');
    } finally {
      setLoadingFeatured(false);
    }
  }, []);

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

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

  const handleFeature = async (playlistId: number) => {
    try {
      await mediaApi.post(`/media/playlists/${playlistId}/feature`);
      message.success('Playlist featured');
      fetchAll();
      fetchFeatured();
    } catch (error: unknown) {
      if (axios.isAxiosError(error) && error.response?.status === 409) {
        message.warning('Already featured');
      } else {
        message.error('Failed to feature playlist');
      }
    }
  };

  const handleUnfeature = async (playlistId: number) => {
    try {
      await mediaApi.delete(`/media/playlists/${playlistId}/feature`);
      message.success('Playlist unfeatured');
      fetchAll();
      fetchFeatured();
    } catch {
      message.error('Failed to unfeature');
    }
  };

  const handleDelete = async (playlistId: number) => {
    try {
      await mediaApi.delete(`/media/playlists/${playlistId}`);
      message.success('Playlist deleted');
      fetchAll();
      fetchFeatured();
    } catch {
      message.error('Failed to delete playlist');
    }
  };

  const handleToggleVisibility = async (record: PlaylistRow) => {
    try {
      await mediaApi.put(`/media/playlists/${record.id}`, {
        isPublic: !record.isPublic,
      });
      message.success(`Playlist set to ${record.isPublic ? 'Private' : 'Public'}`);
      fetchAll();
    } catch {
      message.error('Failed to update visibility');
    }
  };

  const handleDuplicate = async (playlistId: number) => {
    try {
      const { data } = await mediaApi.post(`/media/playlists/${playlistId}/duplicate`);
      message.success(`Created "${data.name}"`);
      fetchAll();
    } catch {
      message.error('Failed to duplicate playlist');
    }
  };

  const handleReorder = async (index: number, direction: 'up' | 'down') => {
    const newFeatured = [...featured];
    const targetIndex = direction === 'up' ? index - 1 : index + 1;
    if (targetIndex < 0 || targetIndex >= newFeatured.length) return;

    const temp = newFeatured[index]!;
    newFeatured[index] = newFeatured[targetIndex]!;
    newFeatured[targetIndex] = temp;

    const reordered = newFeatured.map((f, i) => ({ ...f, position: i }));
    setFeatured(reordered);

    try {
      await mediaApi.put('/media/playlists/featured/reorder', {
        items: reordered.map((f) => ({
          playlistId: f.playlistId,
          position: f.position,
        })),
      });
    } catch {
      message.error('Failed to reorder');
      fetchFeatured();
    }
  };

  // Table onChange handler for sorting
  const handleTableChange: TableProps<PlaylistRow>['onChange'] = (_pag, _filters, sorter) => {
    if (!sorter || Array.isArray(sorter)) return;
    const field = sorter.columnKey as string;
    const mappedField = sorterFieldMap[field];
    if (mappedField && sorter.order) {
      setSortBy(mappedField);
      setSortOrder(sorter.order === 'ascend' ? 'asc' : 'desc');
    } else {
      setSortBy('createdAt');
      setSortOrder('desc');
    }
    setPagination((p) => ({ ...p, current: 1 }));
  };

  // Bulk operations
  const handleBulkAction = async (action: 'public' | 'private' | 'feature' | 'delete') => {
    if (selectedRowKeys.length === 0) return;
    setBulkLoading(true);
    let successCount = 0;

    try {
      for (const id of selectedRowKeys) {
        try {
          switch (action) {
            case 'public':
              await mediaApi.put(`/media/playlists/${id}`, { isPublic: true });
              break;
            case 'private':
              await mediaApi.put(`/media/playlists/${id}`, { isPublic: false });
              break;
            case 'feature':
              await mediaApi.post(`/media/playlists/${id}/feature`);
              break;
            case 'delete':
              await mediaApi.delete(`/media/playlists/${id}`);
              break;
          }
          successCount++;
        } catch {
          // Continue with other items
        }
      }

      const labels = { public: 'made public', private: 'made private', feature: 'featured', delete: 'deleted' };
      message.success(`${successCount} playlist(s) ${labels[action]}`);
      setSelectedRowKeys([]);
      fetchAll();
      fetchFeatured();
    } finally {
      setBulkLoading(false);
    }
  };

  // All Playlists table columns
  const allColumns = [
    {
      title: 'Name',
      dataIndex: 'name',
      key: 'name',
      sorter: true,
      render: (name: string, record: PlaylistRow) => (
        <Space>
          <Text strong>{name}</Text>
          {record.isFeatured && (
            <StarFilled style={{ color: '#faad14', fontSize: 12 }} />
          )}
        </Space>
      ),
    },
    {
      title: 'Creator',
      key: 'creator',
      responsive: ['md'] as any,
      render: (_: any, record: PlaylistRow) => (
        <Text type="secondary" style={{ fontSize: 12 }}>
          {record.creator.name || record.creator.email}
        </Text>
      ),
    },
    {
      title: 'Videos',
      dataIndex: 'videoCount',
      key: 'videoCount',
      width: 80,
      align: 'center' as const,
      sorter: true,
    },
    {
      title: 'Duration',
      dataIndex: 'totalDurationSeconds',
      key: 'duration',
      width: 100,
      responsive: ['lg'] as any,
      sorter: true,
      render: (seconds: number) => formatDuration(seconds),
    },
    {
      title: 'Views',
      dataIndex: 'viewCount',
      key: 'viewCount',
      width: 80,
      align: 'center' as const,
      sorter: true,
    },
    {
      title: 'Created',
      dataIndex: 'createdAt',
      key: 'createdAt',
      width: 110,
      responsive: ['md'] as any,
      sorter: true,
      render: (date: string) => dayjs(date).format('MMM D, YYYY'),
    },
    {
      title: 'Visibility',
      dataIndex: 'isPublic',
      key: 'isPublic',
      width: 90,
      responsive: ['md'] as any,
      render: (isPublic: boolean, record: PlaylistRow) => (
        <Tag
          color={isPublic ? 'green' : 'default'}
          icon={isPublic ? <GlobalOutlined /> : <LockOutlined />}
          style={{ cursor: 'pointer' }}
          onClick={() => handleToggleVisibility(record)}
        >
          {isPublic ? 'Public' : 'Private'}
        </Tag>
      ),
    },
    {
      title: 'Actions',
      key: 'actions',
      width: 210,
      render: (_: any, record: PlaylistRow) => (
        <Space size={4}>
          <Button
            size="small"
            type="text"
            icon={<EditOutlined />}
            onClick={() => setEditPlaylistId(record.id)}
            title="Edit"
          />
          <Button
            size="small"
            type="text"
            icon={<CopyOutlined />}
            onClick={() => handleDuplicate(record.id)}
            title="Duplicate"
          />
          <Button
            size="small"
            type="text"
            icon={<LinkOutlined />}
            onClick={() => {
              window.open(`/gallery/curated/${record.id}`, '_blank');
            }}
            title="View"
          />
          {record.isFeatured ? (
            <Button
              size="small"
              type="text"
              icon={<StarFilled style={{ color: '#faad14' }} />}
              onClick={() => handleUnfeature(record.id)}
              title="Unfeature"
            />
          ) : (
            <Button
              size="small"
              type="text"
              icon={<StarOutlined />}
              onClick={() => handleFeature(record.id)}
              title="Feature"
            />
          )}
          <Popconfirm
            title="Delete this playlist?"
            onConfirm={() => handleDelete(record.id)}
            okText="Delete"
            okType="danger"
          >
            <Button size="small" type="text" danger icon={<DeleteOutlined />} />
          </Popconfirm>
        </Space>
      ),
    },
  ];

  // Featured table columns
  const featuredColumns = [
    {
      title: '#',
      dataIndex: 'position',
      key: 'position',
      width: 50,
      render: (pos: number) => pos + 1,
    },
    {
      title: 'Playlist',
      key: 'playlist',
      render: (_: any, record: FeaturedRow) => (
        <div>
          <Text strong>{record.playlist.name}</Text>
          <br />
          <Text type="secondary" style={{ fontSize: 12 }}>
            by {record.playlist.creator.name || record.playlist.creator.email}
            {' \u2022 '}
            {record.playlist.videoCount} videos
            {' \u2022 '}
            {record.playlist.viewCount} views
          </Text>
        </div>
      ),
    },
    {
      title: 'Featured By',
      key: 'featuredBy',
      responsive: ['md'] as any,
      render: (_: any, record: FeaturedRow) => (
        <Text type="secondary" style={{ fontSize: 12 }}>
          {record.featuredBy?.name || record.featuredBy?.email || '\u2014'}
        </Text>
      ),
    },
    {
      title: 'Actions',
      key: 'actions',
      width: 140,
      render: (_: any, record: FeaturedRow, index: number) => (
        <Space size={4}>
          <Button
            size="small"
            type="text"
            icon={<ArrowUpOutlined />}
            disabled={index === 0}
            onClick={() => handleReorder(index, 'up')}
          />
          <Button
            size="small"
            type="text"
            icon={<ArrowDownOutlined />}
            disabled={index === featured.length - 1}
            onClick={() => handleReorder(index, 'down')}
          />
          <Button
            size="small"
            type="text"
            danger
            icon={<StarFilled />}
            onClick={() => handleUnfeature(record.playlistId)}
            title="Unfeature"
          />
        </Space>
      ),
    },
  ];

  const handleRefreshAll = () => {
    fetchAll();
    fetchFeatured();
  };

  return (
    <div>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'flex-end', marginBottom: 16 }}>
        <Button
          type="primary"
          icon={<PlusOutlined />}
          onClick={() => setCreateOpen(true)}
        >
          Create Playlist
        </Button>
      </div>

      <Tabs
        items={[
          {
            key: 'all',
            label: `All Playlists (${total})`,
            children: (
              <>
                <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 16, flexWrap: 'wrap' }}>
                  <Input
                    placeholder="Search playlists..."
                    prefix={<SearchOutlined />}
                    value={search}
                    onChange={(e) => {
                      setSearch(e.target.value);
                      setPagination((p) => ({ ...p, current: 1 }));
                    }}
                    allowClear
                    style={{ width: isMobile ? '100%' : 300 }}
                  />

                  {/* Bulk actions bar */}
                  {selectedRowKeys.length > 0 && (
                    <Space size={8}>
                      <Text type="secondary">{selectedRowKeys.length} selected</Text>
                      <Button
                        size="small"
                        icon={<GlobalOutlined />}
                        onClick={() => handleBulkAction('public')}
                        loading={bulkLoading}
                      >
                        {!isMobile && 'Make Public'}
                      </Button>
                      <Button
                        size="small"
                        icon={<LockOutlined />}
                        onClick={() => handleBulkAction('private')}
                        loading={bulkLoading}
                      >
                        {!isMobile && 'Make Private'}
                      </Button>
                      <Button
                        size="small"
                        icon={<StarOutlined />}
                        onClick={() => handleBulkAction('feature')}
                        loading={bulkLoading}
                      >
                        {!isMobile && 'Feature'}
                      </Button>
                      <Popconfirm
                        title={`Delete ${selectedRowKeys.length} playlist(s)?`}
                        onConfirm={() => handleBulkAction('delete')}
                        okText="Delete"
                        okType="danger"
                      >
                        <Button
                          size="small"
                          danger
                          icon={<DeleteOutlined />}
                          loading={bulkLoading}
                        >
                          Delete
                        </Button>
                      </Popconfirm>
                      <Button size="small" onClick={() => setSelectedRowKeys([])}>
                        Clear
                      </Button>
                    </Space>
                  )}
                </div>

                <Table
                  dataSource={playlists}
                  columns={allColumns}
                  scroll={{ x: 'max-content' }}
                  rowKey="id"
                  loading={loadingAll}
                  rowSelection={{
                    selectedRowKeys,
                    onChange: setSelectedRowKeys,
                  }}
                  onChange={handleTableChange}
                  pagination={{
                    current: pagination.current,
                    pageSize: pagination.pageSize,
                    total,
                    onChange: (page, pageSize) =>
                      setPagination({ current: page, pageSize }),
                    showSizeChanger: true,
                    showTotal: (t) => `${t} playlists`,
                  }}
                  size="middle"
                />
              </>
            ),
          },
          {
            key: 'featured',
            label: `Featured (${featured.length})`,
            children: (
              <Table
                dataSource={featured}
                columns={featuredColumns}
                scroll={{ x: 'max-content' }}
                rowKey="id"
                loading={loadingFeatured}
                pagination={false}
                size="middle"
                locale={{ emptyText: 'No featured playlists. Feature playlists from the "All Playlists" tab.' }}
              />
            ),
          },
        ]}
      />

      <CreatePlaylistModal
        open={createOpen}
        onClose={() => setCreateOpen(false)}
        onCreated={handleRefreshAll}
      />

      <EditPlaylistModal
        playlistId={editPlaylistId}
        open={!!editPlaylistId}
        onClose={() => setEditPlaylistId(null)}
        onUpdated={handleRefreshAll}
      />
    </div>
  );
}
