/**
 * Bulk Edit Tab - Titles & Meta Settings
 *
 * Allows bulk editing of SEO titles and descriptions.
 *
 * @package
 * @since   1.0.0
 */

import { useState, useEffect, useCallback } from '@wordpress/element';
import { __, sprintf } from '@wordpress/i18n';
import apiFetch from '@wordpress/api-fetch';
import { debounce } from '../../../shims/wp-utils-shim';
import { Card, Button, Select, Input, Alert } from '../../components/ui';
import LoadingState from '../../components/LoadingState';
import { useNotification } from '../../contexts/NotificationContext';

const getBulkEditRequestState = () => {
  const params = new URLSearchParams(window.location.search);
  const postIds = (params.get('post_ids') || '')
    .split(',')
    .map((id) => parseInt(id, 10))
    .filter((id) => Number.isInteger(id) && id > 0);
  const postType = params.get('post_type') || 'post';

  return {
    postIds,
    postType,
  };
};

// Helper component for radio buttons
const RadioGroup = ({ label, options, selected, onChange }) => (
  <div className="pr:space-y-2">
    <label className="pr:block pr:text-sm pr:font-medium pr:text-gray-700">{label}</label>
    <div className="pr:space-y-2">
      {options.map((option) => (
        <label key={option.value} className="pr:flex pr:items-center pr:gap-2 pr:cursor-pointer">
          <input
            type="radio"
            value={option.value}
            checked={selected === option.value}
            onChange={(e) => onChange(e.target.value)}
            className="pr:w-4 pr:h-4 pr:text-primary-600 pr:border-gray-300 pr:focus:ring-primary-500"
          />
          <span className="pr:text-sm pr:text-gray-700">{option.label}</span>
        </label>
      ))}
    </div>
  </div>
);

// Helper component for checkbox
const Checkbox = ({ label, checked, onChange }) => (
  <label className="pr:flex pr:items-center pr:gap-2 pr:cursor-pointer">
    <input
      type="checkbox"
      checked={checked}
      onChange={(value) => {
        const nextChecked = typeof value === 'boolean' ? value : !!value?.target?.checked;
        onChange(nextChecked);
      }}
      className="pr:w-4 pr:h-4 pr:text-primary-600 pr:border-gray-300 pr:rounded pr:focus:ring-primary-500"
    />
    <span className="pr:text-sm pr:text-gray-700">{label}</span>
  </label>
);

