import SocialNetworkService from '../services/socialnetworkService.js';

class SocialNetworkController {
    constructor() {
        this.socialNetworkService = new SocialNetworkService();
        this.userSearch = this.userSearch.bind(this);
        this.profile = this.profile.bind(this);
        this.createFolder = this.createFolder.bind(this);
        this.getFolders = this.getFolders.bind(this);
        this.uploadImage = this.uploadImage.bind(this);
        this.getImage = this.getImage.bind(this);
        this.getImageVisibilityTypes = this.getImageVisibilityTypes.bind(this);
        this.getFolderImageList = this.getFolderImageList.bind(this);
        this.getImageByHash = this.getImageByHash.bind(this);
        this.changeImage = this.changeImage.bind(this);
        this.getFoldersByUsername = this.getFoldersByUsername.bind(this);
        this.deleteFolder = this.deleteFolder.bind(this);
        this.createGuestbookEntry = this.createGuestbookEntry.bind(this);
        this.getGuestbookEntries = this.getGuestbookEntries.bind(this);
        this.deleteGuestbookEntry = this.deleteGuestbookEntry.bind(this);
        this.getGuestbookImage = this.getGuestbookImage.bind(this);
        this.createDiaryEntry = this.createDiaryEntry.bind(this);
        this.updateDiaryEntry = this.updateDiaryEntry.bind(this);
        this.deleteDiaryEntry = this.deleteDiaryEntry.bind(this);
        this.getDiaryEntries = this.getDiaryEntries.bind(this);
        this.addFriend = this.addFriend.bind(this);
        this.removeFriend = this.removeFriend.bind(this);
        this.acceptFriendship = this.acceptFriendship.bind(this);
        this.getLoggedInFriends = this.getLoggedInFriends.bind(this);
    }

    async userSearch(req, res) {
        try {
            const { userid: hashedUserId } = req.headers;
            const { username, ageFrom, ageTo, genders } = req.body;
            const users = await this.socialNetworkService.searchUsers({ hashedUserId, username, ageFrom, ageTo, genders });
            res.status(200).json(users);
        } catch (error) {
            console.error('Error in userSearch:', error);
            res.status(500).json({ error: error.message });
        }
    }

    async profile(req, res) {
        try {
            const { userId } = req.params;
            const requestingUserId = req.headers.userid;
            if (!userId || !requestingUserId) {
                return res.status(400).json({ error: 'Invalid user or requesting user ID.' });
            }
            const profile = await this.socialNetworkService.getProfile(userId, requestingUserId);
            res.status(200).json(profile);
        } catch (error) {
            console.error('Error in profile:', error);
            res.status(500).json({ error: error.message });
        }
    }

    async createFolder(req, res) {
        try {
            const userId = req.headers.userid;
            const folderData = req.body;
            const { folderId } = req.params;
            const folder = await this.socialNetworkService.createFolder(userId, folderData, folderId);
            res.status(201).json(folder);
        } catch (error) {
            console.error('Error in createFolder:', error);
            res.status(500).json({ error: error.message });
        }
    }

    async getFolders(req, res) {
        try {
            const userId = req.headers.userid;
            const folders = await this.socialNetworkService.getFolders(userId);
            res.status(200).json(folders);
        } catch (error) {
            console.error('Error in getFolders:', error);
            res.status(500).json({ error: error.message });
        }
    }

    async getFolderImageList(req, res) {
        try {
            const userId = req.headers.userid;
            const { folderId } = req.params;
            const images = await this.socialNetworkService.getFolderImageList(userId, folderId);
            res.status(200).json(images);
        } catch (error) {
            console.error('Error in getFolderImageList:', error);
            res.status(500).json({ error: error.message });
        }
    }

    async uploadImage(req, res) {
        try {
            const userId = req.headers.userid;
            const file = req.file;
            const formData = req.body;
            const image = await this.socialNetworkService.uploadImage(userId, file, formData);
            res.status(201).json(image);
        } catch (error) {
            console.error('Error in uploadImage:', error);
            res.status(500).json({ error: error.message });
        }
    }

