import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { useParams } from 'react-router-dom';
import { Button, Form, Modal, Table } from 'react-bootstrap';
import 'bootstrap/dist/css/bootstrap.min.css';
import { fetchData } from '../../fetching/Fetch.js';
import { uploadFormData } from '../../fetching/uploadFormData.js';
import { SERVER_URL } from '../../constants.js';
import './ManageAdsScreen.css';

const styles = {
    primaryButton: {
        backgroundColor: '#548CA8',
        borderColor: '#548CA8',
    },
    infoButton: {
        backgroundColor: '#548CA8',
        color: 'white',
        borderColor: '#548CA8',
    },
    modalHeader: {
        backgroundColor: '#334257',
        color: 'white',
    },
};

const ACCEPTED_TYPES = 'image/jpeg,image/png,image/webp,image/gif,video/mp4,video/webm';

/** Matches branch TV ad box (see BranchDisplayPage `.branch-display__ad-stage`). */
const AD_DISPLAY_SPEC = {
    aspectRatio: '16:10',
    recommendedSize: '1920 × 1200 px',
    minSize: '1280 × 800 px',
};

function AdDisplayGuidelines() {
    return (
        <div
            className="text-start small rounded border p-3 mb-3"
            style={{ backgroundColor: '#f8fafc', borderColor: '#cbd5e1' }}
        >
            <strong>TV display size guide</strong>
            <ul className="mb-0 mt-2 ps-3">
                <li>
                    Aspect ratio: <strong>{AD_DISPLAY_SPEC.aspectRatio}</strong> (width : height)
                </li>
                <li>
                    Recommended resolution: <strong>{AD_DISPLAY_SPEC.recommendedSize}</strong>
                </li>
                <li>
                    Minimum for clear TV: <strong>{AD_DISPLAY_SPEC.minSize}</strong>
                </li>
                <li>
                    Use landscape media that fills the frame. Other ratios will show empty bars
                    or look cropped on the branch display.
                </li>
            </ul>
        </div>
    );
}

function mediaUrlFromAd(ad) {
    if (!ad?.mediaUrl) return null;
    return ad.mediaUrl.startsWith('http')
        ? ad.mediaUrl
        : `${SERVER_URL}${ad.mediaUrl}`;
}

function isVideoFile(file) {
    return Boolean(file?.type?.startsWith('video/'));
}

/**
 * Mimics the branch TV advertisement panel (16:10 stage).
 */
function AdTvPreview({ src, isVideo, title, emptyLabel = 'Select a file to preview' }) {
    return (
        <div className="ad-tv-preview">
            <div className="ad-tv-preview__chrome">
                <span className="ad-tv-preview__label">Branch TV preview</span>
                <span className="ad-tv-preview__ratio">{AD_DISPLAY_SPEC.aspectRatio}</span>
            </div>
            <div className="ad-tv-preview__stage">
                {!src ? (
                    <p className="ad-tv-preview__empty">{emptyLabel}</p>
                ) : isVideo ? (
                    <video
                        key={src}
                        className="ad-tv-preview__media"
                        src={src}
                        controls
                        muted
                        playsInline
                    />
                ) : (
                    <img
                        key={src}
                        className="ad-tv-preview__media"
                        src={src}
                        alt={title || 'Advertisement preview'}
                    />
                )}
            </div>
            {title ? <p className="ad-tv-preview__caption">{title}</p> : null}
        </div>
    );
}