const BulkEditTab = () => {
  const initialRequest = getBulkEditRequestState();
  const [loading, setLoading] = useState(false);
  const [saving, setSaving] = useState(false);
  const [posts, setPosts] = useState([]);
  const [selectedPosts, setSelectedPosts] = useState([]);
  const [postType, setPostType] = useState(initialRequest.postType || 'post');
  const [currentPage, setCurrentPage] = useState(1);
  const [totalPages, setTotalPages] = useState(1);
  const [totalPosts, setTotalPosts] = useState(0);
  const [searchTerm, setSearchTerm] = useState('');
  const [editedData, setEditedData] = useState({});
  const [error, setError] = useState(null);
  const [success, setSuccess] = useState(null);
  const [availablePostTypes, setAvailablePostTypes] = useState([]);
  const [settings, setSettings] = useState({});
  const [requestedPostIds] = useState(initialRequest.postIds);
  // Task 3 — CSV import/export state.
  const [exportBusy, setExportBusy] = useState(false);
  const [showImportPanel, setShowImportPanel] = useState(false);
  const [importContent, setImportContent] = useState('');
  const [importBusy, setImportBusy] = useState(false);
  const [importResult, setImportResult] = useState(null);
  const { showNotification } = useNotification();

  // Debounced search
  const debouncedSearch = useCallback(
    debounce((term) => {
      loadPosts(1, term);
    }, 500),
    [postType]
  );

  useEffect(() => {
    // Load settings and available post types
    loadSettings();
  }, []);

  useEffect(() => {
    if (postType) {
      loadPosts();
    }
  }, [postType]);

  useEffect(() => {
    if (searchTerm) {
      debouncedSearch(searchTerm);
    } else if (postType) {
      loadPosts();
    }
  }, [searchTerm]);

  const loadSettings = async () => {
    try {
      // Load titles-meta settings to check which post types have bulk editing enabled
      const response = await apiFetch({
        path: '/prorank-seo/v1/settings/titles-meta',
      });
      
      setSettings(response || {});
      
      // Get all post types from WordPress
      const typesResponse = await apiFetch({
        path: '/wp/v2/types?context=edit',
      });
      
      // Filter to only show post types that have bulk editing enabled
      const types = [];
      Object.entries(typesResponse).forEach(([key, type]) => {
        // Check if bulk editing is enabled for this post type
        const postTypeSettings = response[`post_type_${key}`] || {};
        // Always show posts and pages, check setting for others
        if (key === 'post' || key === 'page' || postTypeSettings.bulk_editing === true) {
          types.push({
            value: key,
            label: type.labels.name,
          });
        }
      });
      
      setAvailablePostTypes(types);

      // Set initial post type if available
      if (types.length > 0 && !postType) {
        setPostType(types[0].value);
      }
    } catch (err) {
      // Fallback to default post types
      setAvailablePostTypes([
        { label: __('Posts', 'prorank-seo'), value: 'post' },
        { label: __('Pages', 'prorank-seo'), value: 'page' },
      ]);
    }
  };

  const loadPosts = async (page = 1, search = '') => {
    setLoading(true);
    setError(null);
    
    try {
      const params = new URLSearchParams({
        post_type: postType,
        paged: String(page),
        per_page: '20',
        search,
      });

      if (requestedPostIds.length > 0) {
        params.set('post_ids', requestedPostIds.join(','));
      }

      const response = await apiFetch({
        path: `/prorank-seo/v1/titles-meta/bulk-edit?${params.toString()}`,
      });

      if (response.success && response.data) {
        setPosts(response.data.posts);
        setTotalPages(response.data.pages);
        setTotalPosts(response.data.total);
        setCurrentPage(response.data.current_page);
        setSelectedPosts(
          Array.isArray(response.data.selected_post_ids) && response.data.selected_post_ids.length > 0
            ? response.data.posts.map((post) => post.id)
            : []
        );
        setEditedData({});
      }
    } catch (err) {
      setError(__('Failed to load posts.', 'prorank-seo'));
    } finally {
      setLoading(false);
    }
  };

  const handleSelectAll = (checked) => {
    if (checked) {
      setSelectedPosts(posts.map(post => post.id));
    } else {
      setSelectedPosts([]);
    }
  };

  const handleSelectPost = (postId, checked) => {
    if (checked) {
      setSelectedPosts([...selectedPosts, postId]);
    } else {
      setSelectedPosts(selectedPosts.filter(id => id !== postId));
    }
  };

  const handleFieldEdit = (postId, field, value) => {
    setEditedData(prev => ({
      ...prev,
      [postId]: {
        ...prev[postId],
        id: postId,
        [field]: value,
      }
    }));
  };

  // Task 3 — Export current post type's metadata as CSV.
  const handleExportCsv = async () => {
    setExportBusy(true);
    try {
      const params = new URLSearchParams({ post_type: postType });
      if (searchTerm) {
        params.set('search', searchTerm);
      }
      const response = await apiFetch({
        path: `/prorank-seo/v1/titles-meta/bulk-edit/export-csv?${params.toString()}`,
      });
      const payload = response?.data || response || {};
      const csv = String(payload.csv || '');
      if (!csv) {
        showNotification(__('Nothing to export.', 'prorank-seo'), 'info');
        return;
      }
      const blob = new Blob([csv], { type: 'text/csv;charset=utf-8' });
      const url = window.URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = payload.filename || `prorank-seo-bulk-${postType}.csv`;
      document.body.appendChild(a);
      a.click();
      window.URL.revokeObjectURL(url);
      document.body.removeChild(a);
      showNotification(
        sprintf(/* translators: %d: rows exported */ __('Exported %d rows', 'prorank-seo'), payload.row_count || 0),
        'success'
      );
    } catch (err) {
      showNotification(err?.message || __('Failed to export CSV.', 'prorank-seo'), 'error');
    } finally {
      setExportBusy(false);
    }
  };

  // Task 3 — Import (or dry-run) a CSV against the bulk metadata endpoint.
  const submitImportCsv = async (dryRun) => {
    if (!importContent.trim()) {
      showNotification(__('Paste CSV content first.', 'prorank-seo'), 'error');
      return;
    }
    setImportBusy(true);
    setImportResult(null);
    try {
      const response = await apiFetch({
        path: '/prorank-seo/v1/titles-meta/bulk-edit/import-csv',
        method: 'POST',
        data: { content: importContent, dry_run: !!dryRun },
      });
      const result = response?.data || response || {};
      setImportResult(result);
      if (!dryRun) {
        showNotification(
          sprintf(/* translators: %d: number of rows updated */ __('%d row(s) updated', 'prorank-seo'), result.will_update || 0),
          'success'
        );
        await loadPosts(currentPage, searchTerm);
      }
    } catch (err) {
      showNotification(err?.message || __('Failed to import CSV.', 'prorank-seo'), 'error');
    } finally {
      setImportBusy(false);
    }
  };

  const saveChanges = async () => {
    const updates = Object.values(editedData).filter(data => 
      selectedPosts.includes(data.id)
    );

    if (updates.length === 0) {
      setError(__('No changes to save.', 'prorank-seo'));
      return;
    }

    setSaving(true);
    setError(null);
    setSuccess(null);

    try {
      const response = await apiFetch({
        path: '/prorank-seo/v1/titles-meta/bulk-edit',
        method: 'POST',
        data: { updates },
      });

      if (response.success) {
        const message = response.message || __('Changes saved.', 'prorank-seo');
        setSuccess(message);
        showNotification(message, 'success');
        setEditedData({});
        await loadPosts(currentPage, searchTerm);
      } else {
        throw new Error(response.message || __('Failed to save changes.', 'prorank-seo'));
      }
    } catch (err) {
      setError(err.message);
      showNotification(__('Failed to save changes.', 'prorank-seo'), 'error');
    } finally {
      setSaving(false);
    }
  };

  const getFieldValue = (post, field) => {
    if (editedData[post.id] && editedData[post.id][field] !== undefined) {
      return editedData[post.id][field];
    }
    return post[field] || '';
  };

  // Enhanced Character Progress with color-coded progress bar
  const CharacterProgress = ({ text, type = 'title' }) => {
    const length = text?.length || 0;

    // Define ranges based on type
    const ranges = type === 'title'
      ? { min: 30, optMin: 50, optMax: 60, warnMax: 65, max: 70 }
      : { min: 70, optMin: 120, optMax: 155, warnMax: 160, max: 160 };

    // Calculate status
    const getStatus = () => {
      if (length === 0) return { color: 'gray' };
      if (length < ranges.min) return { color: 'red' };
      if (length < ranges.optMin) return { color: 'yellow' };
      if (length <= ranges.optMax) return { color: 'green' };
      if (length <= ranges.warnMax) return { color: 'yellow' };
      return { color: 'red' };
    };

    const status = getStatus();
    const percent = length === 0 ? 0 : Math.min(100, (length / ranges.max) * 100);

    const barColors = {
      gray: 'pr:bg-gray-300',
      red: 'pr:bg-red-500',
      yellow: 'pr:bg-yellow-500',
      green: 'pr:bg-green-500',
    };

    const textColors = {
      gray: 'pr:text-gray-500',
      red: 'pr:text-red-600',
      yellow: 'pr:text-yellow-600',
      green: 'pr:text-green-600',
    };

    return (
      <div className="pr:mt-1.5">
        {/* Progress bar */}
        <div className="pr:h-1.5 pr:bg-gray-200 pr:rounded-full pr:overflow-hidden">
          <div
            className={`pr:h-full pr:transition-all pr:duration-300 pr:rounded-full ${barColors[status.color]}`}
            style={{ width: `${percent}%` }}
          />
        </div>
        {/* Counter text */}
        <div className="pr:flex pr:justify-between pr:items-center pr:mt-1">
          <span className={`pr:text-xs pr:font-medium ${textColors[status.color]}`}>
            {length}
          </span>
          <span className="pr:text-xs pr:text-gray-400">
            {type === 'title' ? '50-60' : '120-155'}
          </span>
        </div>
      </div>
    );
  };

  return (
    <div className="pr:space-y-6">
      {error && (
        <Alert variant="error" dismissible onDismiss={() => setError(null)}>
          {error}
        </Alert>
      )}

      {success && (
        <Alert variant="success" dismissible onDismiss={() => setSuccess(null)}>
          {success}
        </Alert>
      )}

      {availablePostTypes.length === 0 && !loading && (
        <Alert variant="info">
          <p>
            <strong>{__('No post types available for bulk editing.', 'prorank-seo')}</strong>
          </p>
          <p>
            {__('To enable bulk editing for a post type:', 'prorank-seo')}
          </p>
          <ol className="pr:ml-5 pr:mt-2 pr:list-decimal">
            <li>{__('Go to the Post Types tab', 'prorank-seo')}</li>
            <li>{__('Select the post type you want to edit (Posts, Pages, etc.)', 'prorank-seo')}</li>
            <li>{__('Enable the "Enable Bulk Editing" option', 'prorank-seo')}</li>
            <li>{__('Save your changes', 'prorank-seo')}</li>
          </ol>
          <p className="pr:mt-2">
            <em>{__('Note: Posts and Pages are always available for bulk editing by default.', 'prorank-seo')}</em>
          </p>
        </Alert>
      )}

      {requestedPostIds.length > 0 && (
        <Alert variant="info">
          {sprintf(
            __('Loaded %d selected items from the posts list for bulk editing.', 'prorank-seo'),
            requestedPostIds.length
          )}
        </Alert>
      )}

      <Card>
        <div className="pr:p-6 pr:border-b pr:border-gray-200">
          <div className="pr:grid pr:grid-cols-1 pr:md:grid-cols-3 pr:gap-4">
            <div>
              <label className="pr:block pr:text-sm pr:font-medium pr:text-gray-700 pr:mb-2">
                {__('Post Type', 'prorank-seo')}
              </label>
              <Select
                value={postType}
                options={availablePostTypes}
                onChange={(e) => setPostType(e.target.value)}
              />
              {availablePostTypes.length === 0 && (
                <p className="pr:text-xs pr:text-gray-500 pr:mt-1">
                  {__('No post types available. Enable bulk editing in Post Types settings.', 'prorank-seo')}
                </p>
              )}
            </div>

            <div>
              <label className="pr:block pr:text-sm pr:font-medium pr:text-gray-700 pr:mb-2">
                {__('Search', 'prorank-seo')}
              </label>
              <Input
                type="text"
                value={searchTerm}
                onChange={(e) => setSearchTerm(e.target.value)}
                placeholder={__('Search posts...', 'prorank-seo')}
              />
            </div>

            <div className="pr:mt-6 pr:flex pr:flex-wrap pr:gap-2 pr:transition-all pr:duration-300">
              <Button
                variant="primary"
                onClick={saveChanges}
                disabled={saving || selectedPosts.length === 0}
                isBusy={saving}
              >
                {saving ? __('Saving...', 'prorank-seo') : __('Save Changes', 'prorank-seo')}
              </Button>
              <Button
                variant="secondary"
                onClick={handleExportCsv}
                disabled={exportBusy}
                isBusy={exportBusy}
              >
                {__('Export CSV', 'prorank-seo')}
              </Button>
              <Button
                variant="secondary"
                onClick={() => {
                  setShowImportPanel((prev) => !prev);
                  setImportResult(null);
                }}
              >
                {showImportPanel ? __('Close Import', 'prorank-seo') : __('Import CSV', 'prorank-seo')}
              </Button>
            </div>
          </div>
        </div>
        {showImportPanel && (
          <div className="pr:p-6 pr:border-b pr:border-gray-200 pr:bg-gray-50">
            <h4 className="pr:text-base pr:font-semibold pr:mb-2">{__('Import Metadata CSV', 'prorank-seo')}</h4>
            <p className="pr:text-sm pr:text-gray-600 pr:mb-3">
              {__(
                'Paste an exported CSV (or one from another tool). Posts are matched by post_id; if missing, permalink is tried. Only seo_title, meta_description, focus_keyword, canonical_url, and robots columns are written. Use Preview to dry-run before importing.',
                'prorank-seo'
              )}
            </p>
            <textarea
              className="pr:w-full pr:h-48 pr:font-mono pr:text-xs pr:p-3 pr:border pr:border-gray-300 pr:rounded-xs"
              placeholder={__('Paste CSV here…', 'prorank-seo')}
              value={importContent}
              onChange={(event) => setImportContent(event.target.value)}
            />
            <div className="pr:flex pr:gap-2 pr:mt-3">
              <Button variant="secondary" onClick={() => submitImportCsv(true)} disabled={importBusy}>
                {__('Preview (dry-run)', 'prorank-seo')}
              </Button>
              <Button variant="primary" onClick={() => submitImportCsv(false)} disabled={importBusy}>
                {importBusy ? __('Importing…', 'prorank-seo') : __('Import', 'prorank-seo')}
              </Button>
            </div>
            {importResult && (
              <div className="pr:text-sm pr:bg-white pr:border pr:border-gray-200 pr:rounded-xs pr:p-3 pr:mt-3">
                <div className="pr:font-medium pr:mb-1">
                  {importResult.dry_run ? __('Preview result', 'prorank-seo') : __('Import result', 'prorank-seo')}
                </div>
                <ul className="pr:list-disc pr:ml-5 pr:space-y-1">
                  <li>{sprintf(__('Will update: %d', 'prorank-seo'), importResult.will_update || 0)}</li>
                  <li>{sprintf(__('Unchanged: %d', 'prorank-seo'), importResult.unchanged || 0)}</li>
                  <li>{sprintf(__('Invalid: %d', 'prorank-seo'), importResult.invalid || 0)}</li>
                  <li>{sprintf(__('Missing post: %d', 'prorank-seo'), importResult.missing_post || 0)}</li>
                </ul>
                {Array.isArray(importResult.errors) && importResult.errors.length > 0 && (
                  <details className="pr:mt-2">
                    <summary className="pr:cursor-pointer pr:text-xs pr:text-gray-700">
                      {sprintf(__('%d error(s) — first 20 shown', 'prorank-seo'), importResult.errors.length)}
                    </summary>
                    <ul className="pr:mt-1 pr:ml-5 pr:list-disc pr:text-xs pr:text-gray-700 pr:space-y-1">
                      {importResult.errors.slice(0, 20).map((err, idx) => (
                        <li key={idx}>{err}</li>
                      ))}
                    </ul>
                  </details>
                )}
              </div>
            )}
          </div>
        )}
        <div className="pr:p-6">
          {loading ? (
            <div className="pr:text-center pr:py-10 pr:transition-all pr:duration-300">
              <LoadingState />
              <p className="pr:mt-4 pr:text-gray-600">{__('Loading posts...', 'prorank-seo')}</p>
            </div>
          ) : posts.length === 0 ? (
            <Alert variant="info">
              {__('No posts found.', 'prorank-seo')}
            </Alert>
          ) : (
            <>
              <div className="pr:mb-5 pr:transition-all pr:duration-300">
                <Checkbox
                  label={__('Select All', 'prorank-seo')}
                  checked={selectedPosts.length === posts.length && posts.length > 0}
                  onChange={handleSelectAll}
                />
                <p className="pr:mt-2 pr:text-gray-500 pr:transition-all pr:duration-300">
                  {selectedPosts.length > 0
                    ? sprintf(__('%d items selected', 'prorank-seo'), selectedPosts.length)
                    : __('Select items to edit', 'prorank-seo')
                  }
                </p>
              </div>

              <div className="bulk-edit-table pr:overflow-x-auto">
                <table className="wp-list-table widefat fixed striped">
                  <thead>
                    <tr>
                      <th className="pr:w-8 pr:transition-all pr:duration-300"></th>
                      <th>{__('Title', 'prorank-seo')}</th>
                      <th>
                        {__('SEO Title', 'prorank-seo')}
                        <span className="pr:text-xs pr:text-gray-400 pr:font-normal pr:ml-1">(50-60)</span>
                      </th>
                      <th>
                        {__('Meta Description', 'prorank-seo')}
                        <span className="pr:text-xs pr:text-gray-400 pr:font-normal pr:ml-1">(120-155)</span>
                      </th>
                      <th>{__('Focus Keyword', 'prorank-seo')}</th>
                    </tr>
                  </thead>
                  <tbody>
                    {posts.map(post => (
                      <tr key={post.id} className={selectedPosts.includes(post.id) ? 'selected' : ''}>
                        <td>
                          <Checkbox
                            checked={selectedPosts.includes(post.id)}
                            onChange={(checked) => handleSelectPost(post.id, checked)}
                          />
                        </td>
                        <td>
                          <strong>{post.title}</strong>
                          <br />
                          <span className="pr:text-xs pr:text-gray-500 pr:transition-all pr:duration-300">
                            <a href={post.url} target="_blank" rel="noopener noreferrer" className="pr:hover:text-primary-600">
                              {__('View', 'prorank-seo')}
                            </a>
                          </span>
                        </td>
                        <td>
                          <div className="pr:relative">
                            <Input
                              type="text"
                              value={getFieldValue(post, 'seo_title')}
                              onChange={(e) => handleFieldEdit(post.id, 'seo_title', e.target.value)}
                              placeholder={post.title}
                              disabled={!selectedPosts.includes(post.id)}
                            />
                          </div>
                          <CharacterProgress
                            text={getFieldValue(post, 'seo_title') || post.title}
                            type="title"
                          />
                        </td>
                        <td>
                          <div className="pr:relative">
                            <textarea
                              className="pr:w-full pr:px-3 pr:py-2 pr:border pr:border-gray-300 pr:rounded-md pr:focus:outline-hidden pr:focus:ring-2 pr:focus:ring-primary-500 pr:transition-all pr:duration-300"
                              value={getFieldValue(post, 'seo_description')}
                              onChange={(e) => handleFieldEdit(post.id, 'seo_description', e.target.value)}
                              placeholder={post.excerpt || __('Auto-generated from content', 'prorank-seo')}
                              disabled={!selectedPosts.includes(post.id)}
                              rows={2}
                            />
                          </div>
                          <CharacterProgress
                            text={getFieldValue(post, 'seo_description') || post.excerpt || ''}
                            type="description"
                          />
                        </td>
                        <td>
                          <Input
                            type="text"
                            value={getFieldValue(post, 'focus_keyword')}
                            onChange={(e) => handleFieldEdit(post.id, 'focus_keyword', e.target.value)}
                            placeholder={__('Focus keyword', 'prorank-seo')}
                            disabled={!selectedPosts.includes(post.id)}
                          />
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>

              {totalPages > 1 && (
                <div className="pr:mt-5 pr:text-center pr:flex pr:items-center pr:justify-center pr:gap-4 pr:transition-all pr:duration-300">
                  <Button
                    variant="secondary"
                    onClick={() => loadPosts(currentPage - 1, searchTerm)}
                    disabled={currentPage === 1}
                  >
                    {__('Previous', 'prorank-seo')}
                  </Button>
                  <span className="pr:text-gray-600 pr:transition-all pr:duration-300">
                    {sprintf(__('Page %d of %d', 'prorank-seo'), currentPage, totalPages)}
                  </span>
                  <Button
                    variant="secondary"
                    onClick={() => loadPosts(currentPage + 1, searchTerm)}
                    disabled={currentPage === totalPages}
                  >
                    {__('Next', 'prorank-seo')}
                  </Button>
                </div>
              )}
            </>
          )}
        </div>
      </Card>

    </div>
  );
};

export default BulkEditTab;