    async getImage(req, res) {
        try {
            const { imageId } = req.params;
            const image = await this.socialNetworkService.getImage(imageId);
            res.status(200).json(image);
        } catch (error) {
            console.error('Error in getImage:', error);
            res.status(500).json({ error: error.message });
        }
    }

    async getImageVisibilityTypes(req, res) {
        try {
            const types = await this.socialNetworkService.getPossibleImageVisibilities();
            res.status(200).json(types);
        } catch (error) {
            console.log(error);
            res.status(500).json({ error: error.message });
        }
    }

    async getImageByHash(req, res) {
        try {
            const userId = req.headers.userid;
            const { hash } = req.params;
            const filePath = await this.socialNetworkService.getImageFilePath(userId, hash);
            res.sendFile(filePath, err => {
                if (err) {
                    console.error('Error sending file:', err);
                    res.status(500).json({ error: 'Error sending file' });
                }
            });
        } catch (error) {
            console.error('Error in getImageByHash:', error);
            res.status(403).json({ error: error.message || 'Access denied or image not found' });
        }
    }

    async changeImage(req, res) {
        try {
            const userId = req.headers.userid;
            const { imageId } = req.params;
            const { title, visibilities } = req.body;
            const folderId = await this.socialNetworkService.changeImage(userId, imageId, title, visibilities);
            console.log('--->', folderId);
            res.status(201).json(await this.socialNetworkService.getFolderImageList(userId, folderId));
        } catch (error) {
            console.error('Error in getImageByHash:', error);
            res.status(403).json({ error: error.message || 'Access denied or image not found' });
        }
    }

    async getFoldersByUsername(req, res) {
        try {
            const { username } = req.params;
            const requestingUserId = req.headers.userid;
            if (!username || !requestingUserId) {
                return res.status(400).json({ error: 'Invalid username or requesting user ID.' });
            }
            const folders = await this.socialNetworkService.getFoldersByUsername(username, requestingUserId);
            if (!folders) {
                return res.status(404).json({ error: 'No folders found or access denied.' });
            }
            res.status(200).json(folders);
        } catch (error) {
            console.error('Error in getFoldersByUsername:', error);
            res.status(500).json({ error: error.message });
        }
    }

    async deleteFolder(req, res) {
        try {
            const userId = req.headers.userid;
            const { folderId } = req.params;
            await this.socialNetworkService.deleteFolder(userId, folderId);
            res.status(204).send();
        } catch (error) {
            console.error('Error in deleteFolder:', error);
            res.status(500).json({ error: error.message });
        }
    }

    async createGuestbookEntry(req, res) {
        try {
            const { htmlContent, recipientName } = req.body;
            const hashedSenderId = req.headers.userid;
            const image = req.file ? req.file : null;
            const entry = await this.socialNetworkService.createGuestbookEntry(
                hashedSenderId,
                recipientName,
                htmlContent,
                image
            );
            res.status(201).json(entry);
        } catch (error) {
            console.error('Error in createGuestbookEntry:', error);
            res.status(500).json({ error: error.message });
        }
    }

    async getGuestbookEntries(req, res) {
        try {
            const hashedUserId = req.headers.userid;  
            const { username, page = 1 } = req.params;
            const entries = await this.socialNetworkService.getGuestbookEntries(hashedUserId, username, page);
            res.status(200).json(entries);
        } catch (error) {
            console.error('Error in getGuestbookEntries:', error);
            res.status(500).json({ error: error.message });
        }
    }

    async deleteGuestbookEntry(req, res) {
        try {
            const hashedUserId = req.headers.userid;  
            const { entryId } = req.params;
            await this.socialNetworkService.deleteGuestbookEntry(hashedUserId, entryId);
            res.status(200).json({ message: 'Entry deleted successfully' });
        } catch (error) {
            console.error('Error in deleteGuestbookEntry:', error);
            res.status(500).json({ error: error.message });
        }
    }