export default function ManageAdsScreen() {
    const { tenantCode } = useParams();
    const [ads, setAds] = useState([]);
    const [errorMessage, setErrorMessage] = useState('');
    const [loading, setLoading] = useState(false);

    const [showUpload, setShowUpload] = useState(false);
    const [showEdit, setShowEdit] = useState(false);
    const [showDelete, setShowDelete] = useState(false);
    const [showPreview, setShowPreview] = useState(false);
    const [selectedAd, setSelectedAd] = useState(null);

    const [file, setFile] = useState(null);
    const [title, setTitle] = useState('');
    const [durationSeconds, setDurationSeconds] = useState(10);
    const [sortOrder, setSortOrder] = useState('');
    const [active, setActive] = useState(true);

    const url = `${SERVER_URL}/api/v1/ads/${encodeURIComponent(tenantCode)}`;

    const uploadObjectUrl = useMemo(() => {
        if (!file) return null;
        return URL.createObjectURL(file);
    }, [file]);

    useEffect(() => {
        return () => {
            if (uploadObjectUrl) {
                URL.revokeObjectURL(uploadObjectUrl);
            }
        };
    }, [uploadObjectUrl]);

    const loadAds = useCallback(async () => {
        try {
            const response = await fetchData(url, 'GET');
            if (!response.success) {
                setErrorMessage('Failed to load advertisements.');
                return;
            }
            setAds(Array.isArray(response.data) ? response.data : []);
        } catch (error) {
            console.error(error);
            setErrorMessage('Failed to load advertisements.');
        }
    }, [url]);

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

    function resetUploadForm() {
        setFile(null);
        setTitle('');
        setDurationSeconds(10);
        setSortOrder('');
        setActive(true);
    }

    function openEdit(ad) {
        setSelectedAd(ad);
        setTitle(ad.title ?? '');
        setDurationSeconds(ad.durationSeconds ?? 10);
        setSortOrder(String(ad.sortOrder ?? 0));
        setActive(Boolean(ad.active));
        setShowEdit(true);
    }

    function openPreview(ad) {
        setSelectedAd(ad);
        setShowPreview(true);
    }

    async function handleUpload(event) {
        event.preventDefault();
        if (!file) {
            setErrorMessage('Choose an image or video file to upload.');
            return;
        }

        setLoading(true);
        try {
            const formData = new FormData();
            formData.append('file', file);
            if (title.trim()) {
                formData.append('title', title.trim());
            }
            formData.append('durationSeconds', String(durationSeconds || 10));
            formData.append('active', String(active));
            if (sortOrder !== '' && !Number.isNaN(Number(sortOrder))) {
                formData.append('sortOrder', String(Number(sortOrder)));
            }

            const response = await uploadFormData(url, formData, 'POST');
            if (!response.success) {
                setErrorMessage(response.data?.message || 'Failed to upload advertisement.');
                return;
            }

            setShowUpload(false);
            resetUploadForm();
            await loadAds();
        } catch (error) {
            console.error(error);
            setErrorMessage('Failed to upload advertisement.');
        } finally {
            setLoading(false);
        }
    }

    async function handleEdit(event) {
        event.preventDefault();
        if (!selectedAd) return;

        setLoading(true);
        try {
            const response = await fetchData(`${url}/${selectedAd.id}`, 'PUT', {
                title: title.trim() || null,
                durationSeconds: Number(durationSeconds) || 10,
                sortOrder: sortOrder === '' ? null : Number(sortOrder),
                active,
            });
            if (!response.success) {
                setErrorMessage(response.data?.message || 'Failed to update advertisement.');
                return;
            }
            setShowEdit(false);
            setSelectedAd(null);
            await loadAds();
        } catch (error) {
            console.error(error);
            setErrorMessage('Failed to update advertisement.');
        } finally {
            setLoading(false);
        }
    }

    async function handleDelete() {
        if (!selectedAd) return;

        setLoading(true);
        try {
            const response = await fetchData(`${url}/${selectedAd.id}`, 'DELETE');
            if (!response.success) {
                setErrorMessage(response.data?.message || 'Failed to delete advertisement.');
                return;
            }
            setShowDelete(false);
            setSelectedAd(null);
            await loadAds();
        } catch (error) {
            console.error(error);
            setErrorMessage('Failed to delete advertisement.');
        } finally {
            setLoading(false);
        }
    }

    return (
        <div className="text-center">
            <h2>Manage Advertisements</h2>
            <p className="text-muted mb-2">
                Ads are shared across all branches for this company.
            </p>
            <div className="mx-auto mb-3" style={{ maxWidth: 640 }}>
                <AdDisplayGuidelines />
            </div>
            <Button
                variant="primary"
                style={styles.primaryButton}
                className="mb-3"
                onClick={() => {
                    resetUploadForm();
                    setShowUpload(true);
                }}
            >
                Upload Ad
            </Button>

            <Table striped bordered hover>
                <thead>
                    <tr>
                        <th>Preview</th>
                        <th>Title</th>
                        <th>Type</th>
                        <th>Order</th>
                        <th>Duration (s)</th>
                        <th>Active</th>
                        <th>Actions</th>
                    </tr>
                </thead>
                <tbody>
                    {ads.length === 0 ? (
                        <tr>
                            <td colSpan={7} className="text-muted">
                                No advertisements yet.
                            </td>
                        </tr>
                    ) : (
                        ads.map((ad) => (
                            <tr key={ad.id}>
                                <td style={{ width: 120 }}>
                                    {ad.mediaType === 'IMAGE' ? (
                                        <img
                                            src={mediaUrlFromAd(ad)}
                                            alt={ad.title || ad.fileName}
                                            style={{
                                                maxWidth: 100,
                                                maxHeight: 60,
                                                objectFit: 'cover',
                                                cursor: 'pointer',
                                            }}
                                            onClick={() => openPreview(ad)}
                                        />
                                    ) : (
                                        <Button
                                            variant="link"
                                            className="p-0"
                                            onClick={() => openPreview(ad)}
                                        >
                                            Video
                                        </Button>
                                    )}
                                </td>
                                <td>{ad.title || ad.fileName}</td>
                                <td>{ad.mediaType}</td>
                                <td>{ad.sortOrder}</td>
                                <td>{ad.durationSeconds}</td>
                                <td>{ad.active ? 'Yes' : 'No'}</td>
                                <td>
                                    <Button
                                        variant="info"
                                        style={styles.infoButton}
                                        onClick={() => openPreview(ad)}
                                    >
                                        Preview
                                    </Button>{' '}
                                    <Button
                                        variant="info"
                                        style={styles.infoButton}
                                        onClick={() => openEdit(ad)}
                                    >
                                        Edit
                                    </Button>{' '}
                                    <Button
                                        variant="danger"
                                        onClick={() => {
                                            setSelectedAd(ad);
                                            setShowDelete(true);
                                        }}
                                    >
                                        Delete
                                    </Button>
                                </td>
                            </tr>
                        ))
                    )}
                </tbody>
            </Table>

            <Modal
                show={showUpload}
                onHide={() => {
                    setShowUpload(false);
                    resetUploadForm();
                }}
                size="lg"
            >
                <Modal.Header closeButton style={styles.modalHeader}>
                    <Modal.Title>UPLOAD ADVERTISEMENT</Modal.Title>
                </Modal.Header>
                <Form onSubmit={handleUpload}>
                    <Modal.Body>
                        <AdDisplayGuidelines />
                        <AdTvPreview
                            src={uploadObjectUrl}
                            isVideo={isVideoFile(file)}
                            title={title.trim() || file?.name}
                        />
                        <Form.Group className="mb-3 mt-3">
                            <Form.Label>File (image or video)</Form.Label>
                            <Form.Control
                                type="file"
                                accept={ACCEPTED_TYPES}
                                onChange={(event) => setFile(event.target.files?.[0] ?? null)}
                                required
                            />
                            <Form.Text className="text-muted">
                                Best fit: {AD_DISPLAY_SPEC.aspectRatio},{' '}
                                {AD_DISPLAY_SPEC.recommendedSize}
                            </Form.Text>
                        </Form.Group>
                        <Form.Group className="mb-3">
                            <Form.Label>Title</Form.Label>
                            <Form.Control
                                type="text"
                                value={title}
                                onChange={(event) => setTitle(event.target.value)}
                                placeholder="Optional"
                            />
                        </Form.Group>
                        <Form.Group className="mb-3">
                            <Form.Label>Duration seconds (images)</Form.Label>
                            <Form.Control
                                type="number"
                                min={1}
                                value={durationSeconds}
                                onChange={(event) => setDurationSeconds(event.target.value)}
                            />
                        </Form.Group>
                        <Form.Group className="mb-3">
                            <Form.Label>Sort order</Form.Label>
                            <Form.Control
                                type="number"
                                value={sortOrder}
                                onChange={(event) => setSortOrder(event.target.value)}
                                placeholder="Auto if empty"
                            />
                        </Form.Group>
                        <Form.Check
                            type="switch"
                            id="upload-active"
                            label="Active"
                            checked={active}
                            onChange={(event) => setActive(event.target.checked)}
                        />
                    </Modal.Body>
                    <Modal.Footer>
                        <Button
                            variant="secondary"
                            onClick={() => {
                                setShowUpload(false);
                                resetUploadForm();
                            }}
                        >
                            Close
                        </Button>
                        <Button
                            type="submit"
                            variant="primary"
                            style={styles.primaryButton}
                            disabled={loading}
                        >
                            {loading ? 'Uploading…' : 'Upload'}
                        </Button>
                    </Modal.Footer>
                </Form>
            </Modal>

            <Modal show={showEdit} onHide={() => setShowEdit(false)} size="lg">
                <Modal.Header closeButton style={styles.modalHeader}>
                    <Modal.Title>EDIT ADVERTISEMENT</Modal.Title>
                </Modal.Header>
                <Form onSubmit={handleEdit}>
                    <Modal.Body>
                        {selectedAd ? (
                            <AdTvPreview
                                src={mediaUrlFromAd(selectedAd)}
                                isVideo={selectedAd.mediaType === 'VIDEO'}
                                title={title.trim() || selectedAd.fileName}
                            />
                        ) : null}
                        <Form.Group className="mb-3 mt-3">
                            <Form.Label>Title</Form.Label>
                            <Form.Control
                                type="text"
                                value={title}
                                onChange={(event) => setTitle(event.target.value)}
                            />
                        </Form.Group>
                        <Form.Group className="mb-3">
                            <Form.Label>Duration seconds (images)</Form.Label>
                            <Form.Control
                                type="number"
                                min={1}
                                value={durationSeconds}
                                onChange={(event) => setDurationSeconds(event.target.value)}
                            />
                        </Form.Group>
                        <Form.Group className="mb-3">
                            <Form.Label>Sort order</Form.Label>
                            <Form.Control
                                type="number"
                                value={sortOrder}
                                onChange={(event) => setSortOrder(event.target.value)}
                            />
                        </Form.Group>
                        <Form.Check
                            type="switch"
                            id="edit-active"
                            label="Active"
                            checked={active}
                            onChange={(event) => setActive(event.target.checked)}
                        />
                    </Modal.Body>
                    <Modal.Footer>
                        <Button variant="secondary" onClick={() => setShowEdit(false)}>
                            Close
                        </Button>
                        <Button
                            type="submit"
                            variant="primary"
                            style={styles.primaryButton}
                            disabled={loading}
                        >
                            {loading ? 'Saving…' : 'Save'}
                        </Button>
                    </Modal.Footer>
                </Form>
            </Modal>

            <Modal
                show={showPreview}
                onHide={() => {
                    setShowPreview(false);
                    setSelectedAd(null);
                }}
                size="lg"
                centered
            >
                <Modal.Header closeButton style={styles.modalHeader}>
                    <Modal.Title>TV DISPLAY PREVIEW</Modal.Title>
                </Modal.Header>
                <Modal.Body>
                    {selectedAd ? (
                        <AdTvPreview
                            src={mediaUrlFromAd(selectedAd)}
                            isVideo={selectedAd.mediaType === 'VIDEO'}
                            title={selectedAd.title || selectedAd.fileName}
                        />
                    ) : null}
                    <p className="text-muted small mt-3 mb-0 text-center">
                        This matches the advertisement panel on the branch waiting-area TV
                        ({AD_DISPLAY_SPEC.aspectRatio}).
                    </p>
                </Modal.Body>
                <Modal.Footer>
                    <Button
                        variant="secondary"
                        onClick={() => {
                            setShowPreview(false);
                            setSelectedAd(null);
                        }}
                    >
                        Close
                    </Button>
                </Modal.Footer>
            </Modal>

            <Modal show={showDelete} onHide={() => setShowDelete(false)}>
                <Modal.Header closeButton style={styles.modalHeader}>
                    <Modal.Title>CONFIRMATION</Modal.Title>
                </Modal.Header>
                <Modal.Body>
                    <p>
                        Delete advertisement{' '}
                        <strong>{selectedAd?.title || selectedAd?.fileName}</strong>?
                    </p>
                </Modal.Body>
                <Modal.Footer>
                    <Button variant="secondary" onClick={() => setShowDelete(false)}>
                        Cancel
                    </Button>
                    <Button variant="danger" onClick={handleDelete} disabled={loading}>
                        {loading ? 'Deleting…' : 'Delete'}
                    </Button>
                </Modal.Footer>
            </Modal>

            <Modal
                show={errorMessage !== ''}
                onHide={() => setErrorMessage('')}
                backdrop="static"
                keyboard={false}
            >
                <Modal.Header closeButton style={{ backgroundColor: '#dc3545', color: 'white' }}>
                    <Modal.Title>ERROR</Modal.Title>
                </Modal.Header>
                <Modal.Body>
                    <p>{errorMessage}</p>
                </Modal.Body>
                <Modal.Footer>
                    <Button variant="secondary" onClick={() => setErrorMessage('')}>
                        Close
                    </Button>
                </Modal.Footer>
            </Modal>
        </div>
    );
}