    async getGuestbookImage(req, res) {
        try {
            const userId = req.headers.userid;
            const { guestbookUserName, entryId } = req.params;
            const filePath = await this.socialNetworkService.getGuestbookImageFilePath(userId, guestbookUserName, entryId);
            res.sendFile(filePath, err => {
                if (err) {
                    console.error('Error sending file:', err);
                    res.status(500).json({ error: 'Error sending file' });
                }
            });
        } catch (error) {
            console.error('Error in getImageByHash:', error);
            res.status(403).json({ error: error.message || 'Access denied or image not found' });
        }
    }

    async createDiaryEntry(req, res) {
        try {
            const { userId, text } = req.body;
            const entry = await this.socialNetworkService.createDiaryEntry(userId, text);
            res.status(201).json(entry);
        } catch (error) {
            console.error('Error in createDiaryEntry:', error);
            res.status(500).json({ error: error.message });
        }
    }

    async updateDiaryEntry(req, res) {
        try {
            const { diaryEntryId } = req.params;
            const { userId, text } = req.body;
            const updatedEntry = await this.socialNetworkService.updateDiaryEntry(diaryEntryId, userId, text);
            res.status(200).json(updatedEntry);
        } catch (error) {
            console.error('Error in updateDiaryEntry:', error);
            res.status(500).json({ error: error.message });
        }
    }

    async deleteDiaryEntry(req, res) {
        try {
            const { entryId } = req.params;
            const { userId } = req.body;
            const result = await this.socialNetworkService.deleteDiaryEntry(entryId, userId);
            res.status(200).json({ message: 'Entry deleted successfully', result });
        } catch (error) {
            console.error('Error in deleteDiaryEntry:', error);
            res.status(500).json({ error: error.message });
        }
    }

    async getDiaryEntries(req, res) {
        try {
            const { userid: userId } = req.headers;
            const { page } = req.params;
            const entries = await this.socialNetworkService.getDiaryEntries(userId, page);
            res.status(200).json(entries);
        } catch (error) {
            console.error('Error in getDiaryEntries:', error);
            res.status(500).json({ error: error.message });
        }
    }

    async addFriend(req, res) {
        try {
            const { userid: hashedUserid } = req.headers;
            const { friendUserid } = req.body;
            console.log('--------', friendUserid, hashedUserid);
            await this.socialNetworkService.addFriend(hashedUserid, friendUserid);
            res.status(201).json({ message: 'added' });
        } catch (error) {
            console.error('Error in addFriend:', error);
            res.status(500).json({ error: error.message });
        }
    }

    async removeFriend(req, res) {
        try {
            const { userid: hashedUserid } = req.headers;
            const { friendUserid } = req.params;
            await this.socialNetworkService.removeFriend(hashedUserid, friendUserid);
            res.status(200).json({ message: 'removed' });
        } catch (error) {
            console.error('Error in removeFriend:', error);
            res.status(500).json({ error: error.message });
        }
    }

    async acceptFriendship(req, res) {
        try {
            const { userid: hashedUserid } = req.headers;
            const { friendUserid } = req.params;
            await this.socialNetworkService.acceptFriendship(hashedUserid, friendUserid);
            res.status(200).json({ message: 'accepted' });
        } catch (error) {
            console.error('Error in acceptFriendship:', error);
            res.status(500).json({ error: error.message });
        }
    }

    async getLoggedInFriends(req, res) {
        try {
            const { userid: userId } = req.headers;
            if (!userId) {
                return res.status(400).json({ error: 'Missing user ID' });
            }
            const loggedInFriends = await this.socialNetworkService.getLoggedInFriends(userId);
            res.status(200).json(loggedInFriends);
        } catch (error) {
            console.error('Error in getLoggedInFriends:', error);
            res.status(500).json({ error: error.message });
        }
    }
}

export default SocialNetworkController;
